[
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"env\": {\n    \"browser\": true,\n    \"node\": true,\n    \"es6\": true,\n    \"mocha\": true\n  },\n  \"extends\": \"eslint:recommended\",\n  \"parserOptions\": {\n      \"sourceType\": \"module\"\n  },\n  \"globals\": {\n    \"nv\": true,\n    \"d3\": true\n  },\n  \"rules\": {\n    \"indent\": [\n      \"error\",\n      2\n    ],\n    \"linebreak-style\": [\n      \"error\",\n      \"unix\"\n    ],\n    \"quotes\": [\n      \"error\",\n      \"single\"\n    ],\n    \"object-curly-spacing\": [\n      \"error\",\n      \"always\"\n    ],\n    \"prefer-arrow-callback\": [\n      \"never\",\n      {\n        \"allowNamedFunctions\": true\n      }\n    ],\n    \"arrow-parens\": [\n      \"error\",\n      \"always\"\n    ],\n    \"space-before-function-paren\": [\"error\", {\n      \"anonymous\": \"never\",\n      \"named\": \"never\",\n      \"asyncArrow\": \"never\"\n    }],\n    \"semi\": [\n      \"error\",\n      \"always\"\n    ],\n    \"comma-dangle\": [\"error\", {\n      \"arrays\": \"never\",\n      \"objects\": \"never\",\n      \"imports\": \"never\",\n      \"exports\": \"never\",\n      \"functions\": \"ignore\"\n    }]\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "\n.idea\n*.swp\n*~\n*.log\n.DS_Store*\nehthumbs.db\nIcon?\nThumbs.db\nnode_modules\nbower_components\ncoverage\ntest-results.xml\n*.orig\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"asi\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n    - \"0.12\"\nbefore_install:\n    - \"npm install -g bower\"\n    - \"npm install -g grunt-cli\"\n    - \"export DISPLAY=:99.0\"\n    - \"sh -e /etc/init.d/xvfb start\"\n#   Meteor Tinytest support\n    - \"curl https://install.meteor.com | /bin/sh\"\n    - export PATH=\"$HOME/.meteor:$PATH\"\n    - \"npm install -g spacejam\"\ninstall:\n    - \"npm install\"\n    - \"bower install\"\n\nscript:\n    - \"npm test\"\n    - \"spacejam test-packages ./\"\n"
  },
  {
    "path": "GruntFile.js",
    "content": "module.exports = function(grunt) {\n    var _pkg = grunt.file.readJSON('package.json');\n\n    // allows autoprefixer to work on older node_js versions\n    require('es6-promise').polyfill();\n\n    //Project configuration.\n    grunt.initConfig({\n        pkg: _pkg,\n        concat: {\n            css: {\n                options: {\n                    separator: '\\n',\n                    banner: '/* nvd3 version ' + _pkg.version + ' (' + _pkg.url + ') ' +\n                        '<%= grunt.template.today(\"yyyy-mm-dd\") %> */\\n'\n                },\n                src: [\n                    'src/css/*.css'\n                ],\n                dest: 'build/nv.d3.css'\n            },\n            js: {\n                options: {\n                    separator: '',\n                    banner: '/* nvd3 version ' + _pkg.version + ' (' + _pkg.url + ') ' +\n                        '<%= grunt.template.today(\"yyyy-mm-dd\") %> */\\n' + '(function(){\\n',\n                    footer: '\\nnv.version = \"' + _pkg.version + '\";\\n})();',\n                    sourceMap: true,\n                    sourceMapName: 'build/nv.d3.js.map',\n                    sourceMapStyle: 'embed'\n                },\n                src: [\n                    'src/core.js',\n                    'src/dom.js',\n                    'src/interactiveLayer.js',\n                    'src/tooltip.js',\n                    'src/utils.js',\n                    //Include all files in src/models\n                    'src/models/*.js',\n                    // example to exclude files: '!src/models/excludeMe*'\n                ],\n                dest: 'build/nv.d3.js'\n            }\n        },\n        uglify: {\n            options: {\n                sourceMap: true,\n                sourceMapIncludeSources : true,\n                sourceMapIn : 'build/nv.d3.js.map',\n                banner: '/* nvd3 version ' + _pkg.version + ' (' + _pkg.url + ') ' +\n                    '<%= grunt.template.today(\"yyyy-mm-dd\") %> */\\n'\n            },\n            js: {\n                files: {\n                    'build/nv.d3.min.js': ['build/nv.d3.js']\n                }\n            }\n        },\n        replace: {\n            version: {\n                src: [\n                    'package.js'\n                ],\n                overwrite: true,\n                replacements: [{\n                    from: /(version?\\s?=?\\:?\\s\\')([\\d\\.]*)\\'/gi,\n                    to: '$1' + _pkg.version + \"'\"\n                }]\n            }\n        },\n        jshint: {\n            foo: {\n                src: \"src/**/*.js\"\n            },\n            options: {\n                jshintrc: '.jshintrc'\n            }\n        },\n        watch: {\n            js: {\n                files: [\"src/**/*.js\"],\n                tasks: ['concat']\n            }\n        },\n        copy: {\n            css: {\n                files: [\n                    { src: 'src/nv.d3.css', dest: 'build/nv.d3.css' }\n                ]\n            }\n        },\n        postcss: {\n            options: {\n                processors: [\n                    require('autoprefixer')({\n                        browsers: [\n                            'last 2 versions',\n                            'last 3 iOS versions',\n                            'last 2 safari versions',\n                            'ie >= 9']\n                    })\n                ]\n            },\n            dist: {\n                src: 'build/nv.d3.css'\n            }\n        },\n        cssmin: {\n            options: {\n                sourceMap: true\n            },\n            dist: {\n                files: {\n                    'build/nv.d3.min.css' : ['build/nv.d3.css']\n                }\n            }\n        },\n        karma: {\n            unit: {\n                options: {\n                    logLevel: 'DEBUG',\n                    browsers: ['Firefox'],\n                    browserNoActivityTimeout: 60000,\n                    browserDisconnectTimeout: 60000,\n                    captureTimeout: 60000,\n                    frameworks: [ 'mocha', 'sinon-chai' ],\n                    reporters: [ 'spec', 'junit', 'coverage'],\n                    singleRun: true,\n                    preprocessors: {\n                        'src/*.js': ['coverage'],\n                        'src/models/*.js': ['coverage'],\n                        'test/mocha/*.coffee': ['coffee']\n                    },\n                    files: [\n                        'bower_components/d3/d3.js',\n                        'node_modules/moment/moment.js',\n                        'src/*.js',\n                        'src/models/*.js',\n                        'test/mocha/*.coffee',\n                        'https://cdn.rawgit.com/Kcnarf/d3-beeswarm/fbda9b54/build/d3-beeswarm.min.js',\n                        'test/mocha/*.js'\n                    ],\n                    exclude: [\n                        'src/intro.js',\n                        'src/outro.js',\n                        //Files we don't want to test.\n                        'src/models/lineWith*',\n                        'src/models/parallelCoordinates*',\n                        'src/models/multiBarTime*',\n                        'src/models/indented*',\n                        'src/models/linePlus*',\n                        'src/models/ohlcBar.js',\n                        'src/models/candlestickBar.js'\n                    ]\n                }\n            }\n        }\n    });\n\n    grunt.loadNpmTasks('grunt-contrib-watch');\n    grunt.loadNpmTasks('grunt-contrib-concat');\n    grunt.loadNpmTasks('grunt-contrib-jshint');\n    grunt.loadNpmTasks('grunt-contrib-uglify');\n    grunt.loadNpmTasks('grunt-contrib-copy');\n    grunt.loadNpmTasks('grunt-postcss');\n    grunt.loadNpmTasks('grunt-contrib-cssmin');\n    grunt.loadNpmTasks('grunt-karma');\n    grunt.loadNpmTasks('grunt-text-replace');\n\n    grunt.registerTask('default', ['concat', 'copy', 'postcss', 'karma:unit']);\n    grunt.registerTask('production', ['concat', 'uglify', 'copy', 'postcss', 'cssmin', 'replace']);\n    grunt.registerTask('release', ['production']);\n    grunt.registerTask('lint', ['jshint']);\n};\n"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "content": "PLEASE READ THIS BEFORE SUBMITTING A NEW ISSUE.\n\nARE YOU ASKING FOR HELP? Please use Stack Overflow tag nvd3.js and include a link to a live, minimal example on jsfiddle / plunker.\n\nThe live example should use the latest code for nvd3. Links are below:\nhttps://raw.githubusercontent.com/novus/nvd3/master/build/nv.d3.js\nhttps://raw.githubusercontent.com/novus/nvd3/master/build/nv.d3.css\n\nSupported D3 js version. v3.5.17\n\nhttps://github.com/cdnjs/cdnjs/blob/master/ajax/libs/d3/3.5.17/d3.min.js\n\nARE YOU REPORTING AN ISSUE? Please provide below information with the issue:\n\nNVD3 version used:\n\nBrowser and OS used:\n\nLive Example: Jsfiddle / Plunker\n\nExpected Behaviour:\n\nPresent Behaviour:\n\nAny more information regarding the issue:\n"
  },
  {
    "path": "LICENSE.md",
    "content": "##nvd3.js License\n\nCopyright (c) 2011-2014 [Novus Partners, Inc.][novus]\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n[novus]: https://www.novus.com/\n\n\n\n##d3.js License\n\nCopyright (c) 2012, Michael Bostock\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* The name Michael Bostock may not be used to endorse or promote products\n  derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,\nINDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\nOF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "README.md",
    "content": "## NVD3 - A reusable D3 charting library\n\nInspired by the work of Mike Bostock's [Towards Reusable Charts](http://bost.ocks.org/mike/chart/), and supported by a combined effort of [Novus](http://www.novus.com) and the NVD3 community.\n\n[View Examples](http://nvd3-community.github.io/nvd3/) | [NEW Documentation!](http://nvd3-community.github.io/nvd3/examples/documentation.html) | Development build status: [![Build Status](https://travis-ci.org/novus/nvd3.svg?branch=master)](https://travis-ci.org/novus/nvd3)\n\n\n## Usage\nSimply add the `nv.d3` assets to your project and include them in your HTML.\n\n```\n<link href=\"nv.d3.min.css\" rel=\"stylesheet\">\n<script src=\"nv.d3.min.js\"></script>\n```\n\n*  `nv.d3.js` should appear after `d3.js` is included.\n* Prefer minified assets (`.min`) for production.\n\n### Dependencies\n\nNVD3 is recommended to go with [d3.js](http://d3js.org/) version 3.5.3 and later, but NOT d3 4.x yet. [version 3.5.17](https://github.com/d3/d3/releases/tag/v3.5.17) is the most recent d3 v3 release. \n\n**Minimum D3 version required: 3.4.4**\n\nFor a D3v4 Version, see the work in progress at the [nvd3 organization](http://github.com/nvd3/nvd3)\n\nAlong with `pieChart` options `padAngle` and `cornerRadius`, the interactive guideline tooltip now requires these later versions of D3 (3.4.4+, specifically, to get interactive tooltips). The interactive guide lines rely on the more recent `d3.bisector()` method which treats accessors taking two parameters (the second being the element index) as comparators (see [d3.bisector()](https://github.com/mbostock/d3/wiki/Arrays#d3_bisector)).\n\n\n## Supported Browsers\nNVD3 runs best on WebKit based browsers.\n\n* Google Chrome: latest version\n* Opera 15+ (i.e. webkit version)\n* Safari: latest version\n* Firefox: latest version\n* Internet Explorer: 10+\n\n## Do we support D3 v4.x?\n\nNo, we do not...  we are very interested in taking this on but could use some help.  Please let us know if you'd like to help make this a reality!  :)\n\n## Changelog\n\n**1.8.6** Changes:\n\n* Community bugfixes\n\n**1.8.5** Changes:\n\n* Community bugfixes\n* New force-directed graph\n\n**1.8.4** Changes:\n\n* Community bugfixes including tooltip fixes.\n\n**1.8.3** Changes:\n\n* Lots of community bugfixes\n* Added force-directed chart\n\n**1.8.2** Changes:\n\n* Lots of community bugfixes and a few extra minor features\n\n**1.8.1** Changes:\n\n* Tooltips were refactored - If you have customized your tooltips, note that you may need to adjust your custom functions as the data passed has changed format.  See the new [tooltip options](https://nvd3-community.github.io/nvd3/examples/documentation.html#tooltip) for more details.\n* Added boxplot charts | [example](https://nvd3-community.github.io/nvd3/examples/boxPlot.html)\n* Added candlestick charts | [example](https://nvd3-community.github.io/nvd3/examples/candlestickChart.html)\n* Added extra donut chart abilities | [examples](https://nvd3-community.github.io/nvd3/examples/monitoringChart.html)\n* Added sunburst Charts | [example](https://nvd3-community.github.io/nvd3/examples/sunburst.html)\n* Time Series | [example](https://nvd3-community.github.io/nvd3/examples/TimeSeries.html)\n* Another legend format available | [example](https://nvd3-community.github.io/nvd3/examples/stackedAreaChart.html)\n* Lots of bug fixes (see closed issues)\n* (for all examples, see [here](https://nvd3-community.github.io/nvd3/))\n\n**1.7.1** Changes:\n\n* Fixed axis.staggerLabels bug.\n* Fixed Karma unit tests.\n* Fixed chart test pages.\n* Merged in nvd3-community changes and development branch.\n\n**1.7.0** Changes:\n\n* Fixes around 20 small bugs.\n* Fixed the notorious slowness of line charts and scatter plots on chrome\n* Combined the scatterChart and scatterChartWithLines models\n* Combined the linePlusBarChart and linePlusBarChartWithFocus models.\n* renamed some of the options (see the new documentation for what options are available for each chart)\n* Completed the migration of the option functions to an object format which allows the generation of\nthe documentation in an automated way.  Not everything has a description yet, but check it out!\n* Added extra options to the donut charts based on features that will be in d3 3.5.  The donut example page\nloads the latest d3 from their 3.5 branch so keep that in mind.\n* Added an example of the parallelCoordinates chart.\n* Fixed up the half-done OHLC bar chart, and made an example for it as well.\n\n**1.6.0** Changes:\n\n* includes about a dozen bug fixes and pull requests I fixed and merged in\nfrom the issues/pulls from the original project.\n* It also standardized all indention\n\n---\n\n# Current development focus\n- Review outstanding pull requests and issues.\n- Try to find an easy way to actually document usage and all chart options.\n- Improve the testing framework.\n- Setup continuous integration.\n\n---\n\n# Bugs\n\nFound a bug?  Check out the latest from the `master` branch and make sure it's not already fixed first! If you don't see a related fix, please [open an issue](https://github.com/novus/nvd3/issues).\n\n---\n\n# Optional dependencies\n\nIncluding [Fastdom](https://github.com/wilsonpage/fastdom) in your project can greatly increase the performance of the line chart (particularly in Firefox and Internet Explorer) by batching DOM read and write operations to avoid [layout thrashing](http://wilsonpage.co.uk/preventing-layout-thrashing/). NVD3 will take advantage of Fastdom if present.\n\n---\n\n# Contributing\n\nIf one of [the existing models](https://github.com/novus/nvd3/tree/master/src/models)\ndoesn't meet your needs, fork the project, implement the model and an example using it,\nsend us a pull request, for consideration for inclusion in the project.\n\nIf you'd like to contribute consistently, show me what you've got with some good pull requests and you may get added to the nvd3-community org!\n\n### A few rules for pull requests\n\n1. Please commit to the `master` branch\n2. Do NOT check in anything under the `build` directory, it clutters up the commit and just gets overwritten later.\n3. All new features must come with unit test coverage\n4. Bug fixes should come with unit tests that prove their fix\n\nIf you want to test your changes using the example pages,\nyou'll have to run `grunt production` to build the items into the `build` directory.\nYou must do this before your changes show up in the examples, as they link to the build directory\nin order to properly show off the finished product.\nPlease remember to NOT include the build files in your commit though,\nonly include the source files you changed!\n\n### Tips for Testing\n* Unit tests were written in Karma and Mocha. Follow instructions in **Building Latest** to get npm packages setup. This may not work on Windows machines.\n* Run `bower install` to get bower dependencies.\n* Run `grunt` to start the unit tests.\n* Also visually inspect the HTML pages in the **examples/ and test/ folders**.  Make sure there are no glaring errors.\n* Novus now uses Travis CI for continuous integration. Visit [our travis build page](https://travis-ci.org/novus/nvd3/) to see the latest status.\n\n#### Meteor Tinytests\n* Any Meteor-specific features can be tested from the command line using `tinytest` and [Spacejam](https://www.npmjs.com/package/spacejam)\n* `spacejam` can be installed by running `npm install -g spacejam`.\n* Tinytests can then be executed by running `spacejam test-packages ./` from this project's root.\n\n---\n\n## Building latest\n\n1. First clone the repository and checkout the `master` branch\n2. make sure `nodejs` is installed via your system's package manager.\n3. Install `grunt`, `grunt-cli`, and `bower`:  `npm install -g grunt grunt-cli bower`\n\n> have node download nvd3's required modules with:  `npm install`\n\n> build with:  `grunt production`\n\nYou should now have a `build` directory with the js and css files within.\n\n---\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"nvd3\",\n  \"homepage\": \"http://www.nvd3.org\",\n  \"authors\": [\n    \"Bob Monteverde\",\n    \"Tyler Wolf\",\n    \"Robin Hu\",\n    \"Frank Shao\",\n    \"liquidpele\"\n  ],\n  \"description\": \"Re-usable charts and chart components for d3.\",\n  \"main\": [\n    \"build/nv.d3.js\",\n    \"build/nv.d3.css\"\n  ],\n  \"keywords\": [\n    \"d3\",\n    \"visualization\",\n    \"svg\",\n    \"charts\"\n  ],\n  \"license\": \"Apache-2.0\",\n  \"dependencies\": {\n    \"d3\": \"^3.4.4\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"src\",\n    \"examples\",\n    \"GruntFile.js\",\n    \"*.html\",\n    \"*.log\",\n    \"*.xml\",\n    \"*.json\",\n    \"*.md\"\n  ]\n}\n"
  },
  {
    "path": "build/nv.d3.css",
    "content": "/* nvd3 version 1.8.6-dev (https://github.com/novus/nvd3) 2018-02-24 */\n.nvd3 .nv-axis {\r\n    pointer-events:none;\r\n    opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-axis path {\r\n    fill: none;\r\n    stroke: #000;\r\n    stroke-opacity: .75;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-axis path.domain {\r\n    stroke-opacity: .75;\r\n}\r\n\r\n.nvd3 .nv-axis.nv-x path.domain {\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3 .nv-axis line {\r\n    fill: none;\r\n    stroke: #e5e5e5;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-axis .zero line,\r\n    /*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {\r\n    stroke-opacity: .75;\r\n}\r\n\r\n.nvd3 .nv-axis .nv-axisMaxMin text {\r\n    font-weight: bold;\r\n}\r\n\r\n.nvd3 .x  .nv-axis .nv-axisMaxMin text,\r\n.nvd3 .x2 .nv-axis .nv-axisMaxMin text,\r\n.nvd3 .x3 .nv-axis .nv-axisMaxMin text {\r\n    text-anchor: middle;\r\n}\r\n\r\n.nvd3 .nv-axis.nv-disabled {\r\n    opacity: 0;\r\n}\r\n\n.nvd3 .nv-bars rect {\r\n    fill-opacity: .75;\r\n\r\n    transition: fill-opacity 250ms linear;\r\n}\n\r\n.nvd3 .nv-bars rect.hover {\r\n    fill-opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-bars .hover rect {\r\n    fill: lightblue;\r\n}\r\n\r\n.nvd3 .nv-bars text {\r\n    fill: rgba(0,0,0,0);\r\n}\r\n\r\n.nvd3 .nv-bars .hover text {\r\n    fill: rgba(0,0,0,1);\r\n}\r\n\r\n.nvd3 .nv-multibar .nv-groups rect,\r\n.nvd3 .nv-multibarHorizontal .nv-groups rect,\r\n.nvd3 .nv-discretebar .nv-groups rect {\r\n    stroke-opacity: 0;\r\n\r\n    transition: fill-opacity 250ms linear;\r\n}\n\r\n.nvd3 .nv-multibar .nv-groups rect:hover,\r\n.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,\r\n.nvd3 .nv-candlestickBar .nv-ticks rect:hover,\r\n.nvd3 .nv-discretebar .nv-groups rect:hover {\r\n    fill-opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-discretebar .nv-groups text,\r\n.nvd3 .nv-multibarHorizontal .nv-groups text {\r\n    font-weight: bold;\r\n    fill: rgba(0,0,0,1);\r\n    stroke: rgba(0,0,0,0);\r\n}\r\n\n/* boxplot CSS */\n.nvd3 .nv-boxplot circle {\n  fill-opacity: 0.5;\n}\n\n.nvd3 .nv-boxplot circle:hover {\n  fill-opacity: 1;\n}\n\n.nvd3 .nv-boxplot rect:hover {\n  fill-opacity: 1;\n}\n\n.nvd3 line.nv-boxplot-median {\n  stroke: black;\n}\n\n.nv-boxplot-tick:hover {\n  stroke-width: 2.5px;\n}\n/* bullet */\r\n.nvd3.nv-bullet { font: 10px sans-serif; }\r\n.nvd3.nv-bullet .nv-measure { fill-opacity: .8; }\r\n.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; }\r\n.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; }\r\n.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; }\r\n.nvd3.nv-bullet .nv-markerLine { stroke: #000; stroke-width: 1.5px; }\r\n.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; }\r\n.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; }\r\n.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; }\r\n.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; }\r\n.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; }\r\n.nvd3.nv-bullet .nv-subtitle { fill: #999; }\r\n\r\n.nvd3.nv-bullet .nv-range {\n    fill: #bababa;\r\n    fill-opacity: .4;\r\n}\n\n.nvd3.nv-bullet .nv-range:hover {\r\n    fill-opacity: .7;\r\n}\r\n\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick {\r\n    stroke-width: 1px;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover {\r\n    stroke-width: 2px;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect {\r\n    stroke: #2ca02c;\r\n    fill: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect {\r\n    stroke: #d62728;\r\n    fill: #d62728;\r\n}\r\n\r\n.with-transitions .nv-candlestickBar .nv-ticks .nv-tick {\r\n    transition: stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-candlestickBar .nv-ticks line {\r\n    stroke: #333;\r\n}\r\n\n.nv-force-node {\n    stroke: #fff;\n    stroke-width: 1.5px;\n}\n\n.nv-force-link {\n    stroke: #999;\n    stroke-opacity: .6;\n}\n\n.nv-force-node text {\n    stroke-width: 0px;\n}\n\n.nvd3 .nv-legend .nv-disabled rect {\n    /*fill-opacity: 0;*/\n}\n\n.nvd3 .nv-check-box .nv-box {\n    fill-opacity:0;\n    stroke-width:2;\n}\n\n.nvd3 .nv-check-box .nv-check {\n    fill-opacity:0;\n    stroke-width:4;\n}\n\n.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check {\n    fill-opacity:0;\n    stroke-opacity:0;\n}\n\n.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check {\n    opacity: 0;\n}\n\n/* line plus bar */\r\n.nvd3.nv-linePlusBar .nv-bar rect {\r\n    fill-opacity: .75;\r\n}\r\n\r\n.nvd3.nv-linePlusBar .nv-bar rect:hover {\r\n    fill-opacity: 1;\r\n}\n.nvd3 .nv-groups path.nv-line {\r\n    fill: none;\r\n}\r\n\r\n.nvd3 .nv-groups path.nv-area {\r\n    stroke: none;\r\n}\r\n\r\n.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {\r\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {\r\n    fill-opacity: .5 !important;\r\n    stroke-opacity: .5 !important;\r\n}\r\n\r\n\r\n.with-transitions .nvd3 .nv-groups .nv-point {\r\n    transition: stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-scatter .nv-groups .nv-point.hover,\r\n.nvd3 .nv-groups .nv-point.hover {\r\n    stroke-width: 7px;\r\n    fill-opacity: .95 !important;\r\n    stroke-opacity: .95 !important;\r\n}\r\n\r\n\r\n.nvd3 .nv-point-paths path {\r\n    stroke: #aaa;\r\n    stroke-opacity: 0;\r\n    fill: #eee;\r\n    fill-opacity: 0;\r\n}\r\n\r\n\r\n.nvd3 .nv-indexLine {\n    cursor: ew-resize;\r\n}\r\n\n/********************\r\n * SVG CSS\r\n */\r\n\r\n/********************\r\n  Default CSS for an svg element nvd3 used\r\n*/\r\nsvg.nvd3-svg {\r\n    -webkit-user-select: none;\r\n       -moz-user-select: none;\r\n        -ms-user-select: none;\r\n            user-select: none;\n    display: block;\r\n    width:100%;\r\n    height:100%;\r\n}\r\n\r\n/********************\r\n  Box shadow and border radius styling\r\n*/\r\n.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {\r\n    box-shadow: 0 5px 10px rgba(0,0,0,.2);\n    border-radius: 5px;\n}\r\n\r\n\r\n.nvd3 text {\r\n    font: normal 12px Arial, sans-serif;\r\n}\r\n\r\n.nvd3 .title {\r\n    font: bold 14px Arial, sans-serif;\r\n}\r\n\r\n.nvd3 .nv-background {\r\n    fill: white;\r\n    fill-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-noData {\r\n    font-size: 18px;\r\n    font-weight: bold;\r\n}\r\n\r\n\r\n/**********\r\n*  Brush\r\n*/\r\n\r\n.nv-brush .extent {\r\n    fill-opacity: .125;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nv-brush .resize path {\r\n    fill: #eee;\r\n    stroke: #666;\r\n}\r\n\r\n\r\n/**********\r\n*  Legend\r\n*/\r\n\r\n.nvd3 .nv-legend .nv-series {\r\n    cursor: pointer;\r\n}\r\n\r\n.nvd3 .nv-legend .nv-disabled circle {\r\n    fill-opacity: 0;\r\n}\r\n\r\n/* focus */\r\n.nvd3 .nv-brush .extent {\r\n    fill-opacity: 0 !important;\r\n}\r\n\r\n.nvd3 .nv-brushBackground rect {\r\n    stroke: #000;\r\n    stroke-width: .4;\r\n    fill: #fff;\r\n    fill-opacity: .7;\r\n}\r\n\r\n/**********\r\n*  Print\r\n*/\r\n\r\n@media print {\r\n    .nvd3 text {\n        stroke-width: 0;\n        fill-opacity: 1;\n    }\n}\r\n\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick {\r\n    stroke-width: 1px;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover {\r\n    stroke-width: 2px;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive {\r\n    stroke: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative {\r\n    stroke: #d62728;\r\n}\r\n\r\n\n.nvd3 .background path {\r\n    fill: none;\r\n    stroke: #EEE;\r\n    stroke-opacity: .4;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .foreground path {\r\n    fill: none;\r\n    stroke-opacity: .7;\r\n}\r\n\r\n.nvd3 .nv-parallelCoordinates-brush .extent {\n    fill: #fff;\r\n    fill-opacity: .6;\r\n    stroke: gray;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-parallelCoordinates .hover  {\r\n    fill-opacity: 1;\r\n\tstroke-width: 3px;\r\n}\r\n\r\n\r\n.nvd3 .missingValuesline line {\r\n  fill: none;\r\n  stroke: black;\r\n  stroke-width: 1;\r\n  stroke-opacity: 1;\r\n  stroke-dasharray: 5, 5;\n}\n\n.nvd3.nv-pie path {\r\n    stroke-opacity: 0;\r\n    transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-pie .nv-pie-title {\r\n    font-size: 24px;\r\n    fill: rgba(19, 196, 249, 0.59);\r\n}\r\n\r\n.nvd3.nv-pie .nv-slice text {\r\n    stroke: #000;\r\n    stroke-width: 0;\r\n}\r\n\r\n.nvd3.nv-pie path {\r\n    stroke: #fff;\r\n    stroke-width: 1px;\r\n    stroke-opacity: 1;\r\n}\r\n\r\n.nvd3.nv-pie path {\r\n    fill-opacity: .7;\r\n}\n\n.nvd3.nv-pie .hover path {\r\n    fill-opacity: 1;\r\n}\r\n\n.nvd3.nv-pie .nv-label {\n    pointer-events: none;\r\n}\r\n\n.nvd3.nv-pie .nv-label rect {\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n\n/* scatter */\r\n.nvd3 .nv-groups .nv-point.hover {\r\n    stroke-width: 20px;\r\n    stroke-opacity: .5;\r\n}\r\n\r\n.nvd3 .nv-scatter .nv-point.hover {\r\n    fill-opacity: 1;\r\n}\n\n.nv-noninteractive {\r\n    pointer-events: none;\r\n}\r\n\r\n.nv-distx, .nv-disty {\r\n    pointer-events: none;\r\n}\r\n\n/* sparkline */\r\n.nvd3.nv-sparkline path {\r\n    fill: none;\r\n}\r\n\r\n.nvd3.nv-sparklineplus g.nv-hoverValue {\r\n    pointer-events: none;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-hoverValue line {\r\n    stroke: #333;\r\n    stroke-width: 1.5px;\r\n}\r\n\r\n.nvd3.nv-sparklineplus,\r\n.nvd3.nv-sparklineplus g {\r\n    pointer-events: all;\r\n}\r\n\r\n.nvd3 .nv-hoverArea {\r\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-xValue,\r\n.nvd3.nv-sparklineplus .nv-yValue {\r\n    stroke-width: 0;\r\n    font-size: .9em;\r\n    font-weight: normal;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-yValue {\r\n    stroke: #f66;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-maxValue {\r\n    stroke: #2ca02c;\r\n    fill: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-minValue {\r\n    stroke: #d62728;\r\n    fill: #d62728;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-currentValue {\r\n    font-weight: bold;\r\n    font-size: 1.1em;\r\n}\n/* stacked area */\r\n.nvd3.nv-stackedarea path.nv-area {\r\n    fill-opacity: .7;\r\n    stroke-opacity: 0;\r\n    transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-stackedarea path.nv-area.hover {\r\n    fill-opacity: .9;\r\n}\r\n\r\n\r\n.nvd3.nv-stackedarea .nv-groups .nv-point {\r\n    stroke-opacity: 0;\r\n    fill-opacity: 0;\r\n}\n\n.nvtooltip {\n    position: absolute;\r\n    background-color: rgba(255,255,255,1.0);\r\n    color: rgba(0,0,0,1.0);\r\n    padding: 1px;\r\n    border: 1px solid rgba(0,0,0,.2);\r\n    z-index: 10000;\r\n    display: block;\r\n\r\n    font-family: Arial, sans-serif;\r\n    font-size: 13px;\r\n    text-align: left;\r\n    pointer-events: none;\r\n\r\n    white-space: nowrap;\r\n\r\n    -webkit-user-select: none;\r\n\r\n       -moz-user-select: none;\r\n\r\n        -ms-user-select: none;\r\n\r\n            user-select: none;\n}\n\r\n.nvtooltip {\r\n    background: rgba(255,255,255, 0.8);\r\n    border: 1px solid rgba(0,0,0,0.5);\r\n    border-radius: 4px;\r\n}\r\n\r\n/*Give tooltips that old fade in transition by\r\n    putting a \"with-transitions\" class on the container div.\r\n*/\r\n.nvtooltip.with-transitions, .with-transitions .nvtooltip {\r\n    transition: opacity 50ms linear;\r\n\n    transition-delay: 200ms;\n}\n\r\n.nvtooltip.x-nvtooltip,\r\n.nvtooltip.y-nvtooltip {\r\n    padding: 8px;\r\n}\r\n\r\n.nvtooltip h3 {\r\n    margin: 0;\r\n    padding: 4px 14px;\r\n    line-height: 18px;\r\n    font-weight: normal;\r\n    background-color: rgba(247,247,247,0.75);\r\n    color: rgba(0,0,0,1.0);\r\n    text-align: center;\r\n\r\n    border-bottom: 1px solid #ebebeb;\r\n\r\n    border-radius: 5px 5px 0 0;\n}\r\n\r\n.nvtooltip p {\r\n    margin: 0;\r\n    padding: 5px 14px;\r\n    text-align: center;\r\n}\r\n\r\n.nvtooltip span {\r\n    display: inline-block;\r\n    margin: 2px 0;\r\n}\r\n\r\n.nvtooltip table {\r\n    margin: 6px;\r\n    border-spacing:0;\r\n}\r\n\r\n\r\n.nvtooltip table td {\r\n    padding: 2px 9px 2px 0;\r\n    vertical-align: middle;\r\n}\r\n\r\n.nvtooltip table td.key {\r\n    font-weight: normal;\r\n}\n\n.nvtooltip table td.key.total {\r\n    font-weight: bold;\r\n}\r\n\n.nvtooltip table td.value {\n    text-align: right;\r\n    font-weight: bold;\r\n}\r\n\r\n.nvtooltip table td.percent {\r\n    color: darkgray;\r\n}\r\n\r\n.nvtooltip table tr.highlight td {\r\n    padding: 1px 9px 1px 0;\r\n    border-bottom-style: solid;\r\n    border-bottom-width: 1px;\r\n    border-top-style: solid;\r\n    border-top-width: 1px;\r\n}\r\n\r\n.nvtooltip table td.legend-color-guide div {\r\n    width: 8px;\r\n    height: 8px;\r\n    vertical-align: middle;\r\n}\r\n\r\n.nvtooltip table td.legend-color-guide div {\r\n    width: 12px;\r\n    height: 12px;\r\n    border: 1px solid #999;\r\n}\r\n\r\n.nvtooltip .footer {\r\n    padding: 3px;\r\n    text-align: center;\r\n}\r\n\r\n.nvtooltip-pending-removal {\r\n    pointer-events: none;\r\n    display: none;\r\n}\r\n\r\n\r\n/****\r\nInteractive Layer\r\n*/\r\n.nvd3 .nv-interactiveGuideLine {\r\n    pointer-events:none;\r\n}\n\n.nvd3 line.nv-guideline {\r\n    stroke: #ccc;\r\n}\r\n"
  },
  {
    "path": "build/nv.d3.js",
    "content": "/* nvd3 version 1.8.6-dev (https://github.com/novus/nvd3) 2018-02-24 */\n(function(){\n\n// set up main nv object\nvar nv = {};\n\n// the major global objects under the nv namespace\nnv.dev = false; //set false when in production\nnv.tooltip = nv.tooltip || {}; // For the tooltip system\nnv.utils = nv.utils || {}; // Utility subsystem\nnv.models = nv.models || {}; //stores all the possible models/components\nnv.charts = {}; //stores all the ready to use charts\nnv.logs = {}; //stores some statistics and potential error messages\nnv.dom = {}; //DOM manipulation functions\n\n// Node/CommonJS - require D3\nif (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined' && typeof(d3) == 'undefined') {\n    d3 = require('d3');\n}\n\nnv.dispatch = d3.dispatch('render_start', 'render_end');\n\n// Function bind polyfill\n// Needed ONLY for phantomJS as it's missing until version 2.0 which is unreleased as of this comment\n// https://github.com/ariya/phantomjs/issues/10522\n// http://kangax.github.io/compat-table/es5/#Function.prototype.bind\n// phantomJS is used for running the test suite\nif (!Function.prototype.bind) {\n    Function.prototype.bind = function (oThis) {\n        if (typeof this !== \"function\") {\n            // closest thing possible to the ECMAScript 5 internal IsCallable function\n            throw new TypeError(\"Function.prototype.bind - what is trying to be bound is not callable\");\n        }\n\n        var aArgs = Array.prototype.slice.call(arguments, 1),\n            fToBind = this,\n            fNOP = function () {},\n            fBound = function () {\n                return fToBind.apply(this instanceof fNOP && oThis\n                        ? this\n                        : oThis,\n                    aArgs.concat(Array.prototype.slice.call(arguments)));\n            };\n\n        fNOP.prototype = this.prototype;\n        fBound.prototype = new fNOP();\n        return fBound;\n    };\n}\n\n//  Development render timers - disabled if dev = false\nif (nv.dev) {\n    nv.dispatch.on('render_start', function(e) {\n        nv.logs.startTime = +new Date();\n    });\n\n    nv.dispatch.on('render_end', function(e) {\n        nv.logs.endTime = +new Date();\n        nv.logs.totalTime = nv.logs.endTime - nv.logs.startTime;\n        nv.log('total', nv.logs.totalTime); // used for development, to keep track of graph generation times\n    });\n}\n\n// Logs all arguments, and returns the last so you can test things in place\n// Note: in IE8 console.log is an object not a function, and if modernizr is used\n// then calling Function.prototype.bind with with anything other than a function\n// causes a TypeError to be thrown.\nnv.log = function() {\n    if (nv.dev && window.console && console.log && console.log.apply)\n        console.log.apply(console, arguments);\n    else if (nv.dev && window.console && typeof console.log == \"function\" && Function.prototype.bind) {\n        var log = Function.prototype.bind.call(console.log, console);\n        log.apply(console, arguments);\n    }\n    return arguments[arguments.length - 1];\n};\n\n// print console warning, should be used by deprecated functions\nnv.deprecated = function(name, info) {\n    if (console && console.warn) {\n        console.warn('nvd3 warning: `' + name + '` has been deprecated. ', info || '');\n    }\n};\n\n// The nv.render function is used to queue up chart rendering\n// in non-blocking async functions.\n// When all queued charts are done rendering, nv.dispatch.render_end is invoked.\nnv.render = function render(step) {\n    // number of graphs to generate in each timeout loop\n    step = step || 1;\n\n    nv.render.active = true;\n    nv.dispatch.render_start();\n\n    var renderLoop = function() {\n        var chart, graph;\n\n        for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) {\n            chart = graph.generate();\n            if (typeof graph.callback == typeof(Function)) graph.callback(chart);\n        }\n\n        nv.render.queue.splice(0, i);\n\n        if (nv.render.queue.length) {\n            setTimeout(renderLoop);\n        }\n        else {\n            nv.dispatch.render_end();\n            nv.render.active = false;\n        }\n    };\n\n    setTimeout(renderLoop);\n};\n\nnv.render.active = false;\nnv.render.queue = [];\n\n/*\nAdds a chart to the async rendering queue. This method can take arguments in two forms:\nnv.addGraph({\n    generate: <Function>\n    callback: <Function>\n})\n\nor\n\nnv.addGraph(<generate Function>, <callback Function>)\n\nThe generate function should contain code that creates the NVD3 model, sets options\non it, adds data to an SVG element, and invokes the chart model. The generate function\nshould return the chart model.  See examples/lineChart.html for a usage example.\n\nThe callback function is optional, and it is called when the generate function completes.\n*/\nnv.addGraph = function(obj) {\n    if (typeof arguments[0] === typeof(Function)) {\n        obj = {generate: arguments[0], callback: arguments[1]};\n    }\n\n    nv.render.queue.push(obj);\n\n    if (!nv.render.active) {\n        nv.render();\n    }\n};\n\n// Node/CommonJS exports\nif (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {\n  module.exports = nv;\n}\n\nif (typeof(window) !== 'undefined') {\n  window.nv = nv;\n}\n/* Facade for queueing DOM write operations\r\n * with Fastdom (https://github.com/wilsonpage/fastdom)\r\n * if available.\r\n * This could easily be extended to support alternate\r\n * implementations in the future.\r\n */\r\nnv.dom.write = function(callback) {\r\n\tif (window.fastdom !== undefined) {\r\n\t\treturn fastdom.mutate(callback);\r\n\t}\r\n\treturn callback();\r\n};\r\n\r\n/* Facade for queueing DOM read operations\r\n * with Fastdom (https://github.com/wilsonpage/fastdom)\r\n * if available.\r\n * This could easily be extended to support alternate\r\n * implementations in the future.\r\n */\r\nnv.dom.read = function(callback) {\r\n\tif (window.fastdom !== undefined) {\r\n\t\treturn fastdom.measure(callback);\r\n\t}\r\n\treturn callback();\r\n};\r\n/* Utility class to handle creation of an interactive layer.\n This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch\n containing the X-coordinate. It can also render a vertical line where the mouse is located.\n\n dispatch.elementMousemove is the important event to latch onto.  It is fired whenever the mouse moves over\n the rectangle. The dispatch is given one object which contains the mouseX/Y location.\n It also has 'pointXValue', which is the conversion of mouseX to the x-axis scale.\n */\nnv.interactiveGuideline = function() {\n    \"use strict\";\n\n    var margin = { left: 0, top: 0 } //Pass the chart's top and left magins. Used to calculate the mouseX/Y.\n        ,   width = null\n        ,   height = null\n        ,   xScale = d3.scale.linear()\n        ,   dispatch = d3.dispatch('elementMousemove', 'elementMouseout', 'elementClick', 'elementDblclick', 'elementMouseDown', 'elementMouseUp')\n        ,   showGuideLine = true\n        ,   svgContainer = null // Must pass the chart's svg, we'll use its mousemove event.\n        ,   tooltip = nv.models.tooltip()\n        ,   isMSIE =  window.ActiveXObject// Checkt if IE by looking for activeX. (excludes IE11)\n    ;\n\n    tooltip\n        .duration(0)\n        .hideDelay(0)\n        .hidden(false);\n\n    function layer(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this);\n            var availableWidth = (width || 960), availableHeight = (height || 400);\n            var wrap = container.selectAll(\"g.nv-wrap.nv-interactiveLineLayer\")\n                .data([data]);\n            var wrapEnter = wrap.enter()\n                .append(\"g\").attr(\"class\", \" nv-wrap nv-interactiveLineLayer\");\n            wrapEnter.append(\"g\").attr(\"class\",\"nv-interactiveGuideLine\");\n\n            if (!svgContainer) {\n                return;\n            }\n\n            function mouseHandler() {\n                var mouseX = d3.event.clientX - this.getBoundingClientRect().left;\n                var mouseY = d3.event.clientY - this.getBoundingClientRect().top;\n\n                var subtractMargin = true;\n                var mouseOutAnyReason = false;\n                if (isMSIE) {\n                    /*\n                     D3.js (or maybe SVG.getScreenCTM) has a nasty bug in Internet Explorer 10.\n                     d3.mouse() returns incorrect X,Y mouse coordinates when mouse moving\n                     over a rect in IE 10.\n                     However, d3.event.offsetX/Y also returns the mouse coordinates\n                     relative to the triggering <rect>. So we use offsetX/Y on IE.\n                     */\n                    mouseX = d3.event.offsetX;\n                    mouseY = d3.event.offsetY;\n\n                    /*\n                     On IE, if you attach a mouse event listener to the <svg> container,\n                     it will actually trigger it for all the child elements (like <path>, <circle>, etc).\n                     When this happens on IE, the offsetX/Y is set to where ever the child element\n                     is located.\n                     As a result, we do NOT need to subtract margins to figure out the mouse X/Y\n                     position under this scenario. Removing the line below *will* cause\n                     the interactive layer to not work right on IE.\n                     */\n                    if(d3.event.target.tagName !== \"svg\") {\n                        subtractMargin = false;\n                    }\n\n                    if (d3.event.target.className.baseVal.match(\"nv-legend\")) {\n                        mouseOutAnyReason = true;\n                    }\n\n                }\n\n                if(subtractMargin) {\n                    mouseX -= margin.left;\n                    mouseY -= margin.top;\n                }\n\n                /* If mouseX/Y is outside of the chart's bounds,\n                 trigger a mouseOut event.\n                 */\n                if (d3.event.type === 'mouseout'\n                    || mouseX < 0 || mouseY < 0\n                    || mouseX > availableWidth || mouseY > availableHeight\n                    || (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined)\n                    || mouseOutAnyReason\n                    ) {\n\n                    if (isMSIE) {\n                        if (d3.event.relatedTarget\n                            && d3.event.relatedTarget.ownerSVGElement === undefined\n                            && (d3.event.relatedTarget.className === undefined\n                                || d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass))) {\n\n                            return;\n                        }\n                    }\n                    dispatch.elementMouseout({\n                        mouseX: mouseX,\n                        mouseY: mouseY\n                    });\n                    layer.renderGuideLine(null); //hide the guideline\n                    tooltip.hidden(true);\n                    return;\n                } else {\n                    tooltip.hidden(false);\n                }\n\n\n                var scaleIsOrdinal = typeof xScale.rangeBands === 'function';\n                var pointXValue = undefined;\n\n                // Ordinal scale has no invert method\n                if (scaleIsOrdinal) {\n                    var elementIndex = d3.bisect(xScale.range(), mouseX) - 1;\n                    // Check if mouseX is in the range band\n                    if (xScale.range()[elementIndex] + xScale.rangeBand() >= mouseX) {\n                        pointXValue = xScale.domain()[d3.bisect(xScale.range(), mouseX) - 1];\n                    }\n                    else {\n                        dispatch.elementMouseout({\n                            mouseX: mouseX,\n                            mouseY: mouseY\n                        });\n                        layer.renderGuideLine(null); //hide the guideline\n                        tooltip.hidden(true);\n                        return;\n                    }\n                }\n                else {\n                    pointXValue = xScale.invert(mouseX);\n                }\n\n                dispatch.elementMousemove({\n                    mouseX: mouseX,\n                    mouseY: mouseY,\n                    pointXValue: pointXValue\n                });\n\n                //If user double clicks the layer, fire a elementDblclick\n                if (d3.event.type === \"dblclick\") {\n                    dispatch.elementDblclick({\n                        mouseX: mouseX,\n                        mouseY: mouseY,\n                        pointXValue: pointXValue\n                    });\n                }\n\n                // if user single clicks the layer, fire elementClick\n                if (d3.event.type === 'click') {\n                    dispatch.elementClick({\n                        mouseX: mouseX,\n                        mouseY: mouseY,\n                        pointXValue: pointXValue\n                    });\n                }\n\n                // if user presses mouse down the layer, fire elementMouseDown\n                if (d3.event.type === 'mousedown') {\n                \tdispatch.elementMouseDown({\n                \t\tmouseX: mouseX,\n                \t\tmouseY: mouseY,\n                \t\tpointXValue: pointXValue\n                \t});\n                }\n\n                // if user presses mouse down the layer, fire elementMouseUp\n                if (d3.event.type === 'mouseup') {\n                \tdispatch.elementMouseUp({\n                \t\tmouseX: mouseX,\n                \t\tmouseY: mouseY,\n                \t\tpointXValue: pointXValue\n                \t});\n                }\n            }\n\n            svgContainer\n                .on(\"touchmove\",mouseHandler)\n                .on(\"mousemove\",mouseHandler, true)\n                .on(\"mouseout\" ,mouseHandler,true)\n                .on(\"mousedown\" ,mouseHandler,true)\n                .on(\"mouseup\" ,mouseHandler,true)\n                .on(\"dblclick\" ,mouseHandler)\n                .on(\"click\", mouseHandler)\n            ;\n\n            layer.guideLine = null;\n            //Draws a vertical guideline at the given X postion.\n            layer.renderGuideLine = function(x) {\n                if (!showGuideLine) return;\n                if (layer.guideLine && layer.guideLine.attr(\"x1\") === x) return;\n                nv.dom.write(function() {\n                    var line = wrap.select(\".nv-interactiveGuideLine\")\n                        .selectAll(\"line\")\n                        .data((x != null) ? [nv.utils.NaNtoZero(x)] : [], String);\n                    line.enter()\n                        .append(\"line\")\n                        .attr(\"class\", \"nv-guideline\")\n                        .attr(\"x1\", function(d) { return d;})\n                        .attr(\"x2\", function(d) { return d;})\n                        .attr(\"y1\", availableHeight)\n                        .attr(\"y2\",0);\n                    line.exit().remove();\n                });\n            }\n        });\n    }\n\n    layer.dispatch = dispatch;\n    layer.tooltip = tooltip;\n\n    layer.margin = function(_) {\n        if (!arguments.length) return margin;\n        margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n        margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        return layer;\n    };\n\n    layer.width = function(_) {\n        if (!arguments.length) return width;\n        width = _;\n        return layer;\n    };\n\n    layer.height = function(_) {\n        if (!arguments.length) return height;\n        height = _;\n        return layer;\n    };\n\n    layer.xScale = function(_) {\n        if (!arguments.length) return xScale;\n        xScale = _;\n        return layer;\n    };\n\n    layer.showGuideLine = function(_) {\n        if (!arguments.length) return showGuideLine;\n        showGuideLine = _;\n        return layer;\n    };\n\n    layer.svgContainer = function(_) {\n        if (!arguments.length) return svgContainer;\n        svgContainer = _;\n        return layer;\n    };\n\n    return layer;\n};\n\n/* Utility class that uses d3.bisect to find the index in a given array, where a search value can be inserted.\n This is different from normal bisectLeft; this function finds the nearest index to insert the search value.\n\n For instance, lets say your array is [1,2,3,5,10,30], and you search for 28.\n Normal d3.bisectLeft will return 4, because 28 is inserted after the number 10.  But interactiveBisect will return 5\n because 28 is closer to 30 than 10.\n\n Unit tests can be found in: interactiveBisectTest.html\n\n Has the following known issues:\n * Will not work if the data points move backwards (ie, 10,9,8,7, etc) or if the data points are in random order.\n * Won't work if there are duplicate x coordinate values.\n */\nnv.interactiveBisect = function (values, searchVal, xAccessor) {\n    \"use strict\";\n    if (! (values instanceof Array)) {\n        return null;\n    }\n    var _xAccessor;\n    if (typeof xAccessor !== 'function') {\n        _xAccessor = function(d) {\n            return d.x;\n        }\n    } else {\n        _xAccessor = xAccessor;\n    }\n    var _cmp = function(d, v) {\n        // Accessors are no longer passed the index of the element along with\n        // the element itself when invoked by d3.bisector.\n        //\n        // Starting at D3 v3.4.4, d3.bisector() started inspecting the\n        // function passed to determine if it should consider it an accessor\n        // or a comparator. This meant that accessors that take two arguments\n        // (expecting an index as the second parameter) are treated as\n        // comparators where the second argument is the search value against\n        // which the first argument is compared.\n        return _xAccessor(d) - v;\n    };\n\n    var bisect = d3.bisector(_cmp).left;\n    var index = d3.max([0, bisect(values,searchVal) - 1]);\n    var currentValue = _xAccessor(values[index]);\n\n    if (typeof currentValue === 'undefined') {\n        currentValue = index;\n    }\n\n    if (currentValue === searchVal) {\n        return index; //found exact match\n    }\n\n    var nextIndex = d3.min([index+1, values.length - 1]);\n    var nextValue = _xAccessor(values[nextIndex]);\n\n    if (typeof nextValue === 'undefined') {\n        nextValue = nextIndex;\n    }\n\n    if (Math.abs(nextValue - searchVal) >= Math.abs(currentValue - searchVal)) {\n        return index;\n    } else {\n        return nextIndex\n    }\n};\n\n/*\n Returns the index in the array \"values\" that is closest to searchVal.\n Only returns an index if searchVal is within some \"threshold\".\n Otherwise, returns null.\n */\nnv.nearestValueIndex = function (values, searchVal, threshold) {\n    \"use strict\";\n    var yDistMax = Infinity, indexToHighlight = null;\n    values.forEach(function(d,i) {\n        var delta = Math.abs(searchVal - d);\n        if ( d != null && delta <= yDistMax && delta < threshold) {\n            yDistMax = delta;\n            indexToHighlight = i;\n        }\n    });\n    return indexToHighlight;\n};\n\n/* Model which can be instantiated to handle tooltip rendering.\n Example usage:\n var tip = nv.models.tooltip().gravity('w').distance(23)\n .data(myDataObject);\n\n tip();    //just invoke the returned function to render tooltip.\n */\nnv.models.tooltip = function() {\n    \"use strict\";\n\n    /*\n    Tooltip data. If data is given in the proper format, a consistent tooltip is generated.\n    Example Format of data:\n    {\n        key: \"Date\",\n        value: \"August 2009\",\n        series: [\n            {key: \"Series 1\", value: \"Value 1\", color: \"#000\"},\n            {key: \"Series 2\", value: \"Value 2\", color: \"#00f\"}\n        ]\n    }\n    */\n    var id = \"nvtooltip-\" + Math.floor(Math.random() * 100000) // Generates a unique id when you create a new tooltip() object.\n        ,   data = null\n        ,   gravity = 'w'   // Can be 'n','s','e','w'. Determines how tooltip is positioned.\n        ,   distance = 25 // Distance to offset tooltip from the mouse location.\n        ,   snapDistance = 0   // Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)\n        ,   classes = null  // Attaches additional CSS classes to the tooltip DIV that is created.\n        ,   hidden = true  // Start off hidden, toggle with hide/show functions below.\n        ,   hideDelay = 200  // Delay (in ms) before the tooltip hides after calling hide().\n        ,   tooltip = null // d3 select of the tooltip div.\n        ,   lastPosition = { left: null, top: null } // Last position the tooltip was in.\n        ,   enabled = true  // True -> tooltips are rendered. False -> don't render tooltips.\n        ,   duration = 100 // Tooltip movement duration, in ms.\n        ,   headerEnabled = true // If is to show the tooltip header.\n        ,   nvPointerEventsClass = \"nv-pointer-events-none\" // CSS class to specify whether element should not have mouse events.\n    ;\n\n    // Format function for the tooltip values column.\n    // d is value,\n    // i is series index\n    // p is point containing the value\n    var valueFormatter = function(d, i, p) {\n        return d;\n    };\n\n    // Format function for the tooltip header value.\n    var headerFormatter = function(d) {\n        return d;\n    };\n\n    var keyFormatter = function(d, i) {\n        return d;\n    };\n\n    // By default, the tooltip model renders a beautiful table inside a DIV, returned as HTML\n    // You can override this function if a custom tooltip is desired. For instance, you could directly manipulate\n    // the DOM by accessing elem and returning false.\n    var contentGenerator = function(d, elem) {\n        if (d === null) {\n            return '';\n        }\n\n        var table = d3.select(document.createElement(\"table\"));\n        if (headerEnabled) {\n            var theadEnter = table.selectAll(\"thead\")\n                .data([d])\n                .enter().append(\"thead\");\n\n            theadEnter.append(\"tr\")\n                .append(\"td\")\n                .attr(\"colspan\", 3)\n                .append(\"strong\")\n                .classed(\"x-value\", true)\n                .html(headerFormatter(d.value));\n        }\n\n        var tbodyEnter = table.selectAll(\"tbody\")\n            .data([d])\n            .enter().append(\"tbody\");\n\n        var trowEnter = tbodyEnter.selectAll(\"tr\")\n                .data(function(p) { return p.series})\n                .enter()\n                .append(\"tr\")\n                .classed(\"highlight\", function(p) { return p.highlight});\n\n        trowEnter.append(\"td\")\n            .classed(\"legend-color-guide\",true)\n            .append(\"div\")\n            .style(\"background-color\", function(p) { return p.color});\n\n        trowEnter.append(\"td\")\n            .classed(\"key\",true)\n            .classed(\"total\",function(p) { return !!p.total})\n            .html(function(p, i) { return keyFormatter(p.key, i)});\n\n        trowEnter.append(\"td\")\n            .classed(\"value\",true)\n            .html(function(p, i) { return valueFormatter(p.value, i, p) });\n\n        trowEnter.filter(function (p,i) { return p.percent !== undefined }).append(\"td\")\n            .classed(\"percent\", true)\n            .html(function(p, i) { return \"(\" + d3.format('%')(p.percent) + \")\" });\n\n        trowEnter.selectAll(\"td\").each(function(p) {\n            if (p.highlight) {\n                var opacityScale = d3.scale.linear().domain([0,1]).range([\"#fff\",p.color]);\n                var opacity = 0.6;\n                d3.select(this)\n                    .style(\"border-bottom-color\", opacityScale(opacity))\n                    .style(\"border-top-color\", opacityScale(opacity))\n                ;\n            }\n        });\n\n        var html = table.node().outerHTML;\n        if (d.footer !== undefined)\n            html += \"<div class='footer'>\" + d.footer + \"</div>\";\n        return html;\n\n    };\n\n    /*\n     Function that returns the position (relative to the viewport/document.body)\n     the tooltip should be placed in.\n     Should return: {\n        left: <leftPos>,\n        top: <topPos>\n     }\n     */\n    var position = function() {\n        var pos = {\n            left: d3.event !== null ? d3.event.clientX : 0,\n            top: d3.event !== null ? d3.event.clientY : 0\n        };\n\n        if(getComputedStyle(document.body).transform != 'none') {\n            // Take the offset into account, as now the tooltip is relative\n            // to document.body.\n            var client = document.body.getBoundingClientRect();\n            pos.left -= client.left;\n            pos.top -= client.top;\n        }\n\n        return pos;\n    };\n\n    var dataSeriesExists = function(d) {\n        if (d && d.series) {\n            if (nv.utils.isArray(d.series)) {\n                return true;\n            }\n            // if object, it's okay just convert to array of the object\n            if (nv.utils.isObject(d.series)) {\n                d.series = [d.series];\n                return true;\n            }\n        }\n        return false;\n    };\n\n    // Calculates the gravity offset of the tooltip. Parameter is position of tooltip\n    // relative to the viewport.\n    var calcGravityOffset = function(pos) {\n        var height = tooltip.node().offsetHeight,\n            width = tooltip.node().offsetWidth,\n            clientWidth = document.documentElement.clientWidth, // Don't want scrollbars.\n            clientHeight = document.documentElement.clientHeight, // Don't want scrollbars.\n            left, top, tmp;\n\n        // calculate position based on gravity\n        switch (gravity) {\n            case 'e':\n                left = - width - distance;\n                top = - (height / 2);\n                if(pos.left + left < 0) left = distance;\n                if((tmp = pos.top + top) < 0) top -= tmp;\n                if((tmp = pos.top + top + height) > clientHeight) top -= tmp - clientHeight;\n                break;\n            case 'w':\n                left = distance;\n                top = - (height / 2);\n                if (pos.left + left + width > clientWidth) left = - width - distance;\n                if ((tmp = pos.top + top) < 0) top -= tmp;\n                if ((tmp = pos.top + top + height) > clientHeight) top -= tmp - clientHeight;\n                break;\n            case 'n':\n                left = - (width / 2) - 5; // - 5 is an approximation of the mouse's height.\n                top = distance;\n                if (pos.top + top + height > clientHeight) top = - height - distance;\n                if ((tmp = pos.left + left) < 0) left -= tmp;\n                if ((tmp = pos.left + left + width) > clientWidth) left -= tmp - clientWidth;\n                break;\n            case 's':\n                left = - (width / 2);\n                top = - height - distance;\n                if (pos.top + top < 0) top = distance;\n                if ((tmp = pos.left + left) < 0) left -= tmp;\n                if ((tmp = pos.left + left + width) > clientWidth) left -= tmp - clientWidth;\n                break;\n            case 'center':\n                left = - (width / 2);\n                top = - (height / 2);\n                break;\n            default:\n                left = 0;\n                top = 0;\n                break;\n        }\n\n        return { 'left': left, 'top': top };\n    };\n\n    /*\n     Positions the tooltip in the correct place, as given by the position() function.\n     */\n    var positionTooltip = function() {\n        nv.dom.read(function() {\n            var pos = position(),\n                gravityOffset = calcGravityOffset(pos),\n                left = pos.left + gravityOffset.left,\n                top = pos.top + gravityOffset.top;\n\n            // delay hiding a bit to avoid flickering\n            if (hidden) {\n                tooltip\n                    .interrupt()\n                    .transition()\n                    .delay(hideDelay)\n                    .duration(0)\n                    .style('opacity', 0);\n            } else {\n                // using tooltip.style('transform') returns values un-usable for tween\n                var old_translate = 'translate(' + lastPosition.left + 'px, ' + lastPosition.top + 'px)';\n                var new_translate = 'translate(' + Math.round(left) + 'px, ' + Math.round(top) + 'px)';\n                var translateInterpolator = d3.interpolateString(old_translate, new_translate);\n                var is_hidden = tooltip.style('opacity') < 0.1;\n\n                tooltip\n                    .interrupt() // cancel running transitions\n                    .transition()\n                    .duration(is_hidden ? 0 : duration)\n                    // using tween since some versions of d3 can't auto-tween a translate on a div\n                    .styleTween('transform', function (d) {\n                        return translateInterpolator;\n                    }, 'important')\n                    // Safari has its own `-webkit-transform` and does not support `transform`\n                    .styleTween('-webkit-transform', function (d) {\n                        return translateInterpolator;\n                    })\n                    .style('-ms-transform', new_translate)\n                    .style('opacity', 1);\n            }\n\n            lastPosition.left = left;\n            lastPosition.top = top;\n        });\n    };\n\n    // Creates new tooltip container, or uses existing one on DOM.\n    function initTooltip() {\n        if (!tooltip || !tooltip.node()) {\n            // Create new tooltip div if it doesn't exist on DOM.\n\n            var data = [1];\n            tooltip = d3.select(document.body).selectAll('#'+id).data(data);\n\n            tooltip.enter().append('div')\n                   .attr(\"class\", \"nvtooltip \" + (classes ? classes : \"xy-tooltip\"))\n                   .attr(\"id\", id)\n                   .style(\"top\", 0).style(\"left\", 0)\n                   .style('opacity', 0)\n                   .style('position', 'absolute')\n                   .selectAll(\"div, table, td, tr\").classed(nvPointerEventsClass, true)\n                   .classed(nvPointerEventsClass, true);\n\n            tooltip.exit().remove()\n        }\n    }\n\n    // Draw the tooltip onto the DOM.\n    function nvtooltip() {\n        if (!enabled) return;\n        if (!dataSeriesExists(data)) return;\n\n        nv.dom.write(function () {\n            initTooltip();\n            // Generate data and set it into tooltip.\n            // Bonus - If you override contentGenerator and return false, you can use something like\n            //         Angular, React or Knockout to bind the data for your tooltip directly to the DOM.\n            var newContent = contentGenerator(data, tooltip.node());\n            if (newContent) {\n                tooltip.node().innerHTML = newContent;\n            }\n\n            positionTooltip();\n        });\n\n        return nvtooltip;\n    }\n\n    nvtooltip.nvPointerEventsClass = nvPointerEventsClass;\n    nvtooltip.options = nv.utils.optionsFunc.bind(nvtooltip);\n\n    nvtooltip._options = Object.create({}, {\n        // simple read/write options\n        duration: {get: function(){return duration;}, set: function(_){duration=_;}},\n        gravity: {get: function(){return gravity;}, set: function(_){gravity=_;}},\n        distance: {get: function(){return distance;}, set: function(_){distance=_;}},\n        snapDistance: {get: function(){return snapDistance;}, set: function(_){snapDistance=_;}},\n        classes: {get: function(){return classes;}, set: function(_){classes=_;}},\n        enabled: {get: function(){return enabled;}, set: function(_){enabled=_;}},\n        hideDelay: {get: function(){return hideDelay;}, set: function(_){hideDelay=_;}},\n        contentGenerator: {get: function(){return contentGenerator;}, set: function(_){contentGenerator=_;}},\n        valueFormatter: {get: function(){return valueFormatter;}, set: function(_){valueFormatter=_;}},\n        headerFormatter: {get: function(){return headerFormatter;}, set: function(_){headerFormatter=_;}},\n        keyFormatter: {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        headerEnabled: {get: function(){return headerEnabled;}, set: function(_){headerEnabled=_;}},\n        position: {get: function(){return position;}, set: function(_){position=_;}},\n\n        // Deprecated options\n        chartContainer: {get: function(){return document.body;}, set: function(_){\n            // deprecated after 1.8.3\n            nv.deprecated('chartContainer', 'feature removed after 1.8.3');\n        }},\n        fixedTop: {get: function(){return null;}, set: function(_){\n            // deprecated after 1.8.1\n            nv.deprecated('fixedTop', 'feature removed after 1.8.1');\n        }},\n        offset: {get: function(){return {left: 0, top: 0};}, set: function(_){\n            // deprecated after 1.8.1\n            nv.deprecated('offset', 'use chart.tooltip.distance() instead');\n        }},\n\n        // options with extra logic\n        hidden: {get: function(){return hidden;}, set: function(_){\n            if (hidden != _) {\n                hidden = !!_;\n                nvtooltip();\n            }\n        }},\n        data: {get: function(){return data;}, set: function(_){\n            // if showing a single data point, adjust data format with that\n            if (_.point) {\n                _.value = _.point.x;\n                _.series = _.series || {};\n                _.series.value = _.point.y;\n                _.series.color = _.point.color || _.series.color;\n            }\n            data = _;\n        }},\n\n        // read only properties\n        node: {get: function(){return tooltip.node();}, set: function(_){}},\n        id: {get: function(){return id;}, set: function(_){}}\n    });\n\n    nv.utils.initOptions(nvtooltip);\n    return nvtooltip;\n};\n\n\n/*\nGets the browser window size\n\nReturns object with height and width properties\n */\nnv.utils.windowSize = function() {\n    // Sane defaults\n    var size = {width: 640, height: 480};\n\n    // Most recent browsers use\n    if (window.innerWidth && window.innerHeight) {\n        size.width = window.innerWidth;\n        size.height = window.innerHeight;\n        return (size);\n    }\n\n    // IE can use depending on mode it is in\n    if (document.compatMode=='CSS1Compat' &&\n        document.documentElement &&\n        document.documentElement.offsetWidth ) {\n\n        size.width = document.documentElement.offsetWidth;\n        size.height = document.documentElement.offsetHeight;\n        return (size);\n    }\n\n    // Earlier IE uses Doc.body\n    if (document.body && document.body.offsetWidth) {\n        size.width = document.body.offsetWidth;\n        size.height = document.body.offsetHeight;\n        return (size);\n    }\n\n    return (size);\n};\n\n\n/* handle dumb browser quirks...  isinstance breaks if you use frames\ntypeof returns 'object' for null, NaN is a number, etc.\n */\nnv.utils.isArray = Array.isArray;\nnv.utils.isObject = function(a) {\n    return a !== null && typeof a === 'object';\n};\nnv.utils.isFunction = function(a) {\n    return typeof a === 'function';\n};\nnv.utils.isDate = function(a) {\n    return toString.call(a) === '[object Date]';\n};\nnv.utils.isNumber = function(a) {\n    return !isNaN(a) && typeof a === 'number';\n};\n\n\n/*\nBinds callback function to run when window is resized\n */\nnv.utils.windowResize = function(handler) {\n    if (window.addEventListener) {\n        window.addEventListener('resize', handler);\n    } else {\n        nv.log(\"ERROR: Failed to bind to window.resize with: \", handler);\n    }\n    // return object with clear function to remove the single added callback.\n    return {\n        callback: handler,\n        clear: function() {\n            window.removeEventListener('resize', handler);\n        }\n    }\n};\n\n\n/*\nBackwards compatible way to implement more d3-like coloring of graphs.\nCan take in nothing, an array, or a function/scale\nTo use a normal scale, get the range and pass that because we must be able\nto take two arguments and use the index to keep backward compatibility\n*/\nnv.utils.getColor = function(color) {\n    //if you pass in nothing, get default colors back\n    if (color === undefined) {\n        return nv.utils.defaultColor();\n\n    //if passed an array, turn it into a color scale\n    } else if(nv.utils.isArray(color)) {\n        var color_scale = d3.scale.ordinal().range(color);\n        return function(d, i) {\n            var key = i === undefined ? d : i;\n            return d.color || color_scale(key);\n        };\n\n    //if passed a function or scale, return it, or whatever it may be\n    //external libs, such as angularjs-nvd3-directives use this\n    } else {\n        //can't really help it if someone passes rubbish as color\n        return color;\n    }\n};\n\n\n/*\nDefault color chooser uses a color scale of 20 colors from D3\n https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors\n */\nnv.utils.defaultColor = function() {\n    // get range of the scale so we'll turn it into our own function.\n    return nv.utils.getColor(d3.scale.category20().range());\n};\n\n\n/*\nReturns a color function that takes the result of 'getKey' for each series and\nlooks for a corresponding color from the dictionary\n*/\nnv.utils.customTheme = function(dictionary, getKey, defaultColors) {\n    // use default series.key if getKey is undefined\n    getKey = getKey || function(series) { return series.key };\n    defaultColors = defaultColors || d3.scale.category20().range();\n\n    // start at end of default color list and walk back to index 0\n    var defIndex = defaultColors.length;\n\n    return function(series, index) {\n        var key = getKey(series);\n        if (nv.utils.isFunction(dictionary[key])) {\n            return dictionary[key]();\n        } else if (dictionary[key] !== undefined) {\n            return dictionary[key];\n        } else {\n            // no match in dictionary, use a default color\n            if (!defIndex) {\n                // used all the default colors, start over\n                defIndex = defaultColors.length;\n            }\n            defIndex = defIndex - 1;\n            return defaultColors[defIndex];\n        }\n    };\n};\n\n\n/*\nFrom the PJAX example on d3js.org, while this is not really directly needed\nit's a very cool method for doing pjax, I may expand upon it a little bit,\nopen to suggestions on anything that may be useful\n*/\nnv.utils.pjax = function(links, content) {\n\n    var load = function(href) {\n        d3.html(href, function(fragment) {\n            var target = d3.select(content).node();\n            target.parentNode.replaceChild(\n                d3.select(fragment).select(content).node(),\n                target);\n            nv.utils.pjax(links, content);\n        });\n    };\n\n    d3.selectAll(links).on(\"click\", function() {\n        history.pushState(this.href, this.textContent, this.href);\n        load(this.href);\n        d3.event.preventDefault();\n    });\n\n    d3.select(window).on(\"popstate\", function() {\n        if (d3.event.state) {\n            load(d3.event.state);\n        }\n    });\n};\n\n\n/*\nFor when we want to approximate the width in pixels for an SVG:text element.\nMost common instance is when the element is in a display:none; container.\nForumla is : text.length * font-size * constant_factor\n*/\nnv.utils.calcApproxTextWidth = function (svgTextElem) {\n    if (nv.utils.isFunction(svgTextElem.style) && nv.utils.isFunction(svgTextElem.text)) {\n        var fontSize = parseInt(svgTextElem.style(\"font-size\").replace(\"px\",\"\"), 10);\n        var textLength = svgTextElem.text().length;\n        return nv.utils.NaNtoZero(textLength * fontSize * 0.5);\n    }\n    return 0;\n};\n\n\n/*\nNumbers that are undefined, null or NaN, convert them to zeros.\n*/\nnv.utils.NaNtoZero = function(n) {\n    if (!nv.utils.isNumber(n)\n        || isNaN(n)\n        || n === null\n        || n === Infinity\n        || n === -Infinity) {\n\n        return 0;\n    }\n    return n;\n};\n\n/*\nAdd a way to watch for d3 transition ends to d3\n*/\nd3.selection.prototype.watchTransition = function(renderWatch){\n    var args = [this].concat([].slice.call(arguments, 1));\n    return renderWatch.transition.apply(renderWatch, args);\n};\n\n\n/*\nHelper object to watch when d3 has rendered something\n*/\nnv.utils.renderWatch = function(dispatch, duration) {\n    if (!(this instanceof nv.utils.renderWatch)) {\n        return new nv.utils.renderWatch(dispatch, duration);\n    }\n\n    var _duration = duration !== undefined ? duration : 250;\n    var renderStack = [];\n    var self = this;\n\n    this.models = function(models) {\n        models = [].slice.call(arguments, 0);\n        models.forEach(function(model){\n            model.__rendered = false;\n            (function(m){\n                m.dispatch.on('renderEnd', function(arg){\n                    m.__rendered = true;\n                    self.renderEnd('model');\n                });\n            })(model);\n\n            if (renderStack.indexOf(model) < 0) {\n                renderStack.push(model);\n            }\n        });\n    return this;\n    };\n\n    this.reset = function(duration) {\n        if (duration !== undefined) {\n            _duration = duration;\n        }\n        renderStack = [];\n    };\n\n    this.transition = function(selection, args, duration) {\n        args = arguments.length > 1 ? [].slice.call(arguments, 1) : [];\n\n        if (args.length > 1) {\n            duration = args.pop();\n        } else {\n            duration = _duration !== undefined ? _duration : 250;\n        }\n        selection.__rendered = false;\n\n        if (renderStack.indexOf(selection) < 0) {\n            renderStack.push(selection);\n        }\n\n        if (duration === 0) {\n            selection.__rendered = true;\n            selection.delay = function() { return this; };\n            selection.duration = function() { return this; };\n            return selection;\n        } else {\n            if (selection.length === 0) {\n                selection.__rendered = true;\n            } else if (selection.every( function(d){ return !d.length; } )) {\n                selection.__rendered = true;\n            } else {\n                selection.__rendered = false;\n            }\n\n            var n = 0;\n            return selection\n                .transition()\n                .duration(duration)\n                .each(function(){ ++n; })\n                .each('end', function(d, i) {\n                    if (--n === 0) {\n                        selection.__rendered = true;\n                        self.renderEnd.apply(this, args);\n                    }\n                });\n        }\n    };\n\n    this.renderEnd = function() {\n        if (renderStack.every( function(d){ return d.__rendered; } )) {\n            renderStack.forEach( function(d){ d.__rendered = false; });\n            dispatch.renderEnd.apply(this, arguments);\n        }\n    }\n\n};\n\n\n/*\nTakes multiple objects and combines them into the first one (dst)\nexample:  nv.utils.deepExtend({a: 1}, {a: 2, b: 3}, {c: 4});\ngives:  {a: 2, b: 3, c: 4}\n*/\nnv.utils.deepExtend = function(dst){\n    var sources = arguments.length > 1 ? [].slice.call(arguments, 1) : [];\n    sources.forEach(function(source) {\n        for (var key in source) {\n            var isArray = nv.utils.isArray(dst[key]);\n            var isObject = nv.utils.isObject(dst[key]);\n            var srcObj = nv.utils.isObject(source[key]);\n\n            if (isObject && !isArray && srcObj) {\n                nv.utils.deepExtend(dst[key], source[key]);\n            } else {\n                dst[key] = source[key];\n            }\n        }\n    });\n};\n\n\n/*\nstate utility object, used to track d3 states in the models\n*/\nnv.utils.state = function(){\n    if (!(this instanceof nv.utils.state)) {\n        return new nv.utils.state();\n    }\n    var state = {};\n    var _self = this;\n    var _setState = function(){};\n    var _getState = function(){ return {}; };\n    var init = null;\n    var changed = null;\n\n    this.dispatch = d3.dispatch('change', 'set');\n\n    this.dispatch.on('set', function(state){\n        _setState(state, true);\n    });\n\n    this.getter = function(fn){\n        _getState = fn;\n        return this;\n    };\n\n    this.setter = function(fn, callback) {\n        if (!callback) {\n            callback = function(){};\n        }\n        _setState = function(state, update){\n            fn(state);\n            if (update) {\n                callback();\n            }\n        };\n        return this;\n    };\n\n    this.init = function(state){\n        init = init || {};\n        nv.utils.deepExtend(init, state);\n    };\n\n    var _set = function(){\n        var settings = _getState();\n\n        if (JSON.stringify(settings) === JSON.stringify(state)) {\n            return false;\n        }\n\n        for (var key in settings) {\n            if (state[key] === undefined) {\n                state[key] = {};\n            }\n            state[key] = settings[key];\n            changed = true;\n        }\n        return true;\n    };\n\n    this.update = function(){\n        if (init) {\n            _setState(init, false);\n            init = null;\n        }\n        if (_set.call(this)) {\n            this.dispatch.change(state);\n        }\n    };\n\n};\n\n\n/*\nSnippet of code you can insert into each nv.models.* to give you the ability to\ndo things like:\nchart.options({\n  showXAxis: true,\n  tooltips: true\n});\n\nTo enable in the chart:\nchart.options = nv.utils.optionsFunc.bind(chart);\n*/\nnv.utils.optionsFunc = function(args) {\n    if (args) {\n        d3.map(args).forEach((function(key,value) {\n            if (nv.utils.isFunction(this[key])) {\n                this[key](value);\n            }\n        }).bind(this));\n    }\n    return this;\n};\n\n\n/*\nnumTicks:  requested number of ticks\ndata:  the chart data\n\nreturns the number of ticks to actually use on X axis, based on chart data\nto avoid duplicate ticks with the same value\n*/\nnv.utils.calcTicksX = function(numTicks, data) {\n    // find max number of values from all data streams\n    var numValues = 1;\n    var i = 0;\n    for (i; i < data.length; i += 1) {\n        var stream_len = data[i] && data[i].values ? data[i].values.length : 0;\n        numValues = stream_len > numValues ? stream_len : numValues;\n    }\n    nv.log(\"Requested number of ticks: \", numTicks);\n    nv.log(\"Calculated max values to be: \", numValues);\n    // make sure we don't have more ticks than values to avoid duplicates\n    numTicks = numTicks > numValues ? numTicks = numValues - 1 : numTicks;\n    // make sure we have at least one tick\n    numTicks = numTicks < 1 ? 1 : numTicks;\n    // make sure it's an integer\n    numTicks = Math.floor(numTicks);\n    nv.log(\"Calculating tick count as: \", numTicks);\n    return numTicks;\n};\n\n\n/*\nreturns number of ticks to actually use on Y axis, based on chart data\n*/\nnv.utils.calcTicksY = function(numTicks, data) {\n    // currently uses the same logic but we can adjust here if needed later\n    return nv.utils.calcTicksX(numTicks, data);\n};\n\n\n/*\nAdd a particular option from an options object onto chart\nOptions exposed on a chart are a getter/setter function that returns chart\non set to mimic typical d3 option chaining, e.g. svg.option1('a').option2('b');\n\noption objects should be generated via Object.create() to provide\nthe option of manipulating data via get/set functions.\n*/\nnv.utils.initOption = function(chart, name) {\n    // if it's a call option, just call it directly, otherwise do get/set\n    if (chart._calls && chart._calls[name]) {\n        chart[name] = chart._calls[name];\n    } else {\n        chart[name] = function (_) {\n            if (!arguments.length) return chart._options[name];\n            chart._overrides[name] = true;\n            chart._options[name] = _;\n            return chart;\n        };\n        // calling the option as _option will ignore if set by option already\n        // so nvd3 can set options internally but the stop if set manually\n        chart['_' + name] = function(_) {\n            if (!arguments.length) return chart._options[name];\n            if (!chart._overrides[name]) {\n                chart._options[name] = _;\n            }\n            return chart;\n        }\n    }\n};\n\n\n/*\nAdd all options in an options object to the chart\n*/\nnv.utils.initOptions = function(chart) {\n    chart._overrides = chart._overrides || {};\n    var ops = Object.getOwnPropertyNames(chart._options || {});\n    var calls = Object.getOwnPropertyNames(chart._calls || {});\n    ops = ops.concat(calls);\n    for (var i in ops) {\n        nv.utils.initOption(chart, ops[i]);\n    }\n};\n\n\n/*\nInherit options from a D3 object\nd3.rebind makes calling the function on target actually call it on source\nAlso use _d3options so we can track what we inherit for documentation and chained inheritance\n*/\nnv.utils.inheritOptionsD3 = function(target, d3_source, oplist) {\n    target._d3options = oplist.concat(target._d3options || []);\n    // Find unique d3 options (string) and update d3options\n    target._d3options = (target._d3options || []).filter(function(item, i, ar){ return ar.indexOf(item) === i; });\n    oplist.unshift(d3_source);\n    oplist.unshift(target);\n    d3.rebind.apply(this, oplist);\n};\n\n\n/*\nRemove duplicates from an array\n*/\nnv.utils.arrayUnique = function(a) {\n    return a.sort().filter(function(item, pos) {\n        return !pos || item != a[pos - 1];\n    });\n};\n\n\n/*\nKeeps a list of custom symbols to draw from in addition to d3.svg.symbol\nNecessary since d3 doesn't let you extend its list -_-\nAdd new symbols by doing nv.utils.symbols.set('name', function(size){...});\n*/\nnv.utils.symbolMap = d3.map();\n\n\n/*\nReplaces d3.svg.symbol so that we can look both there and our own map\n */\nnv.utils.symbol = function() {\n    var type,\n        size = 64;\n    function symbol(d,i) {\n        var t = type.call(this,d,i);\n        var s = size.call(this,d,i);\n        if (d3.svg.symbolTypes.indexOf(t) !== -1) {\n            return d3.svg.symbol().type(t).size(s)();\n        } else {\n            return nv.utils.symbolMap.get(t)(s);\n        }\n    }\n    symbol.type = function(_) {\n        if (!arguments.length) return type;\n        type = d3.functor(_);\n        return symbol;\n    };\n    symbol.size = function(_) {\n        if (!arguments.length) return size;\n        size = d3.functor(_);\n        return symbol;\n    };\n    return symbol;\n};\n\n\n/*\nInherit option getter/setter functions from source to target\nd3.rebind makes calling the function on target actually call it on source\nAlso track via _inherited and _d3options so we can track what we inherit\nfor documentation generation purposes and chained inheritance\n*/\nnv.utils.inheritOptions = function(target, source) {\n    // inherit all the things\n    var ops = Object.getOwnPropertyNames(source._options || {});\n    var calls = Object.getOwnPropertyNames(source._calls || {});\n    var inherited = source._inherited || [];\n    var d3ops = source._d3options || [];\n    var args = ops.concat(calls).concat(inherited).concat(d3ops);\n    args.unshift(source);\n    args.unshift(target);\n    d3.rebind.apply(this, args);\n    // pass along the lists to keep track of them, don't allow duplicates\n    target._inherited = nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited || []));\n    target._d3options = nv.utils.arrayUnique(d3ops.concat(target._d3options || []));\n};\n\n\n/*\nRuns common initialize code on the svg before the chart builds\n*/\nnv.utils.initSVG = function(svg) {\n    svg.classed({'nvd3-svg':true});\n};\n\n\n/*\nSanitize and provide default for the container height.\n*/\nnv.utils.sanitizeHeight = function(height, container) {\n    return (height || parseInt(container.style('height'), 10) || 400);\n};\n\n\n/*\nSanitize and provide default for the container width.\n*/\nnv.utils.sanitizeWidth = function(width, container) {\n    return (width || parseInt(container.style('width'), 10) || 960);\n};\n\n\n/*\nCalculate the available height for a chart.\n*/\nnv.utils.availableHeight = function(height, container, margin) {\n    return Math.max(0,nv.utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\n};\n\n/*\nCalculate the available width for a chart.\n*/\nnv.utils.availableWidth = function(width, container, margin) {\n    return Math.max(0,nv.utils.sanitizeWidth(width, container) - margin.left - margin.right);\n};\n\n/*\nClear any rendered chart components and display a chart's 'noData' message\n*/\nnv.utils.noData = function(chart, container) {\n    var opt = chart.options(),\n        margin = opt.margin(),\n        noData = opt.noData(),\n        data = (noData == null) ? [\"No Data Available.\"] : [noData],\n        height = nv.utils.availableHeight(null, container, margin),\n        width = nv.utils.availableWidth(null, container, margin),\n        x = margin.left + width/2,\n        y = margin.top + height/2;\n\n    //Remove any previously created chart components\n    container.selectAll('g').remove();\n\n    var noDataText = container.selectAll('.nv-noData').data(data);\n\n    noDataText.enter().append('text')\n        .attr('class', 'nvd3 nv-noData')\n        .attr('dy', '-.7em')\n        .style('text-anchor', 'middle');\n\n    noDataText\n        .attr('x', x)\n        .attr('y', y)\n        .text(function(t){ return t; });\n};\n\n/*\n Wrap long labels.\n */\nnv.utils.wrapTicks = function (text, width) {\n    text.each(function() {\n        var text = d3.select(this),\n            words = text.text().split(/\\s+/).reverse(),\n            word,\n            line = [],\n            lineNumber = 0,\n            lineHeight = 1.1,\n            y = text.attr(\"y\"),\n            dy = parseFloat(text.attr(\"dy\")),\n            tspan = text.text(null).append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", dy + \"em\");\n        while (word = words.pop()) {\n            line.push(word);\n            tspan.text(line.join(\" \"));\n            if (tspan.node().getComputedTextLength() > width) {\n                line.pop();\n                tspan.text(line.join(\" \"));\n                line = [word];\n                tspan = text.append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", ++lineNumber * lineHeight + dy + \"em\").text(word);\n            }\n        }\n    });\n};\n\n/*\nCheck equality of 2 array\n*/\nnv.utils.arrayEquals = function (array1, array2) {\n    if (array1 === array2)\n        return true;\n\n    if (!array1 || !array2)\n        return false;\n\n    // compare lengths - can save a lot of time\n    if (array1.length != array2.length)\n        return false;\n\n    for (var i = 0,\n        l = array1.length; i < l; i++) {\n        // Check if we have nested arrays\n        if (array1[i] instanceof Array && array2[i] instanceof Array) {\n            // recurse into the nested arrays\n            if (!nv.arrayEquals(array1[i], array2[i]))\n                return false;\n        } else if (array1[i] != array2[i]) {\n            // Warning - two different object instances will never be equal: {x:20} != {x:20}\n            return false;\n        }\n    }\n    return true;\n};\n\n/*\n Check if a point within an arc\n */\nnv.utils.pointIsInArc = function(pt, ptData, d3Arc) {\n    // Center of the arc is assumed to be 0,0\n    // (pt.x, pt.y) are assumed to be relative to the center\n    var r1 = d3Arc.innerRadius()(ptData), // Note: Using the innerRadius\n      r2 = d3Arc.outerRadius()(ptData),\n      theta1 = d3Arc.startAngle()(ptData),\n      theta2 = d3Arc.endAngle()(ptData);\n\n    var dist = pt.x * pt.x + pt.y * pt.y,\n      angle = Math.atan2(pt.x, -pt.y); // Note: different coordinate system.\n\n    angle = (angle < 0) ? (angle + Math.PI * 2) : angle;\n\n    return (r1 * r1 <= dist) && (dist <= r2 * r2) &&\n      (theta1 <= angle) && (angle <= theta2);\n};\n\nnv.models.axis = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var axis = d3.svg.axis();\n    var scale = d3.scale.linear();\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 75 //only used for tickLabel currently\n        , height = 60 //only used for tickLabel currently\n        , axisLabelText = null\n        , showMaxMin = true //TODO: showMaxMin should be disabled on all ordinal scaled axes\n        , rotateLabels = 0\n        , rotateYLabel = true\n        , staggerLabels = false\n        , isOrdinal = false\n        , ticks = null\n        , axisLabelDistance = 0\n        , fontSize = undefined\n        , duration = 250\n        , dispatch = d3.dispatch('renderEnd')\n        , tickFormatMaxMin\n        ;\n    axis\n        .scale(scale)\n        .orient('bottom')\n        .tickFormat(function(d) { return d })\n    ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var scale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-axis').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-axis');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            if (ticks !== null)\n                axis.ticks(ticks);\n            else if (axis.orient() == 'top' || axis.orient() == 'bottom')\n                axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100);\n\n            //TODO: consider calculating width/height based on whether or not label is added, for reference in charts using this component\n            g.watchTransition(renderWatch, 'axis').call(axis);\n\n            scale0 = scale0 || axis.scale();\n\n            var fmt = axis.tickFormat();\n            if (fmt == null) {\n                fmt = scale0.tickFormat();\n            }\n\n            var axisLabel = g.selectAll('text.nv-axislabel')\n                .data([axisLabelText || null]);\n            axisLabel.exit().remove();\n\n            //only skip when fontSize is undefined so it can be cleared with a null or blank string\n            if (fontSize !== undefined) {\n                g.selectAll('g').select(\"text\").style('font-size', fontSize);\n            }\n\n            var xLabelMargin;\n            var axisMaxMin;\n            var w;\n            switch (axis.orient()) {\n                case 'top':\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                  w = 0;\n                  if (scale.range().length === 1) {\n                    w = isOrdinal ? scale.range()[0] * 2 + scale.rangeBand() : 0;\n                  } else if (scale.range().length === 2) {\n                    w = isOrdinal ? scale.range()[0] + scale.range()[1] + scale.rangeBand() : scale.range()[1];\n                  } else if ( scale.range().length > 2){\n                    w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]);\n                  };\n                    axisLabel\n                        .attr('text-anchor', 'middle')\n                        .attr('y', 0)\n                        .attr('x', w/2);\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ')\n                        }).append('text');\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero(scale(d)) + ',0)'\n                            })\n                            .select('text')\n                            .attr('dy', '-0.5em')\n                            .attr('y', -axis.tickPadding())\n                            .attr('text-anchor', 'middle')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max top')\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero(scale.range()[i]) + ',0)'\n                            });\n                    }\n                    break;\n                case 'bottom':\n                    xLabelMargin = axisLabelDistance + 36;\n                    var maxTextWidth = 30;\n                    var textHeight = 0;\n                    var xTicks = g.selectAll('g').select(\"text\");\n                    var rotateLabelsRule = '';\n                    if (rotateLabels%360) {\n                        //Reset transform on ticks so textHeight can be calculated correctly\n                        xTicks.attr('transform', '');\n                        //Calculate the longest xTick width\n                        xTicks.each(function(d,i){\n                            var box = this.getBoundingClientRect();\n                            var width = box.width;\n                            textHeight = box.height;\n                            if(width > maxTextWidth) maxTextWidth = width;\n                        });\n                        rotateLabelsRule = 'rotate(' + rotateLabels + ' 0,' + (textHeight/2 + axis.tickPadding()) + ')';\n                        //Convert to radians before calculating sin. Add 30 to margin for healthy padding.\n                        var sin = Math.abs(Math.sin(rotateLabels*Math.PI/180));\n                        xLabelMargin = (sin ? sin*maxTextWidth : maxTextWidth)+30;\n                        //Rotate all xTicks\n                        xTicks\n                            .attr('transform', rotateLabelsRule)\n                            .style('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');\n                    } else {\n                        if (staggerLabels) {\n                            xTicks\n                                .attr('transform', function(d,i) {\n                                    return 'translate(0,' + (i % 2 == 0 ? '0' : '12') + ')'\n                                });\n                        } else {\n                            xTicks.attr('transform', \"translate(0,0)\");\n                        }\n                    }\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    w = 0;\n                    if (scale.range().length === 1) {\n                        w = isOrdinal ? scale.range()[0] * 2 + scale.rangeBand() : 0;\n                    } else if (scale.range().length === 2) {\n                        w = isOrdinal ? scale.range()[0] + scale.range()[1] + scale.rangeBand() : scale.range()[1];\n                    } else if ( scale.range().length > 2){\n                        w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]);\n                    };\n                    axisLabel\n                        .attr('text-anchor', 'middle')\n                        .attr('y', xLabelMargin)\n                        .attr('x', w/2);\n                    if (showMaxMin) {\n                        //if (showMaxMin && !isOrdinal) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            //.data(scale.domain())\n                            .data([scale.domain()[0], scale.domain()[scale.domain().length - 1]]);\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ')\n                        }).append('text');\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)'\n                            })\n                            .select('text')\n                            .attr('dy', '.71em')\n                            .attr('y', axis.tickPadding())\n                            .attr('transform', rotateLabelsRule)\n                            .style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max bottom')\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)'\n                            });\n                    }\n\n                    break;\n                case 'right':\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    axisLabel\n                        .style('text-anchor', rotateYLabel ? 'middle' : 'begin')\n                        .attr('transform', rotateYLabel ? 'rotate(90)' : '')\n                        .attr('y', rotateYLabel ? (-Math.max(margin.right, width) + 12 - (axisLabelDistance || 0)) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart\n                        .attr('x', rotateYLabel ? (d3.max(scale.range()) / 2) : axis.tickPadding());\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                       \taxisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ')\n                        }).append('text')\n                            .style('opacity', 0);\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale(d)) + ')'\n                            })\n                            .select('text')\n                            .attr('dy', '.32em')\n                            .attr('y', 0)\n                            .attr('x', axis.tickPadding())\n                            .style('text-anchor', 'start')\n                            .text(function(d, i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max right')\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')'\n                            })\n                            .select('text')\n                            .style('opacity', 1);\n                    }\n                    break;\n                case 'left':\n                    /*\n                     //For dynamically placing the label. Can be used with dynamically-sized chart axis margins\n                     var yTicks = g.selectAll('g').select(\"text\");\n                     yTicks.each(function(d,i){\n                     var labelPadding = this.getBoundingClientRect().width + axis.tickPadding() + 16;\n                     if(labelPadding > width) width = labelPadding;\n                     });\n                     */\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    axisLabel\n                        .style('text-anchor', rotateYLabel ? 'middle' : 'end')\n                        .attr('transform', rotateYLabel ? 'rotate(-90)' : '')\n                        .attr('y', rotateYLabel ? (-Math.max(margin.left, width) + 25 - (axisLabelDistance || 0)) : -10)\n                        .attr('x', rotateYLabel ? (-d3.max(scale.range()) / 2) : -axis.tickPadding());\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ')\n                        }).append('text')\n                            .style('opacity', 0);\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale0(d)) + ')'\n                            })\n                            .select('text')\n                            .attr('dy', '.32em')\n                            .attr('y', 0)\n                            .attr('x', -axis.tickPadding())\n                            .attr('text-anchor', 'end')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max right')\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')'\n                            })\n                            .select('text')\n                            .style('opacity', 1);\n                    }\n                    break;\n            }\n            axisLabel.text(function(d) { return d });\n\n            if (showMaxMin && (axis.orient() === 'left' || axis.orient() === 'right')) {\n                //check if max and min overlap other values, if so, hide the values that overlap\n                g.selectAll('g') // the g's wrapping each tick\n                    .each(function(d,i) {\n                        d3.select(this).select('text').attr('opacity', 1);\n                        if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it!\n                            if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL\n                                d3.select(this).attr('opacity', 0);\n\n                            d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!!\n                        }\n                    });\n\n                //if Max and Min = 0 only show min, Issue #281\n                if (scale.domain()[0] == scale.domain()[1] && scale.domain()[0] == 0) {\n                    wrap.selectAll('g.nv-axisMaxMin').style('opacity', function (d, i) {\n                        return !i ? 1 : 0\n                    });\n                }\n            }\n\n            if (showMaxMin && (axis.orient() === 'top' || axis.orient() === 'bottom')) {\n                var maxMinRange = [];\n                wrap.selectAll('g.nv-axisMaxMin')\n                    .each(function(d,i) {\n                        try {\n                            if (i) // i== 1, max position\n                                maxMinRange.push(scale(d) - this.getBoundingClientRect().width - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)\n                            else // i==0, min position\n                                maxMinRange.push(scale(d) + this.getBoundingClientRect().width + 4)\n                        }catch (err) {\n                            if (i) // i== 1, max position\n                                maxMinRange.push(scale(d) - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)\n                            else // i==0, min position\n                                maxMinRange.push(scale(d) + 4);\n                        }\n                    });\n                // the g's wrapping each tick\n                g.selectAll('g').each(function(d, i) {\n                    if (scale(d) < maxMinRange[0] || scale(d) > maxMinRange[1]) {\n                        if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL\n                            d3.select(this).remove();\n                        else\n                            d3.select(this).select('text').remove(); // Don't remove the ZERO line!!\n                    }\n                });\n            }\n\n            //Highlight zero tick line\n            g.selectAll('.tick')\n                .filter(function (d) {\n                    /*\n                    The filter needs to return only ticks at or near zero.\n                    Numbers like 0.00001 need to count as zero as well,\n                    and the arithmetic trick below solves that.\n                    */\n                    return !parseFloat(Math.round(d * 100000) / 1000000) && (d !== undefined)\n                })\n                .classed('zero', true);\n\n            //store old scales for use in transitions on update\n            scale0 = scale.copy();\n\n        });\n\n        renderWatch.renderEnd('axis immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.axis = axis;\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        axisLabelDistance: {get: function(){return axisLabelDistance;}, set: function(_){axisLabelDistance=_;}},\n        staggerLabels:     {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:      {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        rotateYLabel:      {get: function(){return rotateYLabel;}, set: function(_){rotateYLabel=_;}},\n        showMaxMin:        {get: function(){return showMaxMin;}, set: function(_){showMaxMin=_;}},\n        axisLabel:         {get: function(){return axisLabelText;}, set: function(_){axisLabelText=_;}},\n        height:            {get: function(){return height;}, set: function(_){height=_;}},\n        ticks:             {get: function(){return ticks;}, set: function(_){ticks=_;}},\n        width:             {get: function(){return width;}, set: function(_){width=_;}},\n        fontSize:          {get: function(){return fontSize;}, set: function(_){fontSize=_;}},\n        tickFormatMaxMin:  {get: function(){return tickFormatMaxMin;}, set: function(_){tickFormatMaxMin=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top !== undefined    ? _.top    : margin.top;\n            margin.right  = _.right !== undefined  ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left !== undefined   ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration=_;\n            renderWatch.reset(duration);\n        }},\n        scale: {get: function(){return scale;}, set: function(_){\n            scale = _;\n            axis.scale(scale);\n            isOrdinal = typeof scale.rangeBands === 'function';\n            nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    nv.utils.inheritOptionsD3(chart, axis, ['orient', 'tickValues', 'tickSubdivide', 'tickSize', 'tickPadding', 'tickFormat']);\n    nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']);\n\n    return chart;\n};\nnv.models.boxPlot = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0},\n        width = 960,\n        height = 500,\n        id = Math.floor(Math.random() * 10000), // Create semi-unique ID in case user doesn't select one\n        xScale = d3.scale.ordinal(),\n        yScale = d3.scale.linear(),\n        getX  = function(d) { return d.label }, // Default data model selectors.\n        getQ1 = function(d) { return d.values.Q1 },\n        getQ2 = function(d) { return d.values.Q2 },\n        getQ3 = function(d) { return d.values.Q3 },\n        getWl = function(d) { return d.values.whisker_low },\n        getWh = function(d) { return d.values.whisker_high },\n        getColor = function(d) { return d.color },\n        getOlItems  = function(d) { return d.values.outliers },\n        getOlValue = function(d, i, j) { return d },\n        getOlLabel = function(d, i, j) { return d },\n        getOlColor = function(d, i, j) { return undefined },\n        color = nv.utils.defaultColor(),\n        container = null,\n        xDomain, xRange,\n        yDomain, yRange,\n        dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd'),\n        duration = 250,\n        maxBoxWidth = null;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var xScale0, yScale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            xScale.domain(xDomain || data.map(function(d,i) { return getX(d,i); }))\n                .rangeBands(xRange || [0, availableWidth], 0.1);\n\n            // if we know yDomain, no need to calculate\n            var yData = []\n            if (!yDomain) {\n                // (y-range is based on quartiles, whiskers and outliers)\n                var values = [], yMin, yMax;\n                data.forEach(function (d, i) {\n                    var q1 = getQ1(d), q3 = getQ3(d), wl = getWl(d), wh = getWh(d);\n                    var olItems = getOlItems(d);\n                    if (olItems) {\n                        olItems.forEach(function (e, i) {\n                            values.push(getOlValue(e, i, undefined));\n                        });\n                    }\n                    if (wl) { values.push(wl) }\n                    if (q1) { values.push(q1) }\n                    if (q3) { values.push(q3) }\n                    if (wh) { values.push(wh) }\n                });\n                yMin = d3.min(values);\n                yMax = d3.max(values);\n                yData = [ yMin, yMax ] ;\n            }\n\n            yScale.domain(yDomain || yData);\n            yScale.range(yRange || [availableHeight, 0]);\n\n            //store old scales if they exist\n            xScale0 = xScale0 || xScale;\n            yScale0 = yScale0 || yScale.copy().range([yScale(0),yScale(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var boxplots = wrap.selectAll('.nv-boxplot').data(function(d) { return d });\n            var boxEnter = boxplots.enter().append('g').style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6);\n            boxplots\n                .attr('class', 'nv-boxplot')\n                .attr('transform', function(d,i,j) { return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)'; })\n                .classed('hover', function(d) { return d.hover });\n            boxplots\n                .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', 0.75)\n                .delay(function(d,i) { return i * duration / data.length })\n                .attr('transform', function(d,i) {\n                    return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)';\n                });\n            boxplots.exit().remove();\n\n            // ----- add the SVG elements for each boxPlot -----\n\n            // conditionally append whisker lines\n            boxEnter.each(function(d,i) {\n                var box = d3.select(this);\n                [getWl, getWh].forEach(function (f) {\n                    if (f(d) !== undefined && f(d) !== null) {\n                        var key = (f === getWl) ? 'low' : 'high';\n                        box.append('line')\n                          .style('stroke', getColor(d) || color(d,i))\n                          .attr('class', 'nv-boxplot-whisker nv-boxplot-' + key);\n                        box.append('line')\n                          .style('stroke', getColor(d) || color(d,i))\n                          .attr('class', 'nv-boxplot-tick nv-boxplot-' + key);\n                    }\n                });\n            });\n\n            var box_width = function() { return (maxBoxWidth === null ? xScale.rangeBand() * 0.9 : Math.min(75, xScale.rangeBand() * 0.9)); };\n            var box_left  = function() { return xScale.rangeBand() * 0.45 - box_width()/2; };\n            var box_right = function() { return xScale.rangeBand() * 0.45 + box_width()/2; };\n\n            // update whisker lines and ticks\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                var endpoint = (f === getWl) ? getQ1 : getQ3;\n                boxplots.select('line.nv-boxplot-whisker.nv-boxplot-' + key)\n                  .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                    .attr('x1', xScale.rangeBand() * 0.45 )\n                    .attr('y1', function(d,i) { return yScale(f(d)); })\n                    .attr('x2', xScale.rangeBand() * 0.45 )\n                    .attr('y2', function(d,i) { return yScale(endpoint(d)); });\n                boxplots.select('line.nv-boxplot-tick.nv-boxplot-' + key)\n                  .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                    .attr('x1', box_left )\n                    .attr('y1', function(d,i) { return yScale(f(d)); })\n                    .attr('x2', box_right )\n                    .attr('y2', function(d,i) { return yScale(f(d)); });\n            });\n\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                boxEnter.selectAll('.nv-boxplot-' + key)\n                  .on('mouseover', function(d,i,j) {\n                      d3.select(this).classed('hover', true);\n                      dispatch.elementMouseover({\n                          series: { key: f(d), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mouseout', function(d,i,j) {\n                      d3.select(this).classed('hover', false);\n                      dispatch.elementMouseout({\n                          series: { key: f(d), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mousemove', function(d,i) {\n                      dispatch.elementMousemove({e: d3.event});\n                  });\n            });\n\n            // boxes\n            boxEnter.append('rect')\n                .attr('class', 'nv-boxplot-box')\n                // tooltip events\n                .on('mouseover', function(d,i) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        key: getX(d),\n                        value: getX(d),\n                        series: [\n                            { key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        key: getX(d),\n                        value: getX(d),\n                        series: [\n                            { key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n            // box transitions\n            boxplots.select('rect.nv-boxplot-box')\n              .watchTransition(renderWatch, 'nv-boxplot: boxes')\n                .attr('y', function(d,i) { return yScale(getQ3(d)); })\n                .attr('width', box_width)\n                .attr('x', box_left )\n                .attr('height', function(d,i) { return Math.abs(yScale(getQ3(d)) - yScale(getQ1(d))) || 1 })\n                .style('fill', function(d,i) { return getColor(d) || color(d,i) })\n                .style('stroke', function(d,i) { return getColor(d) || color(d,i) });\n\n            // median line\n            boxEnter.append('line').attr('class', 'nv-boxplot-median');\n\n            boxplots.select('line.nv-boxplot-median')\n              .watchTransition(renderWatch, 'nv-boxplot: boxplots line')\n                .attr('x1', box_left)\n                .attr('y1', function(d,i) { return yScale(getQ2(d)); })\n                .attr('x2', box_right)\n                .attr('y2', function(d,i) { return yScale(getQ2(d)); });\n\n            // outliers\n            var outliers = boxplots.selectAll('.nv-boxplot-outlier').data(function(d) {\n                return getOlItems(d) || [];\n            });\n            outliers.enter().append('circle')\n                .style('fill', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })\n                .style('stroke', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })\n                .style('z-index', 9000)\n                .on('mouseover', function(d,i,j) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n            outliers.attr('class', 'nv-boxplot-outlier');\n            outliers\n              .watchTransition(renderWatch, 'nv-boxplot: nv-boxplot-outlier')\n                .attr('cx', xScale.rangeBand() * 0.45)\n                .attr('cy', function(d,i,j) { return yScale(getOlValue(d,i,j)); })\n                .attr('r', '3');\n            outliers.exit().remove();\n\n            //store old scales for use in transitions on update\n            xScale0 = xScale.copy();\n            yScale0 = yScale.copy();\n        });\n\n        renderWatch.renderEnd('nv-boxplot immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:       {get: function(){return width;}, set: function(_){width=_;}},\n        height:      {get: function(){return height;}, set: function(_){height=_;}},\n        maxBoxWidth: {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}},\n        x:           {get: function(){return getX;}, set: function(_){getX=_;}},\n        q1: {get: function(){return getQ1;}, set: function(_){getQ1=_;}},\n        q2: {get: function(){return getQ2;}, set: function(_){getQ2=_;}},\n        q3: {get: function(){return getQ3;}, set: function(_){getQ3=_;}},\n        wl: {get: function(){return getWl;}, set: function(_){getWl=_;}},\n        wh: {get: function(){return getWh;}, set: function(_){getWh=_;}},\n        itemColor:    {get: function(){return getColor;}, set: function(_){getColor=_;}},\n        outliers:     {get: function(){return getOlItems;}, set: function(_){getOlItems=_;}},\n        outlierValue: {get: function(){return getOlValue;}, set: function(_){getOlValue=_;}},\n        outlierLabel: {get: function(){return getOlLabel;}, set: function(_){getOlLabel=_;}},\n        outlierColor: {get: function(){return getOlColor;}, set: function(_){getOlColor=_;}},\n        xScale:  {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:  {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        // rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}},\n        y: {\n            get: function() {\n                console.warn('BoxPlot \\'y\\' chart option is deprecated. Please use model overrides instead.');\n                return {};\n            },\n            set: function(_) {\n                console.warn('BoxPlot \\'y\\' chart option is deprecated. Please use model overrides instead.');\n            }\n        },\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.boxPlotChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var boxplot = nv.models.boxPlot(),\n        xAxis = nv.models.axis(),\n        yAxis = nv.models.axis();\n\n    var margin = {top: 15, right: 10, bottom: 50, left: 60},\n        width = null,\n        height = null,\n        color = nv.utils.getColor(),\n        showXAxis = true,\n        showYAxis = true,\n        rightAlignYAxis = false,\n        staggerLabels = false,\n        tooltip = nv.models.tooltip(),\n        x, y,\n        noData = 'No Data Available.',\n        dispatch = d3.dispatch('beforeUpdate', 'renderEnd'),\n        duration = 250;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip.duration(0);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(boxplot);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this), that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = (width  || parseInt(container.style('width')) || 960) - margin.left - margin.right;\n            var availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // TODO still need to find a way to validate quartile data presence using boxPlot callbacks.\n            // Display No Data message if there's nothing to show. (quartiles required at minimum).\n            if (!data || !data.length) {\n                var noDataText = container.selectAll('.nv-noData').data([noData]);\n\n                noDataText.enter().append('text')\n                    .attr('class', 'nvd3 nv-noData')\n                    .attr('dy', '-.7em')\n                    .style('text-anchor', 'middle');\n\n                noDataText\n                    .attr('x', margin.left + availableWidth / 2)\n                    .attr('y', margin.top + availableHeight / 2)\n                    .text(function(d) { return d });\n\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = boxplot.xScale();\n            y = boxplot.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-boxPlotWithAxes').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-boxPlotWithAxes').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(' + availableWidth + ',0)');\n            }\n\n            // Main Chart Component(s)\n            boxplot.width(availableWidth).height(availableHeight);\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }))\n\n            barsWrap.transition().call(boxplot);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + boxplot.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + boxplot.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    .ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis').attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 === 0 ? '5' : '17') + ')' })\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    .ticks( Math.floor(availableHeight/36) ) // can't use nv.utils.calcTicksY with Object data\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select('.nv-zeroLine line')\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', y(0))\n                .attr('y2', y(0))\n            ;\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n        });\n\n        renderWatch.renderEnd('nv-boxplot chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    boxplot.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    boxplot.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.data(evt).hidden(true);\n    });\n\n    boxplot.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.boxplot = boxplot;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        tooltipContent:    {get: function(){return tooltip;}, set: function(_){tooltip=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            boxplot.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            boxplot.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, boxplot);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n\n// Chart design based on the recommendations of Stephen Few. Implementation\n// based on the work of Clint Ivy, Jamie Love, and Jason Davies.\n// http://projects.instantcognition.com/protovis/bulletchart/\n\nnv.models.bullet = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , orient = 'left' // TODO top & bottom\n        , reverse = false\n        , ranges = function(d) { return d.ranges }\n        , markers = function(d) { return d.markers ? d.markers : [] }\n        , markerLines = function(d) { return d.markerLines ? d.markerLines : [0] }\n        , measures = function(d) { return d.measures }\n        , rangeLabels = function(d) { return d.rangeLabels ? d.rangeLabels : [] }\n        , markerLabels = function(d) { return d.markerLabels ? d.markerLabels : []  }\n        , markerLineLabels = function(d) { return d.markerLineLabels ? d.markerLineLabels : []  }\n        , measureLabels = function(d) { return d.measureLabels ? d.measureLabels : []  }\n        , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)\n        , width = 380\n        , height = 30\n        , container = null\n        , tickFormat = null\n        , color = nv.utils.getColor(['#1f77b4'])\n        , dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove')\n        , defaultRangeLabels = [\"Maximum\", \"Mean\", \"Minimum\"]\n        , legacyRangeClassNames = [\"Max\", \"Avg\", \"Min\"]\n        , duration = 1000\n        ;\n\n    function sortLabels(labels, values){\n        var lz = labels.slice();\n        labels.sort(function(a, b){\n            var iA = lz.indexOf(a);\n            var iB = lz.indexOf(b);\n            return d3.descending(values[iA], values[iB]);\n        });\n    };\n\n    function chart(selection) {\n        selection.each(function(d, i) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var rangez = ranges.call(this, d, i).slice(),\n                markerz = markers.call(this, d, i).slice(),\n                markerLinez = markerLines.call(this, d, i).slice(),\n                measurez = measures.call(this, d, i).slice(),\n                rangeLabelz = rangeLabels.call(this, d, i).slice(),\n                markerLabelz = markerLabels.call(this, d, i).slice(),\n                markerLineLabelz = markerLineLabels.call(this, d, i).slice(),\n                measureLabelz = measureLabels.call(this, d, i).slice();\n\n            // Sort labels according to their sorted values\n            sortLabels(rangeLabelz, rangez);\n            sortLabels(markerLabelz, markerz);\n            sortLabels(markerLineLabelz, markerLinez);\n            sortLabels(measureLabelz, measurez);\n\n            // sort values descending\n            rangez.sort(d3.descending);\n            markerz.sort(d3.descending);\n            markerLinez.sort(d3.descending);\n            measurez.sort(d3.descending);\n\n            // Setup Scales\n            // Compute the new x-scale.\n            var x1 = d3.scale.linear()\n                .domain( d3.extent(d3.merge([forceX, rangez])) )\n                .range(reverse ? [availableWidth, 0] : [0, availableWidth]);\n\n            // Retrieve the old x-scale, if this is an update.\n            var x0 = this.__chart__ || d3.scale.linear()\n                .domain([0, Infinity])\n                .range(x1.range());\n\n            // Stash the new scale.\n            this.__chart__ = x1;\n\n            var rangeMin = d3.min(rangez), //rangez[2]\n                rangeMax = d3.max(rangez), //rangez[0]\n                rangeAvg = rangez[1];\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            for(var i=0,il=rangez.length; i<il; i++){\n                var rangeClassNames = 'nv-range nv-range'+i;\n                if(i <= 2){\n                    rangeClassNames = rangeClassNames + ' nv-range'+legacyRangeClassNames[i];\n                }\n                gEnter.append('rect').attr('class', rangeClassNames);\n            }\n\n            gEnter.append('rect').attr('class', 'nv-measure');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)\n                w1 = function(d) { return Math.abs(x1(d) - x1(0)) };\n            var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },\n                xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };\n\n            for(var i=0,il=rangez.length; i<il; i++){\n                var range = rangez[i];\n                g.select('rect.nv-range'+i)\n                    .datum(range)\n                    .attr('height', availableHeight)\n                    .transition()\n                    .duration(duration)\n                    .attr('width', w1(range))\n                    .attr('x', xp1(range))\n            }\n\n            g.select('rect.nv-measure')\n                .style('fill', color)\n                .attr('height', availableHeight / 3)\n                .attr('y', availableHeight / 3)\n                .on('mouseover', function() {\n                    dispatch.elementMouseover({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mousemove', function() {\n                    dispatch.elementMousemove({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mouseout', function() {\n                    dispatch.elementMouseout({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .transition()\n                .duration(duration)\n                .attr('width', measurez < 0 ?\n                    x1(0) - x1(measurez[0])\n                    : x1(measurez[0]) - x1(0))\n                .attr('x', xp1(measurez));\n\n            var h3 =  availableHeight / 6;\n\n            var markerData = markerz.map( function(marker, index) {\n                return {value: marker, label: markerLabelz[index]}\n            });\n            gEnter\n              .selectAll(\"path.nv-markerTriangle\")\n              .data(markerData)\n              .enter()\n              .append('path')\n              .attr('class', 'nv-markerTriangle')\n              .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z')\n              .on('mouseover', function(d) {\n                dispatch.elementMouseover({\n                  value: d.value,\n                  label: d.label || 'Previous',\n                  color: d3.select(this).style(\"fill\"),\n                  pos: [x1(d.value), availableHeight/2]\n                })\n\n              })\n              .on('mousemove', function(d) {\n                  dispatch.elementMousemove({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              })\n              .on('mouseout', function(d, i) {\n                  dispatch.elementMouseout({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              });\n\n            g.selectAll(\"path.nv-markerTriangle\")\n              .data(markerData)\n              .transition()\n              .duration(duration)\n              .attr('transform', function(d) { return 'translate(' + x1(d.value) + ',' + (availableHeight / 2) + ')' });\n\n            var markerLinesData = markerLinez.map( function(marker, index) {\n                return {value: marker, label: markerLineLabelz[index]}\n            });\n            gEnter\n              .selectAll(\"line.nv-markerLine\")\n              .data(markerLinesData)\n              .enter()\n              .append('line')\n              .attr('cursor', '')\n              .attr('class', 'nv-markerLine')\n              .attr('x1', function(d) { return x1(d.value) })\n              .attr('y1', '2')\n              .attr('x2', function(d) { return x1(d.value) })\n              .attr('y2', availableHeight - 2)\n              .on('mouseover', function(d) {\n                dispatch.elementMouseover({\n                  value: d.value,\n                  label: d.label || 'Previous',\n                  color: d3.select(this).style(\"fill\"),\n                  pos: [x1(d.value), availableHeight/2]\n                })\n\n              })\n              .on('mousemove', function(d) {\n                  dispatch.elementMousemove({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              })\n              .on('mouseout', function(d, i) {\n                  dispatch.elementMouseout({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              });\n\n            g.selectAll(\"line.nv-markerLine\")\n              .data(markerLinesData)\n              .transition()\n              .duration(duration)\n              .attr('x1', function(d) { return x1(d.value) })\n              .attr('x2', function(d) { return x1(d.value) });\n\n            wrap.selectAll('.nv-range')\n                .on('mouseover', function(d,i) {\n                    var label = rangeLabelz[i] || defaultRangeLabels[i];\n                    dispatch.elementMouseover({\n                        value: d,\n                        label: label,\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mousemove', function() {\n                    dispatch.elementMousemove({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Previous',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mouseout', function(d,i) {\n                    var label = rangeLabelz[i] || defaultRangeLabels[i];\n                    dispatch.elementMouseout({\n                        value: d,\n                        label: label,\n                        color: d3.select(this).style(\"fill\")\n                    })\n                });\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        ranges:      {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good)\n        markers:     {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal)\n        measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast)\n        forceX:      {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n        tickFormat:    {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}},\n        duration:    {get: function(){return duration;}, set: function(_){duration=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom\n            orient = _;\n            reverse = orient == 'right' || orient == 'bottom';\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\n\n\n// Chart design based on the recommendations of Stephen Few. Implementation\n// based on the work of Clint Ivy, Jamie Love, and Jason Davies.\n// http://projects.instantcognition.com/protovis/bulletchart/\nnv.models.bulletChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var bullet = nv.models.bullet();\n    var tooltip = nv.models.tooltip();\n\n    var orient = 'left' // TODO top & bottom\n        , reverse = false\n        , margin = {top: 5, right: 40, bottom: 20, left: 120}\n        , ranges = function(d) { return d.ranges }\n        , markers = function(d) { return d.markers ? d.markers : [] }\n        , measures = function(d) { return d.measures }\n        , width = null\n        , height = 55\n        , tickFormat = null\n        , ticks = null\n        , noData = null\n        , dispatch = d3.dispatch()\n        ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false);\n\n    function chart(selection) {\n        selection.each(function(d, i) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = height - margin.top - margin.bottom,\n                that = this;\n\n            chart.update = function() { chart(selection) };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!d || !ranges.call(this, d, i)) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var rangez = ranges.call(this, d, i).slice().sort(d3.descending),\n                markerz = markers.call(this, d, i).slice().sort(d3.descending),\n                measurez = measures.call(this, d, i).slice().sort(d3.descending);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-bulletChart').data([d]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bulletChart');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-bulletWrap');\n            gEnter.append('g').attr('class', 'nv-titles');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Compute the new x-scale.\n            var x1 = d3.scale.linear()\n                .domain([0, Math.max(rangez[0], (markerz[0] || 0), measurez[0])])  // TODO: need to allow forceX and forceY, and xDomain, yDomain\n                .range(reverse ? [availableWidth, 0] : [0, availableWidth]);\n\n            // Retrieve the old x-scale, if this is an update.\n            var x0 = this.__chart__ || d3.scale.linear()\n                .domain([0, Infinity])\n                .range(x1.range());\n\n            // Stash the new scale.\n            this.__chart__ = x1;\n\n            var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)\n                w1 = function(d) { return Math.abs(x1(d) - x1(0)) };\n\n            var title = gEnter.select('.nv-titles').append('g')\n                .attr('text-anchor', 'end')\n                .attr('transform', 'translate(-6,' + (height - margin.top - margin.bottom) / 2 + ')');\n            title.append('text')\n                .attr('class', 'nv-title')\n                .text(function(d) { return d.title; });\n\n            title.append('text')\n                .attr('class', 'nv-subtitle')\n                .attr('dy', '1em')\n                .text(function(d) { return d.subtitle; });\n\n            bullet\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var bulletWrap = g.select('.nv-bulletWrap');\n            d3.transition(bulletWrap).call(bullet);\n\n            // Compute the tick format.\n            var format = tickFormat || x1.tickFormat( availableWidth / 100 );\n\n            // Update the tick groups.\n            var tick = g.selectAll('g.nv-tick')\n                .data(x1.ticks( ticks ? ticks : (availableWidth / 50) ), function(d) {\n                    return this.textContent || format(d);\n                });\n\n            // Initialize the ticks with the old scale, x0.\n            var tickEnter = tick.enter().append('g')\n                .attr('class', 'nv-tick')\n                .attr('transform', function(d) { return 'translate(' + x0(d) + ',0)' })\n                .style('opacity', 1e-6);\n\n            tickEnter.append('line')\n                .attr('y1', availableHeight)\n                .attr('y2', availableHeight * 7 / 6);\n\n            tickEnter.append('text')\n                .attr('text-anchor', 'middle')\n                .attr('dy', '1em')\n                .attr('y', availableHeight * 7 / 6)\n                .text(format);\n\n            // Transition the updating ticks to the new scale, x1.\n            var tickUpdate = d3.transition(tick)\n                .transition()\n                .duration(bullet.duration())\n                .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' })\n                .style('opacity', 1);\n\n            tickUpdate.select('line')\n                .attr('y1', availableHeight)\n                .attr('y2', availableHeight * 7 / 6);\n\n            tickUpdate.select('text')\n                .attr('y', availableHeight * 7 / 6);\n\n            // Transition the exiting ticks to the new scale, x1.\n            d3.transition(tick.exit())\n                .transition()\n                .duration(bullet.duration())\n                .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' })\n                .style('opacity', 1e-6)\n                .remove();\n        });\n\n        d3.timer.flush();\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    bullet.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: evt.label,\n            value: evt.value,\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    bullet.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bullet.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.bullet = bullet;\n    chart.dispatch = dispatch;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        ranges:      {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good)\n        markers:     {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal)\n        measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast)\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n        tickFormat:    {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}},\n        ticks:    {get: function(){return ticks;}, set: function(_){ticks=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom\n            orient = _;\n            reverse = orient == 'right' || orient == 'bottom';\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, bullet);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\n\n\nnv.models.candlestickBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getOpen = function(d) { return d.open }\n        , getClose = function(d) { return d.close }\n        , getHigh = function(d) { return d.high }\n        , getLow = function(d) { return d.low }\n        , forceX = []\n        , forceY = []\n        , padData     = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , interactive = false\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // Width of the candlestick bars.\n            var barWidth = (availableWidth / data[0].values.length) * .45;\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [5 + barWidth / 2, availableWidth - barWidth / 2 - 5]);\n\n            y.domain(yDomain || [\n                    d3.min(data[0].values.map(getLow).concat(forceY)),\n                    d3.max(data[0].values.map(getHigh).concat(forceY))\n                ]\n            ).range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-candlestickBar').data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-candlestickBar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-ticks');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')\n                .data(function(d) { return d });\n            ticks.exit().remove();\n\n            var tickGroups = ticks.enter().append('g');\n\n            // The colors are currently controlled by CSS.\n            ticks\n                .attr('class', function(d, i, j) { return (getOpen(d, i) > getClose(d, i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i});\n\n            var lines = tickGroups.append('line')\n                .attr('class', 'nv-candlestick-lines')\n                .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; })\n                .attr('x1', 0)\n                .attr('y1', function(d, i) { return y(getHigh(d, i)); })\n                .attr('x2', 0)\n                .attr('y2', function(d, i) { return y(getLow(d, i)); });\n\n            var rects = tickGroups.append('rect')\n                .attr('class', 'nv-candlestick-rects nv-bars')\n                .attr('transform', function(d, i) {\n                    return 'translate(' + (x(getX(d, i)) - barWidth/2) + ','\n                    + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0))\n                    + ')';\n                })\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('width', barWidth)\n                .attr('height', function(d, i) {\n                    var open = getOpen(d, i);\n                    var close = getClose(d, i);\n                    return open > close ? y(close) - y(open) : y(open) - y(close);\n                });\n\n            ticks.select('.nv-candlestick-lines').transition()\n                .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; })\n                .attr('x1', 0)\n                .attr('y1', function(d, i) { return y(getHigh(d, i)); })\n                .attr('x2', 0)\n                .attr('y2', function(d, i) { return y(getLow(d, i)); });\n\n            ticks.select('.nv-candlestick-rects').transition()\n                .attr('transform', function(d, i) {\n                    return 'translate(' + (x(getX(d, i)) - barWidth/2) + ','\n                    + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0))\n                    + ')';\n                })\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('width', barWidth)\n                .attr('height', function(d, i) {\n                    var open = getOpen(d, i);\n                    var close = getClose(d, i);\n                    return open > close ? y(close) - y(open) : y(open) - y(close);\n                });\n        });\n\n        return chart;\n    }\n\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        chart.clearHighlights();\n        container.select(\".nv-candlestickBar .nv-tick-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container.select(\".nv-candlestickBar .nv-tick.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:   {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:   {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:   {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:   {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:   {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceX:   {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:   {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData:  {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:       {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        x:     {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:     {get: function(){return getY;}, set: function(_){getY=_;}},\n        open:  {get: function(){return getOpen();}, set: function(_){getOpen=_;}},\n        close: {get: function(){return getClose();}, set: function(_){getClose=_;}},\n        high:  {get: function(){return getHigh;}, set: function(_){getHigh=_;}},\n        low:   {get: function(){return getLow;}, set: function(_){getLow=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\nnv.models.cumulativeLineChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 30, bottom: 50, left: 60}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = true\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , showControls = true\n        , useInteractiveGuideline = false\n        , rescaleY = true\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , id = lines.id()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , average = function(d) { return d.average }\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , transitionDuration = 250\n        , duration = 250\n        , noErrorCheck = false  //if set to TRUE, will bypass an error check in the indexify function.\n        ;\n\n    state.index = 0;\n    state.rescaleY = rescaleY;\n\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient((rightAlignYAxis) ? 'right' : 'left');\n\n    tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var dx = d3.scale.linear()\n        , index = {i: 0, x: 0}\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        , currentYDomain\n        ;\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                index: index.i,\n                rescaleY: rescaleY\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.index !== undefined)\n                index.i = state.index;\n            if (state.rescaleY !== undefined)\n                rescaleY = state.rescaleY;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(lines);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            container.classed('nv-chart-' + id, true);\n            var that = this;\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition().duration(duration).call(chart)\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            var indexDrag = d3.behavior.drag()\n                .on('dragstart', dragStart)\n                .on('drag', dragMove)\n                .on('dragend', dragEnd);\n\n\n            function dragStart(d,i) {\n                d3.select(chart.container)\n                    .style('cursor', 'ew-resize');\n            }\n\n            function dragMove(d,i) {\n                index.x = d3.event.x;\n                index.i = Math.round(dx.invert(index.x));\n                updateZero();\n            }\n\n            function dragEnd(d,i) {\n                d3.select(chart.container)\n                    .style('cursor', 'auto');\n\n                // update state and send stateChange with new index\n                state.index = index.i;\n                dispatch.stateChange(state);\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = lines.xScale();\n            y = lines.yScale();\n\n\n            dx.domain([0, data[0].values.length - 1]) //Assumes all series have same length\n                .range([0, availableWidth])\n                .clamp(true);\n\n            var data = indexify(index.i, data);\n\n            // initialize the starting yDomain for the not-rescale case after indexify (to have calculated point.display)\n            if (typeof(currentYDomain) === \"undefined\") {\n                currentYDomain = getCurrentYDomain(data);\n            }\n\n            if (!rescaleY) {\n                lines.yDomain(currentYDomain);\n                lines.clipEdge(true);\n            } else {\n                lines.yDomain(null);\n            }\n\n            // Setup containers and skeleton of chart\n            var interactivePointerEvents = (useInteractiveGuideline) ? \"none\" : \"all\";\n            var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-cumulativeLine').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-interactive');\n            gEnter.append('g').attr('class', 'nv-x nv-axis').style(\"pointer-events\",\"none\");\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-background');\n            gEnter.append('g').attr('class', 'nv-linesWrap').style(\"pointer-events\",interactivePointerEvents);\n            gEnter.append('g').attr('class', 'nv-avgLinesWrap').style(\"pointer-events\",\"none\");\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                g.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: 'Re-scale y-axis', disabled: !rescaleY }\n                ];\n\n                controls\n                    .width(140)\n                    .color(['#444', '#444', '#444'])\n                    .rightAlign(false)\n                    .margin({top: 5, right: 0, bottom: 5, left: 20})\n                ;\n\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n                    .call(controls);\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Show error if index point value is 0 (division by zero avoided)\n            var tempDisabled = data.filter(function(d) { return d.tempDisabled });\n\n            wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates\n            if (tempDisabled.length) {\n                wrap.append('text').attr('class', 'tempDisabled')\n                    .attr('x', availableWidth / 2)\n                    .attr('y', '-.71em')\n                    .style('text-anchor', 'end')\n                    .text(tempDisabled.map(function(d) { return d.key }).join(', ') + ' values cannot be calculated for this time period.');\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left,top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            gEnter.select('.nv-background')\n                .append('rect');\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            lines\n                //.x(function(d) { return d.x })\n                .y(function(d) { return d.display.y })\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled && !data[i].tempDisabled; }));\n\n            var linesWrap = g.select('.nv-linesWrap')\n                .datum(data.filter(function(d) { return  !d.disabled && !d.tempDisabled }));\n\n            linesWrap.call(lines);\n\n            //Store a series index number in the data array.\n            data.forEach(function(d,i) {\n                d.seriesIndex = i;\n            });\n\n            var avgLineData = data.filter(function(d) {\n                return !d.disabled && !!average(d);\n            });\n\n            var avgLines = g.select(\".nv-avgLinesWrap\").selectAll(\"line\")\n                .data(avgLineData, function(d) { return d.key; });\n\n            var getAvgLineY = function(d) {\n                //If average lines go off the svg element, clamp them to the svg bounds.\n                var yVal = y(average(d));\n                if (yVal < 0) return 0;\n                if (yVal > availableHeight) return availableHeight;\n                return yVal;\n            };\n\n            avgLines.enter()\n                .append('line')\n                .style('stroke-width',2)\n                .style('stroke-dasharray','10,10')\n                .style('stroke',function (d,i) {\n                    return lines.color()(d,d.seriesIndex);\n                })\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', getAvgLineY)\n                .attr('y2', getAvgLineY);\n\n            avgLines\n                .style('stroke-opacity',function(d){\n                    //If average lines go offscreen, make them transparent\n                    var yVal = y(average(d));\n                    if (yVal < 0 || yVal > availableHeight) return 0;\n                    return 1;\n                })\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', getAvgLineY)\n                .attr('y2', getAvgLineY);\n\n            avgLines.exit().remove();\n\n            //Create index line\n            var indexLine = linesWrap.selectAll('.nv-indexLine')\n                .data([index]);\n            indexLine.enter().append('rect').attr('class', 'nv-indexLine')\n                .attr('width', 3)\n                .attr('x', -2)\n                .attr('fill', 'red')\n                .attr('fill-opacity', .5)\n                .style(\"pointer-events\",\"all\")\n                .call(indexDrag);\n\n            indexLine\n                .attr('transform', function(d) { return 'translate(' + dx(d.i) + ',0)' })\n                .attr('height', availableHeight);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/70, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            function updateZero() {\n                indexLine\n                    .data([index]);\n\n                //When dragging the index line, turn off line transitions.\n                // Then turn them back on when done dragging.\n                var oldDuration = chart.duration();\n                chart.duration(0);\n                chart.update();\n                chart.duration(oldDuration);\n            }\n\n            g.select('.nv-background rect')\n                .on('click', function() {\n                    index.x = d3.mouse(this)[0];\n                    index.i = Math.round(dx.invert(index.x));\n\n                    // update state and send stateChange with new index\n                    state.index = index.i;\n                    dispatch.stateChange(state);\n\n                    updateZero();\n                });\n\n            lines.dispatch.on('elementClick', function(e) {\n                index.i = e.pointIndex;\n                index.x = dx(index.i);\n\n                // update state and send stateChange with new index\n                state.index = index.i;\n                dispatch.stateChange(state);\n\n                updateZero();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                d.disabled = !d.disabled;\n                rescaleY = !d.disabled;\n                state.rescaleY = rescaleY;\n                if (!rescaleY) {\n                    currentYDomain = getCurrentYDomain(data); // rescale is turned off, so set the currentYDomain\n                }\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                lines.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !(series.disabled || series.tempDisabled);\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        lines.highlightPoint(i, pointIndex, true);\n                        var point = series.values[pointIndex];\n                        if (typeof point === 'undefined') return;\n                        if (typeof singlePoint === 'undefined') singlePoint = point;\n                        if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: chart.y()(point, pointIndex),\n                            color: color(series,series.seriesIndex)\n                        });\n                    });\n\n                //Highlight the tooltip entry based on which point the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);\n                    var threshold = 0.03 * domainExtent;\n                    var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold);\n                    if (indexToHighlight !== null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex), pointIndex);\n                interactiveLayer.tooltip\n                    .valueFormatter(function(d,i) {\n                        return yAxis.tickFormat()(d);\n                    })\n                    .data(\n                    {\n                        value: xValue,\n                        series: allData\n                    }\n                )();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                lines.clearHighlights();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.index !== 'undefined') {\n                    index.i = e.index;\n                    index.x = dx(index.i);\n\n                    state.index = e.index;\n\n                    indexLine\n                        .data([index]);\n                }\n\n                if (typeof e.rescaleY !== 'undefined') {\n                    rescaleY = e.rescaleY;\n                }\n\n                chart.update();\n            });\n\n        });\n\n        renderWatch.renderEnd('cumulativeLineChart immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        var point = {\n            x: chart.x()(evt.point),\n            y: chart.y()(evt.point),\n            color: evt.point.color\n        };\n        evt.point = point;\n        tooltip.data(evt).hidden(false);\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n\n    //============================================================\n    // Functions\n    //------------------------------------------------------------\n\n    var indexifyYGetter = null;\n    /* Normalize the data according to an index point. */\n    function indexify(idx, data) {\n        if (!indexifyYGetter) indexifyYGetter = lines.y();\n        return data.map(function(line, i) {\n            if (!line.values) {\n                return line;\n            }\n            var indexValue = line.values[idx];\n            if (indexValue == null) {\n                return line;\n            }\n            var v = indexifyYGetter(indexValue, idx);\n\n            // avoid divide by zero\n            if (Math.abs(v) < 0.00001 && !noErrorCheck) {\n                line.tempDisabled = true;\n                return line;\n            }\n\n            line.tempDisabled = false;\n\n            line.values = line.values.map(function(point, pointIndex) {\n                point.display = {'y': (indexifyYGetter(point, pointIndex) - v) / v };\n                return point;\n            });\n\n            return line;\n        })\n    }\n\n    function getCurrentYDomain(data) {\n        var seriesDomains = data\n            .filter(function(series) { return !(series.disabled || series.tempDisabled)})\n            .map(function(series,i) {\n                return d3.extent(series.values, function (d) { return d.display.y });\n            });\n\n        return [\n            d3.min(seriesDomains, function(d) { return d[0] }),\n            d3.max(seriesDomains, function(d) { return d[1] })\n        ];\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.lines = lines;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.state = state;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showControls:     {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        average: {get: function(){return average;}, set: function(_){average=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        showXAxis:    {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        noErrorCheck:    {get: function(){return noErrorCheck;}, set: function(_){noErrorCheck=_;}},\n\n        // options that require extra logic in the setter\n        rescaleY:     {get: function(){return rescaleY;}, set: function(_){\n            rescaleY = _;\n            chart.state.rescaleY = _; // also update state\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (_ === true) {\n                chart.interactive(false);\n                chart.useVoronoi(false);\n            }\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        duration:    {get: function(){return duration;}, set: function(_){\n            duration = _;\n            lines.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n//TODO: consider deprecating by adding necessary features to multiBar model\nnv.models.discreteBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , color = nv.utils.defaultColor()\n        , showValues = false\n        , valueFormat = d3.format(',.2f')\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , rectClass = 'discreteBar'\n        , duration = 250\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            //add series index to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                });\n            });\n\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0 }\n                    })\n                });\n\n            x   .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableWidth], .1);\n            y   .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y }).concat(forceY)));\n\n            // If showValues, pad the Y axis range to account for label height\n            if (showValues) y.range(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);\n            else y.range(yRange || [availableHeight, 0]);\n\n            //store old scales if they exist\n            x0 = x0 || x;\n            y0 = y0 || y.copy().range([y(0),y(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-discretebar').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discretebar');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            //TODO: by definition, the discrete bar should not have multiple groups, will modify/remove later\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit()\n                .watchTransition(renderWatch, 'discreteBar: exit groups')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6)\n                .remove();\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover });\n            groups\n                .watchTransition(renderWatch, 'discreteBar: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', .75);\n\n            var bars = groups.selectAll('g.nv-bar')\n                .data(function(d) { return d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('g')\n                .attr('transform', function(d,i,j) {\n                    return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'\n                })\n                .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            barsEnter.append('rect')\n                .attr('height', 0)\n                .attr('width', x.rangeBand() * .9 / data.length )\n\n            if (showValues) {\n                barsEnter.append('text')\n                    .attr('text-anchor', 'middle')\n                ;\n\n                bars.select('text')\n                    .text(function(d,i) { return valueFormat(getY(d,i)) })\n                    .watchTransition(renderWatch, 'discreteBar: bars text')\n                    .attr('x', x.rangeBand() * .9 / 2)\n                    .attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 })\n\n                ;\n            } else {\n                bars.selectAll('text').remove();\n            }\n\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive' })\n                .style('fill', function(d,i) { return d.color || color(d,i) })\n                .style('stroke', function(d,i) { return d.color || color(d,i) })\n                .select('rect')\n                .attr('class', rectClass)\n                .watchTransition(renderWatch, 'discreteBar: bars rect')\n                .attr('width', x.rangeBand() * .9 / data.length);\n            bars.watchTransition(renderWatch, 'discreteBar: bars')\n                //.delay(function(d,i) { return i * 1200 / data[0].values.length })\n                .attr('transform', function(d,i) {\n                    var left = x(getX(d,i)) + x.rangeBand() * .05,\n                        top = getY(d,i) < 0 ?\n                            y(0) :\n                                y(0) - y(getY(d,i)) < 1 ?\n                            y(0) - 1 : //make 1 px positive bars show up above y=0\n                            y(getY(d,i));\n\n                    return 'translate(' + left + ', ' + top + ')'\n                })\n                .select('rect')\n                .attr('height', function(d,i) {\n                    return  Math.max(Math.abs(y(getY(d,i)) - y(0)), 1)\n                });\n\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('discreteBar immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        valueFormat:    {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.discreteBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var discretebar = nv.models.discreteBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n\t, legend = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 15, right: 10, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.getColor()\n\t, showLegend = false\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , staggerLabels = false\n        , wrapLabels = false\n        , rotateLabels = 0\n        , x\n        , y\n        , noData = null\n        , dispatch = d3.dispatch('beforeUpdate','renderEnd')\n        , duration = 250\n        ;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .keyFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(discretebar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = discretebar.xScale();\n            y = discretebar.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-discreteBarWithAxes').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discreteBarWithAxes').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n\t    gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Main Chart Component(s)\n            discretebar\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.transition().call(discretebar);\n\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + discretebar.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + discretebar.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + (y.range()[0] + ((discretebar.showValues() && y.domain()[0] < 0) ? 16 : 0)) + ')');\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '5' : '17') + ')' })\n                }\n\n                if (rotateLabels) {\n                    xTicks\n                        .selectAll('.tick text')\n                        .attr('transform', 'rotate(' + rotateLabels + ' 0,0)')\n                        .style('text-anchor', rotateLabels > 0 ? 'start' : 'end');\n                }\n\n                if (wrapLabels) {\n                    g.selectAll('.tick text')\n                        .call(nv.utils.wrapTicks, chart.xAxis.rangeBand())\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select(\".nv-zeroLine line\")\n                .attr(\"x1\",0)\n                .attr(\"x2\",(rightAlignYAxis) ? -availableWidth : availableWidth)\n                .attr(\"y1\", y(0))\n                .attr(\"y2\", y(0))\n            ;\n        });\n\n        renderWatch.renderEnd('discreteBar chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    discretebar.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    discretebar.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    discretebar.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.discretebar = discretebar;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n\tshowLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:  {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        wrapLabels:  {get: function(){return wrapLabels;}, set: function(_){wrapLabels=!!_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            discretebar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            discretebar.color(color);\n\t    legend.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, discretebar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n\nnv.models.distribution = function() {\n    \"use strict\";\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 400 //technically width or height depending on x or y....\n        , size = 8\n        , axis = 'x' // 'x' or 'y'... horizontal or vertical\n        , getData = function(d) { return d[axis] }  // defaults d.x or d.y\n        , color = nv.utils.defaultColor()\n        , scale = d3.scale.linear()\n        , domain\n        , duration = 250\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n\n    //============================================================\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var scale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    //============================================================\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableLength = width - (axis === 'x' ? margin.left + margin.right : margin.top + margin.bottom),\n                naxis = axis == 'x' ? 'y' : 'x',\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            //------------------------------------------------------------\n            // Setup Scales\n\n            scale0 = scale0 || scale;\n\n            //------------------------------------------------------------\n\n\n            //------------------------------------------------------------\n            // Setup containers and skeleton of chart\n\n            var wrap = container.selectAll('g.nv-distribution').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-distribution');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')\n\n            //------------------------------------------------------------\n\n\n            var distWrap = g.selectAll('g.nv-dist')\n                .data(function(d) { return d }, function(d) { return d.key });\n\n            distWrap.enter().append('g');\n            distWrap\n                .attr('class', function(d,i) { return 'nv-dist nv-series-' + i })\n                .style('stroke', function(d,i) { return color(d, i) });\n\n            var dist = distWrap.selectAll('line.nv-dist' + axis)\n                .data(function(d) { return d.values })\n            dist.enter().append('line')\n                .attr(axis + '1', function(d,i) { return scale0(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale0(getData(d,i)) })\n            renderWatch.transition(distWrap.exit().selectAll('line.nv-dist' + axis), 'dist exit')\n                // .transition()\n                .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })\n                .style('stroke-opacity', 0)\n                .remove();\n            dist\n                .attr('class', function(d,i) { return 'nv-dist' + axis + ' nv-dist' + axis + '-' + i })\n                .attr(naxis + '1', 0)\n                .attr(naxis + '2', size);\n            renderWatch.transition(dist, 'dist')\n                // .transition()\n                .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })\n\n\n            scale0 = scale.copy();\n\n        });\n        renderWatch.renderEnd('distribution immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart.dispatch = dispatch;\n\n    chart.margin = function(_) {\n        if (!arguments.length) return margin;\n        margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n        margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;\n        margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;\n        margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        return chart;\n    };\n\n    chart.width = function(_) {\n        if (!arguments.length) return width;\n        width = _;\n        return chart;\n    };\n\n    chart.axis = function(_) {\n        if (!arguments.length) return axis;\n        axis = _;\n        return chart;\n    };\n\n    chart.size = function(_) {\n        if (!arguments.length) return size;\n        size = _;\n        return chart;\n    };\n\n    chart.getData = function(_) {\n        if (!arguments.length) return getData;\n        getData = d3.functor(_);\n        return chart;\n    };\n\n    chart.scale = function(_) {\n        if (!arguments.length) return scale;\n        scale = _;\n        return chart;\n    };\n\n    chart.color = function(_) {\n        if (!arguments.length) return color;\n        color = nv.utils.getColor(_);\n        return chart;\n    };\n\n    chart.duration = function(_) {\n        if (!arguments.length) return duration;\n        duration = _;\n        renderWatch.reset(duration);\n        return chart;\n    };\n    //============================================================\n\n\n    return chart;\n}\nnv.models.distroPlot = function() {\n    \"use strict\";\n\n    // IMPROVEMENTS:\n    // - cleanup tooltip to look like candlestick example (don't need color square for everything)\n    // - extend y scale range to min/max data better visually\n    // - tips of violins need to be cut off if very long\n    // - transition from box to violin not great since box only has a few points, and violin has many - need to generate box with as many points as violin\n    // - when providing colorGroup, should color boxes by either parent or child group category (e.g. isolator)\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0},\n        width = 960,\n        height = 500,\n        id = Math.floor(Math.random() * 10000), // Create semi-unique ID in case user doesn't select one\n        xScale = d3.scale.ordinal(),\n        yScale = d3.scale.linear(),\n        getX  = function(d) { return d.label }, // Default data model selectors.\n        getY  = function(d) { return d.value },\n        getColor = function(d) { return d.color },\n        getQ1 = function(d) { return d.values.q1 },\n        getQ2 = function(d) { return d.values.q2 },\n        getQ3 = function(d) { return d.values.q3 },\n        getNl = function(d) { return (centralTendency == 'mean' ? getMean(d) : getQ2(d)) - d.values.notch },\n        getNu = function(d) { return (centralTendency == 'mean' ? getMean(d) : getQ2(d)) + d.values.notch },\n        getMean = function(d) { return d.values.mean },\n        getWl = function(d) { return d.values.wl[whiskerDef] },\n        getWh = function(d) { return d.values.wu[whiskerDef] },\n        getMin = function(d) { return d.values.min },\n        getMax = function(d) { return d.values.max },\n        getDev = function(d) { return d.values.dev },\n        getValsObj = function(d) { return d.values.observations; },\n        getValsArr = function(d) { return d.values.observations.map(function(e) { return e.y }); },\n        plotType, // type of background: 'box', 'violin', 'none'/false - default: 'box' - 'none' will activate random scatter automatically\n        observationType = false, // type of observations to show: 'random', 'swarm', 'line', 'centered' - default: false (don't show any observations, even if an outlier)\n        whiskerDef = 'iqr', // type of whisker to render: 'iqr', 'minmax', 'stddev' - default: iqr\n        hideWhiskers = false,\n        notchBox = false, // bool whether to notch box\n        colorGroup = false, // if specified, each x-category will be split into groups, each colored\n        centralTendency = false,\n        showOnlyOutliers = true, // show only outliers in box plot\n        jitter = 0.7, // faction of that jitter should take up in 'random' observationType, must be in range [0,1]; see jitterX(), default 0.7\n        squash = true, // whether to remove the x-axis positions for empty data groups, default is true\n        bandwidth = 'scott', // bandwidth for kde calculation, can be float or str, if str, must be one of scott or silverman\n        clampViolin = true, // whether to clamp the \"tails\" of the violin; prevents long 0-density area\n        resolution = 50,\n        pointSize = 3,\n        color = nv.utils.defaultColor(),\n        container = null,\n        xDomain, xRange,\n        yDomain, yRange,\n        dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd'),\n        duration = 250,\n        maxBoxWidth = null;\n\n    //============================================================\n    // Helper Functions\n    //------------------------------------------------------------\n\n\n    /* Returns the smaller of std(X, ddof=1) or normalized IQR(X) over axis 0.\n     *\n     * @param (list) x - input x formatted as a single list of values\n     *\n     * @return float\n     *\n     * Source: https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/bandwidths.py#L9\n     */\n    function select_sigma(x) {\n        var sorted = x.sort(d3.ascending); // sort our dat\n        var normalize = 1.349;\n        var IQR = (d3.quantile(sorted, 0.75) - d3.quantile(sorted, 0.25))/normalize; // normalized IQR\n        return d3.min([d3.deviation(sorted), IQR]);\n    }\n\n    /*\n    Scott's Rule of Thumb\n\n    Parameters\n    ----------\n    x : array-like\n        Array for which to get the bandwidth\n    type : string\n           The type of estimate to use, must be one of scott or silverman\n\n    Returns\n    -------\n    bw : float\n        The estimate of the bandwidth\n\n    Notes\n    -----\n    Returns 1.059 * A * n ** (-1/5.) where ::\n       A = min(std(x, ddof=1), IQR/1.349)\n       IQR = np.subtract.reduce(np.percentile(x, [75,25]))\n\n    References\n    ----------\n    Scott, D.W. (1992) Multivariate Density Estimation: Theory, Practice, and\n        Visualization.\n     */\n    function calcBandwidth(x, type) {\n\n        if (typeof type === 'undefined') type = 'scott';\n\n        // TODO: consider using https://github.com/jasondavies/science.js\n        var A = select_sigma(x);\n        var n = x.length;\n        return type==='scott' ? Math.pow(1.059 * A * n, -0.2) : Math.pow(.9 * A * n, -0.2);\n    }\n\n\n\n    /*\n     * Prep data for use with distroPlot by grouping data\n     * by .x() option set by user and then calculating\n     * count, sum, mean, q1, q2 (median), q3, lower whisker (wl)\n     * upper whisker (wu), iqr, min, max, and standard dev.\n     *\n     * NOTE: preparing this data can be resource intensive, and\n     *       is therefore only run once on plot load. It can\n     *       manually be run by calling recalcData(). This should\n     *       be re-run any time the axis accessors are changed or\n     *       when bandwidth/resolution are updated.\n     *\n     * NOTE: this will also setup the individual vertical scales\n     *       for the violins.\n     *\n     * @param (list) dat - input data formatted as list of objects,\n     *   with an object key that must exist when accessed by getX()\n     *\n     * @return prepared data in the form for box plotType:\n     * [{\n     *    key : YY,\n     *    values: {\n     *      count: XX,\n     *      sum: XX,\n     *      mean: XX,\n     *      q1: XX,\n     *      q2: XX,\n     *      q3: XX,\n     *      wl: XX,\n     *      wu: XX,\n     *      iqr: XX,\n     *      min: XX,\n     *      max: XX,\n     *      dev: XX,\n     *      observations: [{y:XX,..},..],\n     *      key: XX,\n     *      kdeDat: XX,\n     *      notch: XX,\n     *    }\n     *  },\n     *  ...\n     *  ]\n     * for violin plotType:\n     * [{\n     *    key : YY,\n     *    values: {\n     *      original: [{y:XX,..},..]\n     *    }\n     *  },\n     *  ...\n     *  ]\n     * where YY are those keys in dat that define the\n     * x-axis and which are defined by .x()\n     */\n    function prepData(dat) {\n\n        // helper function to calcuate the various boxplot stats\n        function calcStats(g, xGroup) {\n\n            // sort data by Y so we can calc quartiles\n            var v = g.map(function(d) {\n                if (colorGroup) allColorGroups.add(colorGroup(d)); // list of all colorGroups; used to set x-axis\n                return getY(d);\n            }).sort(d3.ascending);\n\n            var q1 = d3.quantile(v, 0.25);\n            var q3 = d3.quantile(v, 0.75);\n            var iqr = q3 - q1;\n            var upper = q3 + 1.5 * iqr;\n            var lower = q1 - 1.5 * iqr;\n\n            /* whisker definitions:\n             *  - iqr: also known as Tukey boxplot, the lowest datum still within 1.5 IQR of the lower quartile, and the highest datum still within 1.5 IQR of the upper quartile\n             *  - minmax: the minimum and maximum of all of the data\n             *  - sttdev: one standard deviation above and below the mean of the data\n             * Note that the central tendency type (median or mean) does not impact the whisker location\n             */\n            var wl = {iqr: d3.max([d3.min(v),  d3.min(v.filter(function(d) {return d > lower}))]), minmax: d3.min(v), stddev: d3.mean(v) - d3.deviation(v)};\n            var wu = {iqr: d3.min([d3.max(v), d3.max(v.filter(function(d) {return d < upper}))]), minmax: d3.max(v), stddev: d3.mean(v) + d3.deviation(v)};\n            var median = d3.median(v);\n            var mean = d3.mean(v);\n            var observations = [];\n\n\n            // d3-beeswarm library must be externally loaded if being used\n            // https://github.com/Kcnarf/d3-beeswarm\n            if (typeof d3.beeswarm !== 'undefined') {\n                observations = d3.beeswarm()\n                    .data(g.map(function(e) { return getY(e); }))\n                    .radius(pointSize+1)\n                    .orientation('vertical')\n                    .side('symmetric')\n                    .distributeOn(function(e) { return yScale(e); })\n                    .arrange()\n\n                // add group info for tooltip\n                observations.map(function(e,i) {\n                    e.key = xGroup;\n                    e.object_constancy = g[i].object_constancy;\n                    e.isOutlier = (e.datum < wl.iqr || e.datum > wu.iqr) // add isOulier meta for proper class assignment\n                    e.isOutlierStdDev = (e.datum < wl.stddev || e.datum > wu.stddev) // add isOulier meta for proper class assignment\n                    e.randX = Math.random() * jitter * (Math.floor(Math.random()*2) == 1 ? 1 : -1) // calculate random x-position only once for each point\n                })\n            } else {\n                v.forEach(function(e,i) {\n                    observations.push({\n                        object_constancy: e.object_constancy,\n                        datum: e,\n                        key: xGroup,\n                        isOutlier: (e < wl.iqr || e > wu.iqr), // add isOulier meta for proper class assignment\n                        isOutlierStdDev: (e < wl.stddev || e > wu.stddev), // add isOulier meta for proper class assignment\n                        randX: Math.random() * jitter * (Math.floor(Math.random()*2) == 1 ? 1 : -1)\n                    })\n                })\n            }\n\n\n            // calculate bandwidth if no number is provided\n            if(isNaN(parseFloat(bandwidth))) { // if not is float\n                var bandwidthCalc;\n                if (['scott','silverman'].indexOf(bandwidth) != -1) {\n                    bandwidthCalc = calcBandwidth(v, bandwidth);\n                } else {\n                    bandwidthCalc = calcBandwidth(v); // calculate with default 'scott'\n                }\n            }\n            var kde = kernelDensityEstimator(eKernel(bandwidthCalc), yScale.ticks(resolution));\n            var kdeDat = clampViolin ? clampViolinKDE(kde(v), d3.extent(v)) : kde(v);\n\n\n            // make a new vertical scale for each group\n            var tmpScale = d3.scale.linear()\n                .domain([0, d3.max(kdeDat, function (e) { return e.y;})])\n                .clamp(true);\n            yVScale.push(tmpScale);\n\n            var reformat = {\n                count: v.length,\n                num_outlier: observations.filter(function (e) { return e.isOutlier; }).length,\n                sum: d3.sum(v),\n                mean: mean,\n                q1: q1,\n                q2: median,\n                q3: q3,\n                wl: wl,\n                wu: wu,\n                iqr: iqr,\n                min: d3.min(v),\n                max: d3.max(v),\n                dev: d3.deviation(v),\n                observations: observations,\n                key: xGroup,\n                kde: kdeDat,\n                notch: 1.57 * iqr / Math.sqrt(v.length), // notch distance from mean/median\n            };\n\n            if (colorGroup) {reformatDatFlat.push({key: xGroup, values: reformat});}\n\n            return reformat;\n        }\n\n        // assign a unique identifier for each point for object constancy\n        // this makes updating data possible\n        dat.forEach(function(d,i) { d.object_constancy = i + '_' + getY(d) + '_' + getX(d); })\n\n\n        // TODO not DRY\n        // couldn't find a conditional way of doing the key() grouping\n        var formatted;\n        if (!colorGroup) {\n            formatted = d3.nest()\n                .key(function(d) { return getX(d); })\n                .rollup(function(v,i) {\n                    return calcStats(v);\n                })\n                .entries(dat);\n        } else {\n            allColorGroups = d3.set() // reset\n            var tmp = d3.nest()\n                .key(function(d) { return getX(d); })\n                .key(function(d) { return colorGroup(d); })\n                .rollup(function(v) {\n                    return calcStats(v, getX(v[0]));\n                })\n                .entries(dat);\n\n            // generate a final list of all x & colorGroup combinations\n            // this is used to properly set the x-axis domain\n            allColorGroups = allColorGroups.values(); // convert from d3.set to list\n            var xGroups = tmp.map(function(d) { return d.key; });\n            var allGroups = [];\n            for (var i = 0; i < xGroups.length; i++) {\n                for (var j = 0; j < allColorGroups.length; j++) {\n                    allGroups.push(xGroups[i] + '_' + allColorGroups[j]);\n                }\n            }\n            allColorGroups = allGroups;\n\n            // flatten the inner most level so that\n            // the plot retains the same DOM structure\n            // to allow for smooth updating between\n            // all groups.\n            formatted = [];\n            tmp.forEach(function(d) {\n                d.values.forEach(function(e) { e.key = d.key +'_'+e.key }) // generate a combo key so that each boxplot has a distinct x-position\n                formatted.push.apply(formatted, d.values)\n            });\n\n        }\n        return formatted;\n    }\n\n    // https://bl.ocks.org/mbostock/4341954\n    function kernelDensityEstimator(kernel, X) {\n        return function (sample) {\n            return X.map(function(x) {\n                var y = d3.mean(sample, function (v) {return kernel(x - v);});\n                return {x:x, y:y};\n            });\n        };\n    }\n\n    /*\n     * Limit whether the density extends past the extreme datapoints\n     * of the violin.\n     *\n     * @param (list) kde - x & y kde cooridinates\n     * @param (list) extent - min/max y-values used for clamping violing\n     */\n    function clampViolinKDE(kde, extent) {\n\n        // this handles the case when all the x-values are equal\n        // which means no kde could be properly calculated\n        // just return the kde data so we can continue plotting successfully\n        if (extent[0] === extent[1]) return kde;\n\n        var clamped = kde.reduce(function(res, d) {\n            if (d.x >= extent[0] && d.x <= extent[1]) res.push(d);\n            return res;\n        },[]);\n\n        // add the extreme data points back in\n        if (extent[0] < clamped[0].x) clamped.unshift({x:extent[0], y:clamped[0].y})\n        if (extent[1] > clamped[clamped.length-1].x) clamped.push({x:extent[1], y:clamped[clamped.length-1].y})\n\n        return clamped;\n\n    }\n\n    // https://bl.ocks.org/mbostock/4341954\n    function eKernel(scale) {\n        return function (u) {\n            return Math.abs(u /= scale) <= 1 ? .75 * (1 - u * u) / scale : 0;\n        };\n    }\n\n    /**\n     * Makes the svg polygon string for a boxplot in either a notched\n     * or square version\n     *\n     * NOTE: this actually only draws the left half of the box, since\n     * the shape is symmetric (and since this is how violins are drawn)\n     * we can simply generate half the box and mirror it.\n     *\n     * @param boxLeft {float} - left position of box\n     * @param notchLeft {float} - left position of notch\n     * @param dat {obj} - box plot data that was run through prepDat, must contain\n     *      data for Q1, median, Q2, notch upper and notch lower\n     * @returns {string} A string in the proper format for a svg polygon\n     */\n    function makeNotchBox(boxLeft, notchLeft, boxCenter, dat) {\n\n        var boxPoints;\n        var y = centralTendency == 'mean' ? getMean(dat) : getQ2(dat); // if centralTendency is not specified, we still want to notch boxes on 'median'\n        if (notchBox) {\n            boxPoints = [\n                    {x:boxCenter, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getNl(dat))},\n                    {x:notchLeft, y:yScale(y)},\n                    {x:boxLeft, y:yScale(getNu(dat))},\n                    {x:boxLeft, y:yScale(getQ3(dat))},\n                    {x:boxCenter, y:yScale(getQ3(dat))},\n                ];\n        } else {\n            boxPoints = [\n                    {x:boxCenter, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(y)}, // repeated point so that transition between notched/regular more smooth\n                    {x:boxLeft, y:yScale(y)},\n                    {x:boxLeft, y:yScale(y)}, // repeated point so that transition between notched/regular more smooth\n                    {x:boxLeft, y:yScale(getQ3(dat))},\n                    {x:boxCenter, y:yScale(getQ3(dat))},\n                ];\n        }\n\n        return boxPoints;\n    }\n\n    /**\n     * Given an x-axis group, return the available color groups within it\n     * provided that colorGroups is set, if not, x-axis group is returned\n     */\n    function getAvailableColorGroups(x) {\n        if (!colorGroup) return x;\n        var tmp = reformatDat.find(function(d) { return d.key == x });\n        return tmp.values.map(function(d) { return d.key }).sort(d3.ascending);\n    }\n\n    // return true if point is an outlier\n    function isOutlier(d) {\n        return (whiskerDef == 'iqr' && d.isOutlier) || (whiskerDef == 'stddev' && d.isOutlierStdDev)\n    }\n\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var allColorGroups = d3.set()\n    var yVScale = [], reformatDat, reformatDatFlat = [];\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var availableWidth, availableHeight;\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            availableWidth = width - margin.left - margin.right,\n            availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup y-scale so that beeswarm layout can use it in prepData()\n            yScale.domain(yDomain || d3.extent(data.map(function(d) { return getY(d)}))).nice()\n                .range(yRange || [availableHeight, 0]);\n\n\n            if (typeof reformatDat === 'undefined') reformatDat = prepData(data); // this prevents us from recalculating data all the time\n\n            // Setup x-scale\n            xScale.rangeBands(xRange || [0, availableWidth], 0.1)\n                  .domain(xDomain || (colorGroup && !squash) ? allColorGroups : reformatDat.map(function(d) { return d.key }))\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([reformatDat]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap');\n            wrap.watchTransition(renderWatch, 'nv-wrap: wrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var areaEnter,\n                distroplots = wrap.selectAll('.nv-distroplot-x-group')\n                    .data(function(d) { return d; });\n\n            // rebind new data\n            // we don't rebuild individual x-axis groups so that we can update transition them\n            // however the data associated with each x-axis group needs to be updated\n            // so we manually update it here\n            distroplots.each(function(d,i) {\n                d3.select(this).selectAll('line.nv-distroplot-middle').datum(d);\n            })\n\n            areaEnter = distroplots.enter()\n                .append('g')\n                .attr('class', 'nv-distroplot-x-group')\n                .style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6)\n                .style('fill', function(d,i) { return getColor(d) || color(d,i) })\n                .style('stroke', function(d,i) { return getColor(d) || color(d,i) })\n\n            distroplots.exit().remove();\n\n            var rangeBand = function() { return xScale.rangeBand() };\n            var areaWidth = function() { return d3.min([maxBoxWidth,rangeBand() * 0.9]); };\n            var areaCenter = function() { return areaWidth()/2; };\n            var areaLeft  = function() { return areaCenter() - areaWidth()/2; };\n            var areaRight = function() { return areaCenter() + areaWidth()/2; };\n            var tickLeft  = function() { return areaCenter() - areaWidth()/5; };\n            var tickRight = function() { return areaCenter() + areaWidth()/5; };\n\n            areaEnter.attr('transform', function(d) {\n                    return 'translate(' + (xScale(d.key) + (rangeBand() - areaWidth()) * 0.5) + ', 0)';\n                });\n\n            distroplots\n                .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', 0.5)\n                .attr('transform', function(d) {\n                    return 'translate(' + (xScale(d.key) + (rangeBand() - areaWidth()) * 0.5) + ', 0)';\n                });\n\n            // set range for violin scale\n            yVScale.map(function(d) { d.range([areaWidth()/2, 0]) });\n\n            // ----- add the SVG elements for each plot type -----\n\n            // scatter plot type\n            if (!plotType) {\n                showOnlyOutliers = false; // force all observations to be seen\n                if (!observationType) observationType = 'random'\n            }\n\n            // conditionally append whisker lines\n            areaEnter.each(function(d,i) {\n                var box = d3.select(this);\n                [getWl, getWh].forEach(function (f) {\n                    var key = (f === getWl) ? 'low' : 'high';\n                    box.append('line')\n                      .style('opacity', function() { return !hideWhiskers ? '0' : '1' })\n                      .attr('class', 'nv-distroplot-whisker nv-distroplot-' + key)\n                    box.append('line')\n                      .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n                      .attr('class', 'nv-distroplot-tick nv-distroplot-' + key)\n                });\n            });\n\n\n            // update whisker lines and ticks\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                var endpoint = (f === getWl) ? getQ1 : getQ3;\n                distroplots.select('line.nv-distroplot-whisker.nv-distroplot-' + key)\n                  .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                    .attr('x1', areaCenter())\n                    .attr('y1', function(d) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .attr('x2', areaCenter())\n                    .attr('y2', function(d) { return plotType=='box' ? yScale(endpoint(d)) : yScale(getQ2(d)); })\n                    .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n                distroplots.select('line.nv-distroplot-tick.nv-distroplot-' + key)\n                  .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                    .attr('x1', function(d) { return plotType!='violin' ? tickLeft() : areaCenter()} )\n                    .attr('y1', function(d,i) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .attr('x2', function(d) { return plotType!='violin' ? tickRight() : areaCenter()} )\n                    .attr('y2', function(d,i) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n            });\n\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                areaEnter.selectAll('.nv-distroplot-' + key)\n                  .on('mouseover', function(d,i,j) {\n                      d3.select(this.parentNode).selectAll('line.nv-distroplot-'+key).classed('hover',true);\n                      dispatch.elementMouseover({\n                          value: key == 'low' ? 'Lower whisker' : 'Upper whisker',\n                          series: { key: f(d).toFixed(2), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mouseout', function(d,i,j) {\n                      d3.select(this.parentNode).selectAll('line.nv-distroplot-'+key).classed('hover',false);\n                      dispatch.elementMouseout({\n                          value: key == 'low' ? 'Lower whisker' : 'Upper whisker',\n                          series: { key: f(d).toFixed(2), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mousemove', function(d,i) {\n                      dispatch.elementMousemove({e: d3.event});\n                  });\n            });\n\n            // setup boxes as 4 parts: left-area, left-line, right-area, right-line,\n            // this way we can transition to a violin\n            areaEnter.each(function(d,i) {\n                var violin = d3.select(this);\n\n                ['left','right'].forEach(function(side) {\n                    ['line','area'].forEach(function(d) {\n                        violin.append('path')\n                            .attr('class', 'nv-distribution-' + d + ' nv-distribution-' + side)\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')); // rotate violin\n                    })\n\n                })\n\n                areaEnter.selectAll('.nv-distribution-line')\n                    .style('fill','none')\n                areaEnter.selectAll('.nv-distribution-area')\n                    .style('stroke','none')\n                    .style('opacity',0.7)\n\n            });\n\n            // transitions\n            distroplots.each(function(d,i) {\n                var violin = d3.select(this);\n                var objData = plotType == 'box' ? makeNotchBox(areaLeft(), tickLeft(), areaCenter(), d) : d.values.kde;\n\n                violin.selectAll('path')\n                    .datum(objData)\n\n                var tmpScale = yVScale[i];\n\n                var interp = plotType=='box' ? 'linear' : 'basis';\n\n                if (plotType == 'box' || plotType == 'violin') {\n                    ['left','right'].forEach(function(side) {\n\n                        // line\n                        distroplots.selectAll('.nv-distribution-line.nv-distribution-' + side)\n                          //.watchTransition(renderWatch, 'nv-distribution-line: distroplots') // disable transition for now because it's jaring\n                            .attr(\"d\", d3.svg.line()\n                                    .x(function(e) { return plotType=='box' ? e.y : yScale(e.x); })\n                                    .y(function(e) { return plotType=='box' ? e.x : tmpScale(e.y) })\n                                    .interpolate(interp)\n                            )\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')) // rotate violin\n                            .style('opacity', !plotType ? '0' : '1');\n\n                        // area\n                        distroplots.selectAll('.nv-distribution-area.nv-distribution-' + side)\n                          //.watchTransition(renderWatch, 'nv-distribution-line: distroplots') // disable transition for now because it's jaring\n                            .attr(\"d\", d3.svg.area()\n                                    .x(function(e) { return plotType=='box' ? e.y : yScale(e.x); })\n                                    .y(function(e) { return plotType=='box' ? e.x : tmpScale(e.y) })\n                                    .y0(areaWidth()/2)\n                                    .interpolate(interp)\n                            )\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')) // rotate violin\n                            .style('opacity', !plotType ? '0' : '1');\n\n                    })\n                } else { // scatter type, hide areas\n                    distroplots.selectAll('.nv-distribution-area')\n                        .watchTransition(renderWatch, 'nv-distribution-area: distroplots')\n                        .style('opacity', !plotType ? '0' : '1');\n\n                    distroplots.selectAll('.nv-distribution-line')\n                        .watchTransition(renderWatch, 'nv-distribution-line: distroplots')\n                        .style('opacity', !plotType ? '0' : '1');\n                }\n\n            })\n\n            // tooltip events\n            distroplots.selectAll('path')\n                .on('mouseover', function(d,i,j) {\n                    d = d3.select(this.parentNode).datum(); // grab data from parent g\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        key: d.key,\n                        value: 'Group ' + d.key + ' stats',\n                        series: [\n                            { key: 'max', value: getMax(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q3', value: getQ3(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q2', value: getQ2(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q1', value: getQ1(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'min', value: getMin(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'mean', value: getMean(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'std. dev.', value: getDev(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'count', value: d.values.count, color: getColor(d) || color(d,j) },\n                            { key: 'num. outliers', value: d.values.num_outlier, color: getColor(d) || color(d,j) },\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    d = d3.select(this.parentNode).datum(); // grab data from parent g\n                    dispatch.elementMouseout({\n                        key: d.key,\n                        value: 'Group ' + d.key + ' stats',\n                        series: [\n                            { key: 'max', value: getMax(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q3', value: getQ3(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q2', value: getQ2(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q1', value: getQ1(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'min', value: getMin(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'mean', value: getMean(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'std. dev.', value: getDev(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'count', value: d.values.count, color: getColor(d) || color(d,j) },\n                            { key: 'num. outliers', value: d.values.num_outlier, color: getColor(d) || color(d,j) },\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n\n            // median/mean line\n            areaEnter.append('line')\n                .attr('class', function(d) { return 'nv-distroplot-middle'})\n\n\n            distroplots.selectAll('line.nv-distroplot-middle')\n                .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots line')\n                .attr('x1', notchBox ? tickLeft : plotType != 'violin' ? areaLeft : tickLeft())\n                .attr('y1', function(d,i,j) { return centralTendency == 'mean' ? yScale(getMean(d)) : yScale(getQ2(d)); })\n                .attr('x2', notchBox ? tickRight : plotType != 'violin' ? areaRight : tickRight())\n                .attr('y2', function(d,i) { return centralTendency == 'mean' ? yScale(getMean(d)) : yScale(getQ2(d)); })\n                .style('opacity', centralTendency ? '1' : '0');\n\n\n            // tooltip\n            distroplots.selectAll('.nv-distroplot-middle')\n                .on('mouseover', function(d,i,j) {\n                    if (d3.select(this).style('opacity') == 0) return; // don't show tooltip for hidden lines\n                    var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        value: centralTendency == 'mean' ? 'Mean' : 'Median',\n                        series: { key: centralTendency == 'mean' ? getMean(d).toFixed(2) : getQ2(d).toFixed(2), color: fillColor },\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    if (d3.select(this).style('opacity') == 0) return; // don't show tooltip for hidden lines\n                    d3.select(this).classed('hover', false);\n                    var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                    dispatch.elementMouseout({\n                        value: centralTendency == 'mean' ? 'Mean' : 'Median',\n                        series: { key: centralTendency == 'mean' ? getMean(d).toFixed(2) : getQ2(d).toFixed(2), color: fillColor },\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n\n            // setup observations\n            // create DOMs even if not requested (and hide them), so that\n            // we can do transitions on them\n            var obsWrap = distroplots.selectAll('g.nv-distroplot-observation')\n                .data(function(d) { return getValsObj(d) }, function(d) {  return d.object_constancy; });\n\n            var obsGroup = obsWrap.enter()\n                .append('g')\n                .attr('class', 'nv-distroplot-observation')\n\n            obsGroup.append('circle')\n                .style({'opacity': 0})\n\n            obsGroup.append('line')\n                .style('stroke-width', 1)\n                .style({'stroke': d3.rgb(85, 85, 85), 'opacity': 0})\n\n            obsWrap.exit().remove();\n            obsWrap.attr('class', function(d) { return 'nv-distroplot-observation ' + (isOutlier(d) && plotType == 'box' ? 'nv-distroplot-outlier' : 'nv-distroplot-non-outlier')})\n\n            // transition observations\n            if (observationType == 'line') {\n                distroplots.selectAll('g.nv-distroplot-observation line')\n                  .watchTransition(renderWatch, 'nv-distrolot-x-group: nv-distoplot-observation')\n                    .attr(\"x1\", tickLeft() + areaWidth()/4)\n                    .attr(\"x2\", tickRight() - areaWidth()/4)\n                    .attr('y1', function(d) { return yScale(d.datum)})\n                    .attr('y2', function(d) { return yScale(d.datum)});\n            } else {\n                distroplots.selectAll('g.nv-distroplot-observation circle')\n                  .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                    .attr('cy', function(d) { return yScale(d.datum); })\n                    .attr('r', pointSize);\n\n                // NOTE: this update can be slow when re-sizing window when many point visible \n                // TODO: filter selection down to only visible points, no need to update x-position\n                //       of the hidden points\n                distroplots.selectAll('g.nv-distroplot-observation circle')\n                  .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                    .attr('cx', function(d) { return observationType == 'swarm' ? d.x + areaWidth()/2 : observationType == 'random' ? areaWidth()/2 + d.randX * areaWidth()/2 : areaWidth()/2; })\n\n            }\n\n            // set opacity on outliers/non-outliers\n            // any circle/line entering has opacity 0\n            if (observationType !== false) { // observationType is False when hidding all circle/lines\n                if (!showOnlyOutliers) { // show all line/circle\n                    distroplots.selectAll(observationType== 'line' ? 'line':'circle')\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',1)\n                } else { // show only outliers\n                    distroplots.selectAll('.nv-distroplot-outlier '+ (observationType== 'line' ? 'line':'circle'))\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',1)\n                    distroplots.selectAll('.nv-distroplot-non-outlier '+ (observationType== 'line' ? 'line':'circle'))\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',0)\n                }\n            }\n\n            // hide all other observations\n            distroplots.selectAll('.nv-distroplot-observation' + (observationType=='line'?' circle':' line'))\n              .watchTransition(renderWatch, 'nv-distroplot: nv-distoplot-observation')\n                .style('opacity',0)\n\n            // tooltip events for observations\n            distroplots.selectAll('.nv-distroplot-observation')\n                    .on('mouseover', function(d,i,j) {\n                        var pt = d3.select(this);\n                        if (showOnlyOutliers && plotType == 'box' && !isOutlier(d)) return; // don't show tooltip for hidden observation\n                        var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                        pt.classed('hover', true);\n                        dispatch.elementMouseover({\n                            value: (plotType == 'box' && isOutlier(d)) ? 'Outlier' : 'Observation',\n                            series: { key: d.datum.toFixed(2), color: fillColor },\n                            e: d3.event\n                        });\n                    })\n                    .on('mouseout', function(d,i,j) {\n                        var pt = d3.select(this);\n                        var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                        pt.classed('hover', false);\n                        dispatch.elementMouseout({\n                            value: (plotType == 'box' && isOutlier(d)) ? 'Outlier' : 'Observation',\n                            series: { key: d.datum.toFixed(2), color: fillColor },\n                            e: d3.event\n                        });\n                    })\n                    .on('mousemove', function(d,i) {\n                        dispatch.elementMousemove({e: d3.event});\n                    });\n\n        });\n\n        renderWatch.renderEnd('nv-distroplot-x-group immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:            {get: function(){return width;}, set: function(_){width=_;}},\n        height:           {get: function(){return height;}, set: function(_){height=_;}},\n        maxBoxWidth:      {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}},\n        x:                {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:                {get: function(){return getY;}, set: function(_){getY=_;}},\n        plotType:         {get: function(){return plotType;}, set: function(_){plotType=_;}}, // plotType of background: 'box', 'violin' - default: 'box'\n        observationType:  {get: function(){return observationType;}, set: function(_){observationType=_;}}, // type of observations to show: 'random', 'swarm', 'line', 'point' - default: false (don't show observations)\n        whiskerDef:       {get: function(){return whiskerDef;}, set: function(_){whiskerDef=_;}}, // type of whisker to render: 'iqr', 'minmax', 'stddev' - default: iqr\n        notchBox:         {get: function(){return notchBox;}, set: function(_){notchBox=_;}}, // bool whether to notch box\n        hideWhiskers:     {get: function(){return hideWhiskers;}, set: function(_){hideWhiskers=_;}},\n        colorGroup:       {get: function(){return colorGroup;}, set: function(_){colorGroup=_;}}, // data key to use to set color group of each x-category - default: don't group\n        centralTendency:       {get: function(){return centralTendency;}, set: function(_){centralTendency=_;}}, // add a mean or median line to the data - default: don't show, must be one of 'mean' or 'median'\n        bandwidth:        {get: function(){return bandwidth;}, set: function(_){bandwidth=_;}}, // bandwidth for kde calculation, can be float or str, if str, must be one of scott or silverman\n        clampViolin:           {get: function(){return clampViolin;}, set: function(_){clampViolin=_;}},\n        resolution:       {get: function(){return resolution;}, set: function(_){resolution=_;}}, // resolution for kde calculation, default 50\n        xScale:           {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:           {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        showOnlyOutliers: {get: function(){return showOnlyOutliers;}, set: function(_){showOnlyOutliers=_;}}, // show only outliers in box plot, default true\n        jitter:           {get: function(){return jitter;}, set: function(_){jitter=_;}}, // faction of that jitter should take up in 'random' observationType, must be in range [0,1]; see jitterX(), default 0.7\n        squash:           {get: function(){return squash;}, set: function(_){squash=_;}}, // whether to squash sparse distribution of color groups towards middle of x-axis position\n        pointSize:     {get: function(){return pointSize;}, set: function(_){pointSize=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        recalcData:   {get: function() { reformatDat = prepData(container.datum()); } },\n        itemColor:    {get: function(){return getColor;}, set: function(_){getColor=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.distroPlotChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var distroplot = nv.models.distroPlot(),\n        xAxis = nv.models.axis(),\n        yAxis = nv.models.axis()\n\n    var margin = {top: 25, right: 10, bottom: 40, left: 60},\n        width = null,\n        height = null,\n        color = nv.utils.getColor(),\n        showXAxis = true,\n        showYAxis = true,\n        rightAlignYAxis = false,\n        staggerLabels = false,\n        xLabel = false,\n        yLabel = false,\n        tooltip = nv.models.tooltip(),\n        x, y,\n        noData = 'No Data Available.',\n        dispatch = d3.dispatch('stateChange', 'beforeUpdate', 'renderEnd'),\n        duration = 500;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip.duration(0);\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var colorGroup0, marginTop0 = margin.top, x0, y0, resolution0, bandwidth0, clampViolin0;\n    var dataCache;\n\n\n    // return true if data has changed somehow after\n    // an .update() was called\n    // works by comparing current data set to the\n    // one previously cached\n    // TODO - since we keep another version of the dataset\n    // around for comparison, it doubles the memory usage :(\n    function dataHasChanged(d) {\n        if (arraysEqual(d, dataCache)) {\n            return false;\n        } else {\n            dataCache = JSON.parse(JSON.stringify(d)) // deep copy\n            return true;\n        }\n    }\n\n    // return true if array of objects equivalent\n    function arraysEqual(arr1, arr2) {\n        if(arr1.length !== arr2.length) return false;\n\n        for(var i = arr1.length; i--;) {\n            if ('object_constancy' in arr1[i]) delete arr1[i].object_constancy\n            if ('object_constancy' in arr2[i]) delete arr2[i].object_constancy\n\n            if(!objectEquals(arr1[i], arr2[i])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    // return true if objects are equivalent\n    function objectEquals(a, b) {\n        // Create arrays of property names\n        var aProps = Object.getOwnPropertyNames(a);\n        var bProps = Object.getOwnPropertyNames(b);\n\n        // If number of properties is different,\n        // objects are not equivalent\n        if (aProps.length != bProps.length) {\n            return false;\n        }\n\n        for (var i = 0; i < aProps.length; i++) {\n            var propName = aProps[i];\n\n            // If values of same property are not equal,\n            // objects are not equivalent\n            if (a[propName] !== b[propName]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(distroplot);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this), that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = (width  || parseInt(container.style('width')) || 960) - margin.left - margin.right;\n            var availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;\n\n            if (typeof dataCache === 'undefined') {\n                dataCache = JSON.parse(JSON.stringify(data)) // deep copy\n            }\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                var opts = distroplot.options()\n                if (colorGroup0 !== opts.colorGroup() || // recalc data when any of the axis accessors are changed\n                    x0 !== opts.x() ||\n                    y0 !== opts.y() ||\n                    bandwidth0 !== opts.bandwidth() ||\n                    resolution0 !== opts.resolution() ||\n                    clampViolin0 !== opts.clampViolin() ||\n                    dataHasChanged(data)\n                ) {\n                    distroplot.recalcData();\n                }\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n\n            if (typeof d3.beeswarm !== 'function' && chart.options().observationType() == 'swarm') {\n                var xPos = margin.left + availableWidth/2;\n                noData = 'Please include the library https://github.com/Kcnarf/d3-beeswarm to use \"swarm\".'\n                nv.utils.noData(chart, container);\n                return chart;\n            } else if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = distroplot.xScale();\n            y = distroplot.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-distroPlot').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-distroPlot').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-distroWrap');\n            gEnter.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            g.watchTransition(renderWatch, 'nv-wrap: wrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(' + availableWidth + ',0)');\n            }\n\n\n            // Main Chart Component(s)\n            distroplot.width(availableWidth).height(availableHeight);\n\n            var distroWrap = g.select('.nv-distroWrap')\n                .datum(data)\n\n            distroWrap.transition().call(distroplot);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + distroplot.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + distroplot.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    .ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis').attr('transform', 'translate(0,' + y.range()[0] + ')')\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                //g.select('.nv-x.nv-axis').select('.nv-axislabel')\n                //    .style('font-size', d3.min([availableWidth * 0.05,20]) + 'px')\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 === 0 ? '5' : '17') + ')' })\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    .ticks( Math.floor(availableHeight/36) ) // can't use nv.utils.calcTicksY with Object data\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n\n                //g.select('.nv-y.nv-axis').select('.nv-axislabel')\n                //    .style('font-size', d3.min([availableHeight * 0.05,20]) + 'px')\n            }\n\n\n\n\n            // Zero line on chart bottom\n            g.select('.nv-zeroLine line')\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', y(0))\n                .attr('y2', y(0))\n            ;\n\n            // store original values so that we can\n            // call 'recalcData()' if needed\n            colorGroup0 = distroplot.options().colorGroup();\n            x0 = distroplot.options().x();\n            y0 = distroplot.options().y();\n            bandwidth0 = distroplot.options().bandwidth();\n            resolution0 = distroplot.options().resolution();\n            clampViolin0 = distroplot.options().clampViolin();\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n        });\n\n        renderWatch.renderEnd('nv-distroplot chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    distroplot.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    distroplot.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.data(evt).hidden(true);\n    });\n\n    distroplot.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.distroplot = distroplot;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        tooltipContent:    {get: function(){return tooltip;}, set: function(_){tooltip=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            distroplot.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            distroplot.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        xLabel:  {get: function(){return xLabel;}, set: function(_){\n            xLabel=_;\n            xAxis.axisLabel(xLabel);\n        }},\n        yLabel:  {get: function(){return yLabel;}, set: function(_){\n            yLabel=_;\n            yAxis.axisLabel(yLabel);\n        }},\n    });\n\n\n    nv.utils.inheritOptions(chart, distroplot);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\nnv.models.focus = function(content) {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var content = content || nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , brush = d3.svg.brush()\n        ;\n\n    var margin = {top: 10, right: 0, bottom: 30, left: 0}\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = 70\n        , showXAxis = true\n        , showYAxis = false\n        , rightAlignYAxis = false\n        , ticks = null\n        , x\n        , y\n        , brushExtent = null\n        , duration = 250\n        , dispatch = d3.dispatch('brush', 'onBrush', 'renderEnd')\n        , syncBrushing = true\n        ;\n\n    content.interactive(false);\n    content.pointActive(function(d) { return false; });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(content);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = height - margin.top - margin.bottom;\n\n            chart.update = function() { \n                if( duration === 0 ) {\n                    container.call( chart );\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = this;\n\n            // Setup Scales\n            x = content.xScale();\n            y = content.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-focus').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-focus').append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            gEnter.append('g').attr('class', 'nv-background').append('rect');\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-contentWrap');\n            gEnter.append('g').attr('class', 'nv-brushBackground');\n            gEnter.append('g').attr('class', 'nv-x nv-brush');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n                \n            content\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var contentWrap = g.select('.nv-contentWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n            d3.transition(contentWrap).call(content);\n            \n            // Setup Brush\n            brush\n                .x(x)\n                .on('brush', function() {\n                    onBrush(syncBrushing);\n                });\n\n            brush.on('brushend', function () {\n                if (!syncBrushing) {\n                    dispatch.onBrush(brush.empty() ? x.domain() : brush.extent());\n                }\n            });\n\n            if (brushExtent) brush.extent(brushExtent);\n\n            var brushBG = g.select('.nv-brushBackground').selectAll('g')\n                .data([brushExtent || brush.extent()]);\n    \n            var brushBGenter = brushBG.enter()\n                .append('g');\n\n            brushBGenter.append('rect')\n                .attr('class', 'left')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight);\n\n            brushBGenter.append('rect')\n                .attr('class', 'right')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight);\n\n            var gBrush = g.select('.nv-x.nv-brush')\n                .call(brush);\n            gBrush.selectAll('rect')\n                .attr('height', availableHeight);\n            gBrush.selectAll('.resize').append('path').attr('d', resizePath);\n\n            onBrush(true);\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            if (showXAxis) {\n                xAxis.scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n  \n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                d3.transition(g.select('.nv-x.nv-axis'))\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                d3.transition(g.select('.nv-y.nv-axis'))\n                    .call(yAxis);\n            }\n            \n            g.select('.nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + y.range()[0] + ')');\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n    \n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight / 3;\n                return 'M' + (0.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (0.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n    \n    \n            function updateBrushBG() {\n                if (!brush.empty()) brush.extent(brushExtent);\n                brushBG\n                    .data([brush.empty() ? x.domain() : brushExtent])\n                    .each(function(d,i) {\n                        var leftWidth = x(d[0]) - x.range()[0],\n                            rightWidth = availableWidth - x(d[1]);\n                        d3.select(this).select('.left')\n                            .attr('width',  leftWidth < 0 ? 0 : leftWidth);\n    \n                        d3.select(this).select('.right')\n                            .attr('x', x(d[1]))\n                            .attr('width', rightWidth < 0 ? 0 : rightWidth);\n                    });\n            }\n\n\n            function onBrush(shouldDispatch) {\n                brushExtent = brush.empty() ? null : brush.extent();\n                var extent = brush.empty() ? x.domain() : brush.extent();\n                dispatch.brush({extent: extent, brush: brush});\n                updateBrushBG();\n                if (shouldDispatch) {\n                    dispatch.onBrush(extent);\n                }\n            }\n        });\n\n        renderWatch.renderEnd('focus immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.content = content;\n    chart.brush = brush;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        brushExtent: {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}},\n        syncBrushing: {get: function(){return syncBrushing;}, set: function(_){syncBrushing=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            content.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            content.color(color);\n        }},\n        interpolate: {get: function(){return content.interpolate();}, set: function(_){\n            content.interpolate(_);\n        }},\n        xTickFormat: {get: function(){return xAxis.tickFormat();}, set: function(_){\n            xAxis.tickFormat(_);\n        }},\n        yTickFormat: {get: function(){return yAxis.tickFormat();}, set: function(_){\n            yAxis.tickFormat(_);\n        }},\n        x: {get: function(){return content.x();}, set: function(_){\n            content.x(_);\n        }},\n        y: {get: function(){return content.y();}, set: function(_){\n            content.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, content);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.forceDirectedGraph = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n    var margin = {top: 2, right: 0, bottom: 2, left: 0}\n        , width = 400\n        , height = 32\n        , container = null\n        , dispatch = d3.dispatch('renderEnd')\n        , color = nv.utils.getColor(['#000'])\n        , tooltip      = nv.models.tooltip()\n        , noData = null\n        // Force directed graph specific parameters [default values]\n        , linkStrength = 0.1\n        , friction = 0.9\n        , linkDist = 30\n        , charge = -120\n        , gravity = 0.1\n        , theta = 0.8\n        , alpha = 0.1\n        , radius = 5\n        // These functions allow to add extra attributes to ndes and links\n        ,nodeExtras = function(nodes) { /* Do nothing */ }\n        ,linkExtras = function(links) { /* Do nothing */ }\n        , getX=d3.functor(0.0)\n        , getY=d3.functor(0.0)\n        ;\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n\n        selection.each(function(data) {\n          container = d3.select(this);\n          nv.utils.initSVG(container);\n\n          var availableWidth = nv.utils.availableWidth(width, container, margin),\n              availableHeight = nv.utils.availableHeight(height, container, margin);\n\n          container\n                  .attr(\"width\", availableWidth)\n                  .attr(\"height\", availableHeight);\n\n          // Display No Data message if there's nothing to show.\n          if (!data || !data.links || !data.nodes) {\n              nv.utils.noData(chart, container)\n              return chart;\n          } else {\n              container.selectAll('.nv-noData').remove();\n          }\n          container.selectAll('*').remove();\n\n          // Collect names of all fields in the nodes\n          var nodeFieldSet = new Set();\n          data.nodes.forEach(function(node) {\n            var keys = Object.keys(node);\n            keys.forEach(function(key) {\n              nodeFieldSet.add(key);\n            });\n          });\n\n          var force = d3.layout.force()\n                .nodes(data.nodes)\n                .links(data.links)\n                .size([availableWidth, availableHeight])\n                .linkStrength(linkStrength)\n                .friction(friction)\n                .linkDistance(linkDist)\n                .charge(charge)\n                .gravity(gravity)\n                .theta(theta)\n                .alpha(alpha)\n                .start();\n\n          var link = container.selectAll(\".link\")\n                .data(data.links)\n                .enter().append(\"line\")\n                .attr(\"class\", \"nv-force-link\")\n                .style(\"stroke-width\", function(d) { return Math.sqrt(d.value); });\n\n          var node = container.selectAll(\".node\")\n                .data(data.nodes)\n                .enter()\n                .append(\"g\")\n                .attr(\"class\", \"nv-force-node\")\n                .call(force.drag);\n\n          node\n            .append(\"circle\")\n            .attr(\"r\", radius)\n            .style(\"fill\", function(d) { return color(d) } )\n            .on(\"mouseover\", function(evt) {\n              container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                  .attr('y1', evt.py);\n              container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                  .attr('x2', evt.px);\n\n              // Add 'series' object to\n              var nodeColor = color(evt);\n              evt.series = [];\n              nodeFieldSet.forEach(function(field) {\n                evt.series.push({\n                  color: nodeColor,\n                  key:   field,\n                  value: evt[field]\n                });\n              });\n              tooltip.data(evt).hidden(false);\n            })\n            .on(\"mouseout\",  function(d) {\n              tooltip.hidden(true);\n            });\n\n          tooltip.headerFormatter(function(d) {return \"Node\";});\n\n          // Apply extra attributes to nodes and links (if any)\n          linkExtras(link);\n          nodeExtras(node);\n\n          force.on(\"tick\", function() {\n              link.attr(\"x1\", function(d) { return d.source.x; })\n                  .attr(\"y1\", function(d) { return d.source.y; })\n                  .attr(\"x2\", function(d) { return d.target.x; })\n                  .attr(\"y2\", function(d) { return d.target.y; });\n\n              node.attr(\"transform\", function(d) {\n                return \"translate(\" + d.x + \", \" + d.y + \")\";\n              });\n            });\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:     {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n\n        // Force directed graph specific parameters\n        linkStrength:{get: function(){return linkStrength;}, set: function(_){linkStrength=_;}},\n        friction:    {get: function(){return friction;}, set: function(_){friction=_;}},\n        linkDist:    {get: function(){return linkDist;}, set: function(_){linkDist=_;}},\n        charge:      {get: function(){return charge;}, set: function(_){charge=_;}},\n        gravity:     {get: function(){return gravity;}, set: function(_){gravity=_;}},\n        theta:       {get: function(){return theta;}, set: function(_){theta=_;}},\n        alpha:       {get: function(){return alpha;}, set: function(_){alpha=_;}},\n        radius:      {get: function(){return radius;}, set: function(_){radius=_;}},\n\n        //functor options\n        x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},\n        y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        nodeExtras: {get: function(){return nodeExtras;}, set: function(_){\n            nodeExtras = _;\n        }},\n        linkExtras: {get: function(){return linkExtras;}, set: function(_){\n            linkExtras = _;\n        }}\n    });\n\n    chart.dispatch = dispatch;\n    chart.tooltip = tooltip;\n    nv.utils.initOptions(chart);\n    return chart;\n};\nnv.models.furiousLegend = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , width = 400\n        , height = 20\n        , getKey = function(d) { return d.key }\n        , keyFormatter = function (d) { return d }\n        , color = nv.utils.getColor()\n        , maxKeyLength = 20 //default value for key lengths\n        , align = true\n        , padding = 28 //define how much space between legend items. - recommend 32 for furious version\n        , rightAlign = true\n        , updateState = true   //If true, legend will update data.disabled and trigger a 'stateChange' dispatch.\n        , radioButtonMode = false   //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time)\n        , expanded = false\n        , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange')\n        , vers = 'classic' //Options are \"classic\" and \"furious\"\n        ;\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-legend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var series = g.selectAll('.nv-series')\n                .data(function(d) {\n                    if(vers != 'furious') return d;\n\n                    return d.filter(function(n) {\n                        return expanded ? true : !n.disengaged;\n                    });\n                });\n            var seriesEnter = series.enter().append('g').attr('class', 'nv-series')\n\n            var seriesShape;\n\n            if(vers == 'classic') {\n                seriesEnter.append('circle')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('r', 5);\n\n                seriesShape = series.select('circle');\n            } else if (vers == 'furious') {\n                seriesEnter.append('rect')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('rx', 3)\n                    .attr('ry', 3);\n\n                seriesShape = series.select('rect');\n\n                seriesEnter.append('g')\n                    .attr('class', 'nv-check-box')\n                    .property('innerHTML','<path d=\"M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z\" class=\"nv-box\"></path><path d=\"M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511\" class=\"nv-check\"></path>')\n                    .attr('transform', 'translate(-10,-8)scale(0.5)');\n\n                var seriesCheckbox = series.select('.nv-check-box');\n\n                seriesCheckbox.each(function(d,i) {\n                    d3.select(this).selectAll('path')\n                        .attr('stroke', setTextColor(d,i));\n                });\n            }\n\n            seriesEnter.append('text')\n                .attr('text-anchor', 'start')\n                .attr('class','nv-legend-text')\n                .attr('dy', '.32em')\n                .attr('dx', '8');\n\n            var seriesText = series.select('text.nv-legend-text');\n\n            series\n                .on('mouseover', function(d,i) {\n                    dispatch.legendMouseover(d,i);  //TODO: Make consistent with other event objects\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.legendMouseout(d,i);\n                })\n                .on('click', function(d,i) {\n                    dispatch.legendClick(d,i);\n                    // make sure we re-get data in case it was modified\n                    var data = series.data();\n                    if (updateState) {\n                        if(vers =='classic') {\n                            if (radioButtonMode) {\n                                //Radio button mode: set every series to disabled,\n                                //  and enable the clicked series.\n                                data.forEach(function(series) { series.disabled = true});\n                                d.disabled = false;\n                            }\n                            else {\n                                d.disabled = !d.disabled;\n                                if (data.every(function(series) { return series.disabled})) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) { series.disabled = false});\n                                }\n                            }\n                        } else if(vers == 'furious') {\n                            if(expanded) {\n                                d.disengaged = !d.disengaged;\n                                d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled;\n                                d.disabled = d.disengaged || d.userDisabled;\n                            } else if (!expanded) {\n                                d.disabled = !d.disabled;\n                                d.userDisabled = d.disabled;\n                                var engaged = data.filter(function(d) { return !d.disengaged; });\n                                if (engaged.every(function(series) { return series.userDisabled })) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) {\n                                        series.disabled = series.userDisabled = false;\n                                    });\n                                }\n                            }\n                        }\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled }),\n                            disengaged: data.map(function(d) { return !!d.disengaged })\n                        });\n\n                    }\n                })\n                .on('dblclick', function(d,i) {\n                    if(vers == 'furious' && expanded) return;\n                    dispatch.legendDblclick(d,i);\n                    if (updateState) {\n                        // make sure we re-get data in case it was modified\n                        var data = series.data();\n                        //the default behavior of NVD3 legends, when double clicking one,\n                        // is to set all other series' to false, and make the double clicked series enabled.\n                        data.forEach(function(series) {\n                            series.disabled = true;\n                            if(vers == 'furious') series.userDisabled = series.disabled;\n                        });\n                        d.disabled = false;\n                        if(vers == 'furious') d.userDisabled = d.disabled;\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled })\n                        });\n                    }\n                });\n\n            series.classed('nv-disabled', function(d) { return d.userDisabled });\n            series.exit().remove();\n\n            seriesText\n                .attr('fill', setTextColor)\n                .text(function (d) { return keyFormatter(getKey(d)) });\n\n            //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option)\n            // NEW ALIGNING CODE, TODO: clean up\n\n            var versPadding;\n            switch(vers) {\n                case 'furious' :\n                    versPadding = 23;\n                    break;\n                case 'classic' :\n                    versPadding = 20;\n            }\n\n            if (align) {\n\n                var seriesWidths = [];\n                series.each(function(d,i) {\n                    var legendText;\n                    if (keyFormatter(getKey(d)) && keyFormatter(getKey(d)).length > maxKeyLength) {\n                        var trimmedKey = keyFormatter(getKey(d)).substring(0, maxKeyLength);\n                        legendText = d3.select(this).select('text').text(trimmedKey + \"...\");\n                        d3.select(this).append(\"svg:title\").text(keyFormatter(getKey(d)));\n                    } else {\n                        legendText = d3.select(this).select('text');\n                    }\n                    var nodeTextLength;\n                    try {\n                        nodeTextLength = legendText.node().getComputedTextLength();\n                        // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead\n                        if(nodeTextLength <= 0) throw Error();\n                    }\n                    catch(e) {\n                        nodeTextLength = nv.utils.calcApproxTextWidth(legendText);\n                    }\n\n                    seriesWidths.push(nodeTextLength + padding);\n                });\n\n                var seriesPerRow = 0;\n                var legendWidth = 0;\n                var columnWidths = [];\n\n                while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {\n                    columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];\n                    legendWidth += seriesWidths[seriesPerRow++];\n                }\n                if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row\n\n                while ( legendWidth > availableWidth && seriesPerRow > 1 ) {\n                    columnWidths = [];\n                    seriesPerRow--;\n\n                    for (var k = 0; k < seriesWidths.length; k++) {\n                        if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )\n                            columnWidths[k % seriesPerRow] = seriesWidths[k];\n                    }\n\n                    legendWidth = columnWidths.reduce(function(prev, cur, index, array) {\n                        return prev + cur;\n                    });\n                }\n\n                var xPositions = [];\n                for (var i = 0, curX = 0; i < seriesPerRow; i++) {\n                    xPositions[i] = curX;\n                    curX += columnWidths[i];\n                }\n\n                series\n                    .attr('transform', function(d, i) {\n                        return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                if (rightAlign) {\n                    g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');\n                }\n                else {\n                    g.attr('transform', 'translate(0' + ',' + margin.top + ')');\n                }\n\n                height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding);\n\n            } else {\n\n                var ypos = 5,\n                    newxpos = 5,\n                    maxwidth = 0,\n                    xpos;\n                series\n                    .attr('transform', function(d, i) {\n                        var length = d3.select(this).select('text').node().getComputedTextLength() + padding;\n                        xpos = newxpos;\n\n                        if (width < margin.left + margin.right + xpos + length) {\n                            newxpos = xpos = 5;\n                            ypos += versPadding;\n                        }\n\n                        newxpos += length;\n                        if (newxpos > maxwidth) maxwidth = newxpos;\n\n                        return 'translate(' + xpos + ',' + ypos + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');\n\n                height = margin.top + margin.bottom + ypos + 15;\n            }\n\n            if(vers == 'furious') {\n                // Size rectangles after text is placed\n                seriesShape\n                    .attr('width', function(d,i) {\n                        return seriesText[0][i].getComputedTextLength() + 27;\n                    })\n                    .attr('height', 18)\n                    .attr('y', -9)\n                    .attr('x', -15)\n            }\n\n            seriesShape\n                .style('fill', setBGColor)\n                .style('stroke', function(d,i) { return d.color || color(d, i) });\n        });\n\n        function setTextColor(d,i) {\n            if(vers != 'furious') return '#000';\n            if(expanded) {\n                return d.disengaged ? color(d,i) : '#fff';\n            } else if (!expanded) {\n                return !!d.disabled ? color(d,i) : '#fff';\n            }\n        }\n\n        function setBGColor(d,i) {\n            if(expanded && vers == 'furious') {\n                return d.disengaged ? '#fff' : color(d,i);\n            } else {\n                return !!d.disabled ? '#fff' : color(d,i);\n            }\n        }\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:          {get: function(){return width;}, set: function(_){width=_;}},\n        height:         {get: function(){return height;}, set: function(_){height=_;}},\n        key:            {get: function(){return getKey;}, set: function(_){getKey=_;}},\n        keyFormatter:   {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        align:          {get: function(){return align;}, set: function(_){align=_;}},\n        rightAlign:     {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}},\n        maxKeyLength:   {get: function(){return maxKeyLength;}, set: function(_){maxKeyLength=_;}},\n        padding:        {get: function(){return padding;}, set: function(_){padding=_;}},\n        updateState:    {get: function(){return updateState;}, set: function(_){updateState=_;}},\n        radioButtonMode:{get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}},\n        expanded:       {get: function(){return expanded;}, set: function(_){expanded=_;}},\n        vers:           {get: function(){return vers;}, set: function(_){vers=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n/* \nImprovements:\n- consistenly apply no-hover classes to rect isntead of to containing g, see example CSS style for .no-hover rect, rect.no-hover\n- row/column order (user specified) or 'ascending' / 'descending'\n- I haven't tested for transitions between changing datasets\n*/\n\nnv.models.heatMap = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , xScale = d3.scale.ordinal()\n        , yScale = d3.scale.ordinal()\n        , colorScale = false\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getCellValue = function(d) { return d.value }\n        , showCellValues = true\n        , cellValueFormat = function(d) { return typeof d === 'number' ? d.toFixed(0) : d }\n        , cellAspectRatio = false // width / height of cell\n        , cellRadius = 2\n        , cellBorderWidth = 4 // pixels between cells\n        , normalize = false\n        , highContrastText = true\n        , xDomain\n        , yDomain\n        , xMetaColorScale = nv.utils.defaultColor()\n        , yMetaColorScale = nv.utils.defaultColor()\n        , missingDataColor = '#bcbcbc'\n        , missingDataLabel = ''\n        , metaOffset = 5 // spacing between meta rects and cells\n        , xRange\n        , yRange\n        , xMeta\n        , yMeta\n        , colorRange\n        , colorDomain\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , duration = 250\n        , xMetaHeight = function(d) { return cellHeight / 3 }\n        , yMetaWidth = function(d) { return cellWidth / 3 }\n        , showGrid = false\n        ;\n\n\n\n    //============================================================\n    // Aux helper function for heatmap\n    //------------------------------------------------------------\n    // choose high contrast text color based on background\n    // shameful steal: https://github.com/alexandersimoes/d3plus/blob/master/src/color/text.coffee\n    function cellTextColor(bgColor) {\n\n        if (highContrastText) {\n            var rgbColor = d3.rgb(bgColor);\n            var r = rgbColor.r;\n            var g = rgbColor.g;\n            var b = rgbColor.b;\n            var yiq = (r * 299 + g * 587 + b * 114) / 1000;\n            return yiq >= 128 ? \"#404040\" : \"#EDEDED\"; // dark text else light text\n        } else {\n            return 'black';\n        }\n    }\n\n    /* go through heatmap data and generate array of values\n     * for each row/column or for entire dataset; for use in\n     * calculating means/medians of data for normalizing\n     * @param {str} axis - 'row', 'col' or null\n     *\n     * @returns {row/column index: [array of values for row/col]}\n     * note that if axis is not specified, the return will be\n     * {0: [all values in heatmap]}\n     */\n    function getHeatmapValues(data, axis) {\n        var vals = {};\n\n        data.forEach(function(cell, i) {\n            if (axis == 'row') {\n                if (!(getIY(cell) in vals)) vals[getIY(cell)] = [];\n                vals[getIY(cell)].push(getCellValue(cell));\n            } else if (axis == 'col') {\n                if (!(getIX(cell) in vals)) vals[getIX(cell)] = [];\n                vals[getIX(cell)].push(getCellValue(cell));\n            } else if (axis == null) { // if calculating stat over entire dataset\n                if (!(0 in vals)) vals[0] = [];\n                vals[0].push(getCellValue(cell)); \n            }\n        })\n\n        return vals;\n    }\n\n    // calculate the median absolute deviation of the given array of data\n    // https://en.wikipedia.org/wiki/Median_absolute_deviation\n    // MAD = median(abs(Xi - median(X)))\n    function mad(dat) {\n        var med = d3.median(dat);\n        var vals = dat.map(function(d) { return Math.abs(d - med); })\n        return d3.median(vals);\n    }\n\n\n    // set cell color based on cell value\n    // depending on whether it should be normalized or not\n    function cellColor(d) {\n        var colorVal = normalize ? getNorm(d) : getCellValue(d);\n        return (cellsAreNumeric() && !isNaN(colorVal) || typeof colorVal !== 'undefined') ? colorScale(colorVal) : missingDataColor;\n    }\n\n    // return the domain of the color data\n    // if ordinal data is given for the cells, this will\n    // return all possible cells values; otherwise it\n    // returns the extent of the cell values\n    // will take into account normalization if specified\n    function getColorDomain() {\n    \n        if (cellsAreNumeric()) { // if cell values are numeric\n            return normalize ? d3.extent(prepedData, function(d) { return getNorm(d); }) : d3.extent(uniqueColor);\n        } else if (!cellsAreNumeric()) { // if cell values are ordinal\n            return uniqueColor;\n        }\n    }\n\n    // return true if cells are numeric\n    // as opposed to categorical\n    function cellsAreNumeric() {\n        return typeof uniqueColor[0] === 'number';\n    }\n\n    /*\n     * Normalize input data\n     *\n     * normalize must be one of centerX, robustCenterX, centerScaleX, robustCenterScaleX, centerAll, \n     * robustCenterAll, centerScaleAll, robustCenterScaleAll where X is either 'Row' or 'Column'\n     *\n     * - centerX: subtract row/column mean from cell\n     * - centerAll: subtract mean of whole data set from cell\n     * - centerScaleX: scale so that row/column has mean 0 and variance 1 (Z-score)\n     * - centerScaleAll: scale by overall normalization factor so that the whole data set has mean 0 and variance 1 (Z-score)\n     * - robustCenterX: subtract row/column median from cell\n     * - robustCenterScaleX: subtract row/column median from cell and then scale row/column by median absolute deviation\n     * - robustCenterAll: subtract median of whole data set from cell\n     * - robustCenterScaleAll: subtract overall median from cell and scale by overall median absolute deviation\n     */\n    function normalizeData(dat) {\n        \n        var normTypes = ['centerRow',\n            'robustCenterRow',\n            'centerScaleRow',\n            'robustCenterScaleRow',\n            'centerColumn',\n            'robustCenterColumn',\n            'centerScaleColumn',\n            'robustCenterScaleColumn',\n            'centerAll',\n            'robustCenterAll',\n            'centerScaleAll',\n            'robustCenterScaleAll'];\n\n\n        if(normTypes.indexOf(normalize) != -1) {\n\n            var xVals = Object.keys(uniqueX), yVals = Object.keys(uniqueY);\n\n            // setup normalization options\n            var scale = normalize.includes('Scale') ? true: false,\n                agg = normalize.includes('robust') ? 'median': 'mean',\n                axis = normalize.includes('Row') ? 'row' : normalize.includes('Column') ? 'col' : null,\n                vals = getHeatmapValues(dat, axis);\n\n            // calculate mean or median\n            // calculate standard dev or median absolute deviation\n            var stat = {};\n            var dev = {};\n            for (var key in vals) {\n                stat[key] = agg == 'mean' ? d3.mean(vals[key]) : d3.median(vals[key]);\n                if (scale) dev[key] = agg == 'mean' ? d3.deviation(vals[key]) : mad(vals[key]);\n            }\n\n\n            // do the normalizing\n            dat.forEach(function(cell, i) {\n                if (cellsAreNumeric()) {\n                    if (axis == 'row') {\n                        var key = getIY(cell);\n                    } else if (axis == 'col') {\n                        var key = getIX(cell);\n                    } else if (axis == null) {  // if calculating stat over entire dataset\n                        var key = 0;\n                    }\n\n                    var normVal = getCellValue(cell) - stat[key];\n                    if (scale) {\n                        cell._cellPos.norm = normVal / dev[key];\n                    } else {\n                        cell._cellPos.norm = normVal;\n                    }\n                } else {\n                    cell._cellPos.norm = getCellValue(cell); // if trying to normalize ordinal cells, just set norm to cell value\n                }\n            })\n\n        } else {\n            normalize = false; // proper normalize option was not provided, disable it so heatmap still shows colors\n        }\n\n        return dat;\n    }\n\n    /*\n     * Process incoming data for use with heatmap including:\n     * - adding a unique key indexer to each data point (idx)\n     * - getting a unique list of all x & y values\n     * - generating a position index (x & y) for each data point\n     * - sorting that data for correct traversal when generating rect\n     * - generating placeholders for missing data\n     *\n     * In order to allow for the flexibility of the user providing either\n     * categorical or quantitative data, we're going to position the cells\n     * through indices that we increment based on previously seen data\n     * this way we can use ordinal() axes even if the data is quantitative.\n     *\n     * When we generate the SVG elements, we assumes traversal occures from\n     * top to bottom and from left to right.\n     *\n     * @param data {list} - input data organize as a list of objects\n     *\n     * @return - copy of input data with additional '_cellPos' key\n     *           formatted as {idx: XXX, ix, XXX, iy: XXX}\n     *           where idx is a global identifier; ix is an identifier\n     *           within each column, and iy is an identifier within\n     *           each row. \n     */\n    function prepData(data) {\n\n        // reinitialize\n        uniqueX = {}, // {cell x value: ix index}\n        uniqueY = {}, // {cell y value: iy index}\n        uniqueColor = [], // [cell color value]\n        uniqueXMeta = [], // [cell x metadata value]\n        uniqueYMeta = [], // [cell y metadata value]\n        uniqueCells = []; // [cell x,y values stored as array]\n        var warnings = [];\n        var sortedCells = {}; // {cell x values: {cell y value: cell data, ... }, ... }\n\n        var ix = 0, iy = 0; // use these indices to position cell in x & y direction\n        var combo, idx=0;\n        data.forEach(function(cell) {\n            var valX = getX(cell),\n                valY = getY(cell),\n                valColor = getCellValue(cell);            \n\n            // assemble list of unique values for each dimension\n            if (!(valX in uniqueX)) { \n                uniqueX[valX] = ix; \n                ix++;\n\n                sortedCells[valX] = {}\n\n                if (typeof xMeta === 'function') uniqueXMeta.push(xMeta(cell));\n            }\n\n            if (!(valY in uniqueY)) {\n                uniqueY[valY] = iy; \n                iy++;\n\n                sortedCells[valX][valY] = {}\n\n                if (typeof yMeta === 'function') uniqueYMeta.push(yMeta(cell));\n            }\n            if (uniqueColor.indexOf(valColor) == -1) uniqueColor.push(valColor)\n\n\n            // for each data point, we generate an object of data\n            // needed to properly position each cell\n            cell._cellPos = {\n                idx: idx,\n                ix: uniqueX[valX],\n                iy: uniqueY[valY],\n            }\n            idx++;\n\n\n            // keep track of row & column combinations we've already seen\n            // this prevents the same cells from being generated when\n            // the user hasn't provided proper data (one value for each\n            // row & column).\n            // if properly formatted data is not provided, only the first\n            // row & column value is used (the rest are ignored)\n            combo = [valX, valY];\n            if (!isArrayInArray(uniqueCells, combo)) {\n                uniqueCells.push(combo)\n                sortedCells[valX][valY] = cell;\n            } else if (warnings.indexOf(valX + valY) == -1) {\n                warnings.push(valX + valY);\n                console.warn(\"The row/column position \" + valX + \"/\" + valY + \" has multiple values; ensure each cell has only a single value.\");\n            }\n\n        });\n\n        uniqueColor = uniqueColor.sort()\n\n        // check in sortedCells that each x has all the y's\n        // if not, generate an empty placeholder\n        // this will also sort all cells from left to right\n        // and top to bottom\n        var reformatData = [];\n        Object.keys(uniqueY).forEach(function(j) {\n            Object.keys(uniqueX).forEach(function(i) {\n                var cellVal = sortedCells[i][j];\n    \n                if (cellVal) {\n                    reformatData.push(cellVal);\n                } else {\n                    var cellPos = {\n                        idx: idx,\n                        ix: uniqueX[i],\n                        iy: uniqueY[j],\n                    }\n                    idx++;\n                    reformatData.push({_cellPos: cellPos}); // empty cell placeholder\n                }\n            })\n        })\n\n\n        // normalize data is needed\n        return normalize ? normalizeData(reformatData) : reformatData;\n\n    }\n\n    // https://stackoverflow.com/a/41661388/1153897\n    function isArrayInArray(arr, item){\n      var item_as_string = JSON.stringify(item);\n\n      var contains = arr.some(function(ele){\n        return JSON.stringify(ele) === item_as_string;\n      });\n      return contains;\n    }\n\n    function removeAllHoverClasses() {\n        // remove all hover classes\n        d3.selectAll('.cell-hover').classed('cell-hover', false);\n        d3.selectAll('.no-hover').classed('no-hover', false);\n        d3.selectAll('.row-hover').classed('row-hover', false);\n        d3.selectAll('.column-hover').classed('column-hover', false);\n    }\n\n    // return the formatted cell value if it is\n    // a number, otherwise return missingDataLabel\n    var cellValueLabel = function(d) {\n        var val = !normalize ? cellValueFormat(getCellValue(d)) : cellValueFormat(getNorm(d));\n        return (cellsAreNumeric() && !isNaN(val) || typeof val !== 'undefined') ? val : missingDataLabel;\n    }\n\n    // https://stackoverflow.com/a/16794116/1153897\n    // note this returns the obj keys\n    function sortObjByVals(obj) {\n        return Object.keys(obj).sort(function(a,b){return obj[a]-obj[b]})\n    }\n\n    // https://stackoverflow.com/a/28191966/1153897\n    function getKeyByValue(object, value) {\n        //return Object.keys(object).find(key => object[key] === value);\n        return Object.keys(object).filter(function(key) {return object[key] === value})[0];\n    }\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var prepedData, cellHeight, cellWidth;\n    var uniqueX = {}, uniqueY = {}, uniqueColor = [];\n    var uniqueXMeta = [], uniqueYMeta = [], uniqueCells = []\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var RdYlBu = [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"];\n\n    var getCellPos = function(d) { return d._cellPos; };\n    var getIX = function(d) { return getCellPos(d).ix; } // get the given cell's x index position\n    var getIY = function(d) { return getCellPos(d).iy; } // get the given cell's y index position\n    var getNorm = function(d) { return getCellPos(d).norm; }\n    var getIdx = function(d) { return getCellPos(d).idx; }\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n\n            prepedData = prepData(data);\n\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            // available width/height set the cell dimenions unless\n            // the aspect ratio is defined - in that case the cell\n            // height is adjusted and availableHeight updated\n            cellWidth = availableWidth / Object.keys(uniqueX).length;\n            cellHeight = cellAspectRatio ? cellWidth / cellAspectRatio : availableHeight / Object.keys(uniqueY).length;\n            if (cellAspectRatio) availableHeight = cellHeight * Object.keys(uniqueY).length - margin.top - margin.bottom;\n\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n  \n            // Setup Scales\n            xScale.domain(xDomain || sortObjByVals(uniqueX))\n                  .rangeBands(xRange || [0, availableWidth-cellBorderWidth/2]);\n            yScale.domain(yDomain || sortObjByVals(uniqueY))\n                  .rangeBands(yRange || [0, availableHeight-cellBorderWidth/2]);\n            colorScale = cellsAreNumeric() ? d3.scale.quantize() : d3.scale.ordinal();\n            colorScale.domain(colorDomain || getColorDomain())\n                  .range(colorRange || RdYlBu);\n\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-heatMapWrap').data([prepedData]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-heatMapWrap');\n            wrapEnter\n                .append('g')\n                .attr('class','cellWrap')\n\n            wrap.watchTransition(renderWatch, 'nv-wrap: heatMapWrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var gridWrap = wrapEnter\n                .append('g')\n                .attr('class','cellGrid')\n                .style('opacity',1e-6)\n\n            var gridLinesV = wrap.select('.cellGrid').selectAll('.gridLines.verticalGrid')\n                .data(Object.values(uniqueX).concat([Object.values(uniqueX).length]))\n                \n            gridLinesV.enter()\n                .append('line')\n                .attr('class','gridLines verticalGrid')\n\n            gridLinesV.exit()\n                .remove()\n\n            var gridLinesH = wrap.select('.cellGrid').selectAll('.gridLines.horizontalGrid')\n                .data(Object.values(uniqueY).concat([Object.values(uniqueY).length]))\n                \n            gridLinesH.enter()\n                .append('line')\n                .attr('class','gridLines horizontalGrid')\n\n            gridLinesH.exit()\n                .remove()\n\n            var cellWrap = wrap.select('.cellWrap')\n                .selectAll(\".nv-cell\")\n                .data(function(d) { return d; }, function(e) { return getIdx(e); })\n\n            var xMetaWrap = wrapEnter\n                .append('g')\n                .attr('class','xMetaWrap')\n                .attr(\"transform\", function() { return \"translate(0,\" + (-xMetaHeight()-cellBorderWidth-metaOffset) + \")\" })\n\n            var xMetas = wrap.select('.xMetaWrap').selectAll('.x-meta')\n                .data(uniqueXMeta)\n\n            var xMetaEnter = xMetas\n                .enter()\n                .append('rect')\n                .attr('class','x-meta meta')\n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", xMetaHeight())\n                .attr(\"transform\", \"translate(0,0)\")\n                .attr(\"fill\", function(d) { return xMetaColorScale(d); })\n\n            var yMetaWrap = wrapEnter\n                .append('g')\n                .attr('class','yMetaWrap')\n                .attr(\"transform\", function(d,i) { return \"translate(\" + (-yMetaWidth()-cellBorderWidth-metaOffset) + \",0)\" })\n\n            var yMetas = wrap.select('.yMetaWrap').selectAll('.y-meta')\n                .data(uniqueYMeta)\n\n            var yMetaEnter = yMetas\n                .enter()\n                .append('rect')\n                .attr('class','y-meta meta')\n                .attr(\"width\", yMetaWidth())\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr(\"transform\", function(d,i) { return \"translate(0,0)\" })\n                .attr(\"fill\", function(d,i) { return yMetaColorScale(d); })\n\n            xMetas.exit().remove()\n            yMetas.exit().remove()\n          \n            // CELLS    \n            var cellsEnter = cellWrap\n                .enter()\n                .append('g')\n                .style('opacity', 1e-6)\n                .attr(\"transform\", function(d) { return \"translate(0,\" + getIY(d) * cellHeight + \")\" }) // enter all g's here for a sweep-right transition\n                .attr('data-row', function(d) { return getIY(d) })\n                .attr('data-column', function(d) { return getIX(d) });\n\n            cellsEnter\n                .append(\"rect\") \n\n            cellsEnter\n                .append('text')\n                .attr('text-anchor', 'middle')\n                .attr(\"dy\", 4)\n                .attr(\"class\",\"cell-text\")\n\n            \n            // transition cell (rect) size\n            cellWrap.selectAll('rect')\n                .watchTransition(renderWatch, 'heatMap: rect')\n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr('rx', cellRadius)\n                .attr('ry', cellRadius)\n                .style('stroke', function(d) { return cellColor(d) })\n\n            // transition cell (g) position, opacity and fill\n            cellWrap\n                .attr(\"class\",function(d) { return isNaN(getCellValue(d)) ? 'nv-cell cell-missing' : 'nv-cell'}) \n                .watchTransition(renderWatch, 'heatMap: cells')\n                .style({\n                    'opacity': 1,\n                    'fill': function(d) { return cellColor(d) },\n                })\n                .attr(\"transform\", function(d) { return \"translate(\" + getIX(d) * cellWidth + \",\" + getIY(d) * cellHeight + \")\" })\n                .attr(\"class\",function(d) { return isNaN(getCellValue(d)) ? 'nv-cell cell-missing' : 'nv-cell'}) \n\n            cellWrap.exit().remove();\n\n            // transition text position and fill\n            cellWrap.selectAll('text')\n                .watchTransition(renderWatch, 'heatMap: cells text')\n                .text(function(d) { return cellValueLabel(d); })\n                .attr(\"x\", function(d) { return (cellWidth-cellBorderWidth) / 2; })\n                .attr(\"y\", function(d) { return (cellHeight-cellBorderWidth) / 2; })\n                .style(\"fill\", function(d) { return cellTextColor(cellColor(d)) })\n                .style('opacity', function() { return showCellValues ? 1 : 0 })\n\n            // transition grid\n            wrap.selectAll('.verticalGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines') \n                .attr('y1',0)\n                .attr('y2',availableHeight-cellBorderWidth)\n                .attr('x1',function(d) { return d*cellWidth-cellBorderWidth/2; })\n                .attr('x2',function(d) { return d*cellWidth-cellBorderWidth/2; })\n\n            var numHLines = Object.keys(uniqueY).length;\n            wrap.selectAll('.horizontalGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines') \n                .attr('x1',function(d) { return (d == 0 || d == numHLines) ? -cellBorderWidth : 0 })\n                .attr('x2',function(d) { return (d == 0 || d == numHLines) ? availableWidth : availableWidth-cellBorderWidth})\n                .attr('y1',function(d) { return d*cellHeight-cellBorderWidth/2; })\n                .attr('y2',function(d) { return d*cellHeight-cellBorderWidth/2; })\n\n            wrap.select('.cellGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines')\n                .style({\n                    'stroke-width': cellBorderWidth,\n                    'opacity': function() { return showGrid ? 1 : 1e-6 },\n                })\n\n            var xMetaRect = wrap.selectAll('.x-meta')\n            var yMetaRect = wrap.selectAll('.y-meta')\n            var allMetaRect = wrap.selectAll('.meta')\n\n            // transition meta rect size\n            xMetas\n                .watchTransition(renderWatch, 'heatMap: xMetaRect') \n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", xMetaHeight())\n                .attr(\"transform\", function(d,i) { return \"translate(\" + (i * cellWidth) + \",0)\" })\n\n            yMetas\n                .watchTransition(renderWatch, 'heatMap: yMetaRect') \n                .attr(\"width\", yMetaWidth())\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr(\"transform\", function(d,i) { return \"translate(0,\" + (i * cellHeight) + \")\" })\n\n\n            // transition position of meta wrap g & opacity\n            wrap.select('.xMetaWrap')\n                .watchTransition(renderWatch, 'heatMap: xMetaWrap') \n                .attr(\"transform\", function(d,i) { return \"translate(0,\" + (-xMetaHeight()-cellBorderWidth-metaOffset) + \")\" })\n                .style(\"opacity\", function() { return xMeta !== false ? 1 : 0 })\n            wrap.select('.yMetaWrap')\n                .watchTransition(renderWatch, 'heatMap: yMetaWrap') \n                .attr(\"transform\", function(d,i) { return \"translate(\" + (-yMetaWidth()-cellBorderWidth-metaOffset) + \",0)\" })\n                .style(\"opacity\", function() { return yMeta !== false ? 1 : 0 })\n\n            // TOOLTIPS\n            cellWrap\n                .on('mouseover', function(d,i) {\n\n                    var idx = getIdx(d);\n                    var ix = getIX(d);\n                    var iy = getIY(d);\n\n                    // set the proper classes for all cells\n                    // hover row gets class .row-hover\n                    // hover column gets class .column-hover\n                    // hover cell gets class .cell-hover\n                    // all remaining cells get class .no-hover\n                    d3.selectAll('.nv-cell').each(function(e) {\n                        if (idx == getIdx(e)) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                        if (ix == getIX(e)) {\n                            d3.select(this).classed('no-hover', false);\n                            d3.select(this).classed('column-hover', true);\n                        }\n                        if (iy == getIY(e)) {\n                            d3.select(this).classed('no-hover', false);\n                            d3.select(this).classed('row-hover', true);\n                        }\n                    })\n    \n                    // set hover classes for column metadata\n                    d3.selectAll('.x-meta').each(function(e, j) {\n                        if (j == ix) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                    });\n\n                    // set hover class for row metadata\n                    d3.selectAll('.y-meta').each(function(e, j) {\n                        if (j == iy) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                    });\n                    \n                    dispatch.elementMouseover({\n                        value: getKeyByValue(uniqueX, ix) + ' & ' + getKeyByValue(uniqueY, iy), \n                        series: {\n                                value: cellValueLabel(d), \n                                color: d3.select(this).select('rect').style(\"fill\")\n                                },\n                        e: d3.event,\n                    });\n\n                })\n                .on('mouseout', function(d,i) {\n\n                    // allow tooltip to remain even when mouse is over the\n                    // space between the cell;\n                    // this prevents cells from \"flashing\" when transitioning\n                    // between cells\n                    var bBox = d3.select(this).select('rect').node().getBBox();\n                    var coordinates = d3.mouse(d3.select('.nv-heatMap').node());\n                    var x = coordinates[0];\n                    var y = coordinates[1];\n\n                    // we only trigger mouseout when mouse moves outside of\n                    // .nv-heatMap\n                    if (x + cellBorderWidth >= availableWidth || y + cellBorderWidth >= availableHeight || x < 0 || y < 0) {\n                        // remove all hover classes\n                        removeAllHoverClasses();\n\n                        dispatch.elementMouseout({e: d3.event});\n                    }\n                })\n                .on('mousemove', function(d,i) {\n\n                    dispatch.elementMousemove({e: d3.event});\n                })\n\n            allMetaRect\n                .on('mouseover', function(d,i) {\n\n                    // true if hovering over a row metadata rect\n                    var isColMeta = d3.select(this).attr('class').indexOf('x-meta') != -1 ? true : false;\n\n                    // apply proper .row-hover & .column-hover\n                    // classes to cells\n                    d3.selectAll('.nv-cell').each(function(e) {\n\n                        if (isColMeta && i == getIX(e)) {\n                            d3.select(this).classed('column-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else if (!isColMeta && i-uniqueXMeta.length == getIY(e)) {\n                            // since allMetaRect selects all the meta rects, the index for the y's will\n                            // be offset by the number of x rects. TODO - write seperate tooltip sections\n                            // for x meta rect & y meta rect\n                            d3.select(this).classed('row-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('column-hover', false);\n                            d3.select(this).classed('row-hover', false);\n                        }\n                        d3.select(this).classed('cell-hover', false);\n                    })\n\n                    // apply proper .row-hover & .column-hover\n                    // classes to meta rects\n                    d3.selectAll('.meta').classed('no-hover', true);\n                    d3.select(this).classed('cell-hover', true);\n                    d3.select(this).classed('no-hover', false);\n\n                    dispatch.elementMouseover({\n                        value: isColMeta ? 'Column meta' : 'Row meta',\n                        series: { value: d, color: d3.select(this).style('fill'), }\n                    });\n                })\n                .on('mouseout', function(d,i) {\n\n                    // true if hovering over a row metadata rect\n                    var isColMeta = d3.select(this).attr('class').indexOf('x-meta') != -1 ? true : false;\n\n                    // allow tooltip to remain even when mouse is over the\n                    // space between the cell;\n                    // this prevents cells from \"flashing\" when transitioning\n                    // between cells\n                    var bBox = d3.select(this).node().getBBox();\n                    var coordinates = d3.mouse(d3.select(isColMeta ? '.xMetaWrap' : '.yMetaWrap').node());\n                    var x = coordinates[0];\n                    var y = coordinates[1];\n\n                    if ( y < 0 || x < 0 || \n                        (isColMeta && x + cellBorderWidth >= availableWidth) ||\n                        (!isColMeta && y + cellBorderWidth >= availableHeight)\n                    ) {\n                        // remove all hover classes\n                        removeAllHoverClasses();\n\n                        dispatch.elementMouseout({e: d3.event});\n                    }\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                })\n\n        });\n\n\n        renderWatch.renderEnd('heatMap immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        showCellValues: {get: function(){return showCellValues;}, set: function(_){showCellValues=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}}, // data attribute for horizontal axis\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}}, // data attribute for vertical axis\n        cellValue:       {get: function(){return getCellValue;}, set: function(_){getCellValue=_;}}, // data attribute that sets cell value and color\n        missingDataColor:  {get: function(){return missingDataColor;}, set: function(_){missingDataColor=_;}},\n        missingDataLabel:  {get: function(){return missingDataLabel;}, set: function(_){missingDataLabel=_;}},\n        xScale:  {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:  {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        colorScale:  {get: function(){return colorScale;}, set: function(_){colorScale=_;}}, // scale to map cell values to colors\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        colorRange:  {get: function(){return colorRange;}, set: function(_){colorRange=_;}},\n        colorDomain:  {get: function(){return colorDomain;}, set: function(_){colorDomain=_;}},\n        xMeta:  {get: function(){return xMeta;}, set: function(_){xMeta=_;}},\n        yMeta:  {get: function(){return yMeta;}, set: function(_){yMeta=_;}},\n        xMetaColorScale:  {get: function(){return color;}, set: function(_){color = nv.utils.getColor(_);}},\n        yMetaColorScale:  {get: function(){return color;}, set: function(_){color = nv.utils.getColor(_);}},\n        cellAspectRatio:  {get: function(){return cellAspectRatio;}, set: function(_){cellAspectRatio=_;}}, // cell width / height\n        cellRadius:  {get: function(){return cellRadius;}, set: function(_){cellRadius=_;}}, // cell width / height\n        cellHeight:  {get: function(){return cellHeight;}}, // TODO - should not be exposed since we don't want user setting this\n        cellWidth:   {get: function(){return cellWidth;}}, // TODO - should not be exposed since we don't want user setting this\n        normalize:   {get: function(){return normalize;}, set: function(_){normalize=_;}},\n        cellBorderWidth:     {get: function(){return cellBorderWidth;}, set: function(_){cellBorderWidth=_;}},\n        highContrastText:    {get: function(){return highContrastText;}, set: function(_){highContrastText=_;}},\n        cellValueFormat:     {get: function(){return cellValueFormat;}, set: function(_){cellValueFormat=_;}},\n        id:                  {get: function(){return id;}, set: function(_){id=_;}},\n        metaOffset:          {get: function(){return metaOffset;}, set: function(_){metaOffset=_;}},\n        xMetaHeight:         {get: function(){return xMetaHeight;}, set: function(_){xMetaHeight=_;}},\n        yMetaWidth:          {get: function(){return yMetaWidth;}, set: function(_){yMetaWidth=_;}},\n        showGrid:          {get: function(){return showGrid;}, set: function(_){showGrid=_;}},\n\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n\n    return chart;\n};\n/* Heatmap Chart Type\n\nA heatmap is a graphical representation of data where the individual values\ncontained in a matrix are represented as colors within cells. Furthermore,\nmetadata can be associated with each of the matrix rows or columns. By grouping\nthese rows/columns together by a given metadata value, data trends can be spotted.\n\nFormat for input data should be:\nvar data = [\n    {day: 'mo', hour: '1a', value: 16, timeperiod: 'early morning', weekperiod: 'week', category: 1},\n    {day: 'mo', hour: '2a', value: 20, timeperiod: 'early morning', weekperiod: 'week', category: 2},\n    {day: 'mo', hour: '3a', value: 0, timeperiod: 'early morning', weekperiod: 'week', category: 1},\n    ...\n]\nwhere the keys 'day' and 'hour' specify the row/column of the heatmap, 'value' specifies the  cell\nvalue and the keys 'timeperiod', 'weekperiod' and 'week' are extra metadata that can be associated\nwith rows/columns.\n\n\nOptions for chart:\n*/\nnv.models.heatMapChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var heatMap = nv.models.heatMap()\n        , legend = nv.models.legend()\n        , legendRowMeta = nv.models.legend()\n        , legendColumnMeta = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        ;\n\n\n    var margin = {top: 20, right: 10, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.getColor()\n        , showLegend = true\n        , staggerLabels = false\n        , showXAxis = true\n        , showYAxis = true\n        , alignYAxis = 'left'\n        , alignXAxis = 'top'\n        , rotateLabels = 0\n        , title = false\n        , x\n        , y\n        , noData = null\n        , dispatch = d3.dispatch('beforeUpdate','renderEnd')\n        , duration = 250\n        ;\n\n    xAxis\n        .orient(alignXAxis)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient(alignYAxis)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(true)\n        .keyFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    // https://bl.ocks.org/mbostock/4573883\n    // get max/min range for all the quantized cell values\n    // returns an array where each element is [start,stop]\n    // of color bin\n    function quantizeLegendValues() {\n\n        var e = heatMap.colorScale(), legendVals;\n\n        if (typeof e.domain()[0] === 'string') { // if color scale is ordinal\n\n            legendVals = e.domain();\n\n        } else { // if color scale is numeric\n\n            legendVals = e.range().map(function(color) {\n              var d = e.invertExtent(color);\n              if (d[0] === null) d[0] = e.domain()[0];\n              if (d[1] === null) d[1] = e.domain()[1];\n              return d;\n            })\n\n        }\n\n        return legendVals\n\n    }\n\n    // return true if row metadata specified by user\n    function hasRowMeta() {\n        return typeof heatMap.yMeta() === 'function'\n    }\n    // return true if col metadata specified by user\n    function hasColumnMeta() {\n        return typeof heatMap.xMeta() === 'function'\n    }\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(heatMap);\n        renderWatch.models(xAxis);\n        renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = heatMap.xScale();\n            y = heatMap.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap').append('g');\n            var g = wrap.select('g');\n\n\n            gEnter.append('g').attr('class', 'nv-heatMap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n\n            heatMap\n                .width(availableWidth)\n                .height(availableHeight);\n\n\n            var heatMapWrap = g.select('.nv-heatMap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n\n            heatMapWrap.transition().call(heatMap);\n\n\n            if (heatMap.cellAspectRatio()) {\n                availableHeight = heatMap.cellHeight() * y.domain().length;\n                heatMap.height(availableHeight);\n            }\n\n\n            // Setup Axes\n            xAxis\n                .scale(x)\n                ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                .tickSize(-availableHeight, 0);\n\n            var axisX = g.select('.nv-x.nv-axis')\n\n            axisX.call(xAxis)\n                .watchTransition(renderWatch, 'heatMap: axisX')\n                .selectAll('.tick')\n                .style('opacity', function() { return showXAxis ? 1 : 0 } )\n\n            var xTicks = axisX.selectAll('g');\n\n            xTicks\n                .selectAll('.tick text')\n                .attr('transform', function(d,i,j) {\n                    var rot = rotateLabels != 0 ? rotateLabels : '0';\n                    var stagger = staggerLabels ? j % 2 == 0 ? '5' : '17' : '0';\n                    return 'translate(0, ' + stagger + ') rotate(' + rot + ' 0,0)';\n                })\n                .style('text-anchor', rotateLabels > 0 ? 'start' : rotateLabels < 0 ? 'end' : 'middle');\n\n            // position text in center of meta rects\n            var yPos = -5;\n            if (hasColumnMeta()) {\n                axisX.selectAll('text').style('text-anchor', 'middle')\n                yPos = -heatMap.xMetaHeight()()/2 - heatMap.metaOffset() + 3;\n            }\n\n            // adjust position of axis based on presence of metadata group\n            if (alignXAxis == 'bottom') {\n                axisX\n                    .watchTransition(renderWatch, 'heatMap: axisX')\n                    .attr(\"transform\", \"translate(0,\" + (availableHeight - yPos) + \")\");\n                if (heatMap.xMeta() !== false) { // if showing x metadata\n                    var pos = availableHeight+heatMap.metaOffset()+heatMap.cellBorderWidth()\n                    g.select('.xMetaWrap')\n                        .watchTransition(renderWatch, 'heatMap: xMetaWrap')\n                        .attr(\"transform\", function(d,i) { return \"translate(0,\" + pos + \")\" })\n                }\n            } else {\n                axisX\n                    .watchTransition(renderWatch, 'heatMap: axisX')\n                    .attr(\"transform\", \"translate(0,\" + yPos + \")\");\n            }\n\n\n            yAxis\n                .scale(y)\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n            var axisY = g.select('.nv-y.nv-axis')\n\n            axisY.call(yAxis)\n                .watchTransition(renderWatch, 'heatMap: axisY')\n                .selectAll('.tick')\n                .style('opacity', function() { return showYAxis ? 1 : 0 } )\n\n            // position text in center of meta rects\n            var xPos = -5;\n            if (hasRowMeta()) {\n                axisY.selectAll('text').style('text-anchor', 'middle')\n                xPos = -heatMap.yMetaWidth()()/2 - heatMap.metaOffset();\n            }\n\n            // adjust position of axis based on presence of metadata group\n            if (alignYAxis == 'right') {\n                axisY.attr(\"transform\", \"translate(\" + (availableWidth - xPos) + \",0)\");\n                if (heatMap.yMeta() !== false) { // if showing y meatdata\n                    var pos = availableWidth+heatMap.metaOffset()+heatMap.cellBorderWidth()\n                    g.select('.yMetaWrap')\n                        .watchTransition(renderWatch, 'heatMap: yMetaWrap')\n                        .attr(\"transform\", function(d,i) { return \"translate(\" + pos + \",0)\" })\n                }\n            } else {\n                axisY.attr(\"transform\", \"translate(\" + xPos + \",0)\");\n            }\n\n\n\n            // Legend\n            var legendWrap = g.select('.nv-legendWrap')\n\n            legend\n                .width(availableWidth)\n                .color(heatMap.colorScale().range())\n\n            var legendVal = quantizeLegendValues().map(function(d) {\n                if (Array.isArray(d)) { // if cell values are numeric\n                    return {key: d[0].toFixed(1) + \" - \" + d[1].toFixed(1)};\n                } else { // if cell values are ordinal\n                    return {key: d};\n                }\n            })\n            \n\n            legendWrap\n                .datum(legendVal)\n                .call(legend)\n                .attr('transform', 'translate(0,' + (alignXAxis == 'top' ? availableHeight : -30) + ')'); // TODO: more intelligent offset (-30) when top aligning legend\n\n            legendWrap\n                .watchTransition(renderWatch, 'heatMap: nv-legendWrap')\n                .style('opacity', function() { return showLegend ? 1 : 0 } )\n\n        });\n\n        // axis don't have a flag for disabling the zero line, so we do it manually\n        d3.selectAll('.nv-axis').selectAll('line')\n            .style('stroke-opacity', 0)\n        d3.select('.nv-y').select('path.domain').remove()\n\n        renderWatch.renderEnd('heatMap chart immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    heatMap.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    heatMap.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    heatMap.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.heatMap = heatMap;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        noData:     {get: function(){return noData;}, set: function(_){noData=_;}},\n        showXAxis:     {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:     {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:  {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            heatMap.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        alignYAxis: {get: function(){return alignYAxis;}, set: function(_){\n            alignYAxis = _;\n            yAxis.orient(_);\n        }},\n        alignXAxis: {get: function(){return alignXAxis;}, set: function(_){\n            alignXAxis = _;\n            xAxis.orient(_);\n        }},\n    });\n\n    nv.utils.inheritOptions(chart, heatMap);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n//TODO: consider deprecating and using multibar with single series for this\nnv.models.historicalBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceX = []\n        , forceY = [0]\n        , padData = false\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , interactive = true\n        ;\n\n    var renderWatch = nv.utils.renderWatch(dispatch, 0);\n\n    function chart(selection) {\n        selection.each(function(data) {\n            renderWatch.reset();\n\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [0, availableWidth]);\n\n            y.domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) ))\n                .range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-historicalBar-' + id).data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBar-' + id);\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-bars');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var bars = wrap.select('.nv-bars').selectAll('.nv-bar')\n                .data(function(d) { return d }, function(d,i) {return getX(d,i)});\n            bars.exit().remove();\n\n            bars.enter().append('rect')\n                .attr('x', 0 )\n                .attr('y', function(d,i) {  return nv.utils.NaNtoZero(y(Math.max(0, getY(d,i)))) })\n                .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.abs(y(getY(d,i)) - y(0))) })\n                .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })\n                .on('mouseover', function(d,i) {\n                    if (!interactive) return;\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n\n                })\n                .on('mouseout', function(d,i) {\n                    if (!interactive) return;\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    if (!interactive) return;\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    if (!interactive) return;\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    if (!interactive) return;\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            bars\n                .attr('fill', function(d,i) { return color(d, i); })\n                .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })\n                .watchTransition(renderWatch, 'bars')\n                .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })\n                //TODO: better width calculations that don't assume always uniform data spacing;w\n                .attr('width', (availableWidth / data[0].values.length) * .9 );\n\n            bars.watchTransition(renderWatch, 'bars')\n                .attr('y', function(d,i) {\n                    var rval = getY(d,i) < 0 ?\n                        y(0) :\n                            y(0) - y(getY(d,i)) < 1 ?\n                        y(0) - 1 :\n                        y(getY(d,i));\n                    return nv.utils.NaNtoZero(rval);\n                })\n                .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) });\n\n        });\n\n        renderWatch.renderEnd('historicalBar immediate');\n        return chart;\n    }\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        container\n            .select(\".nv-bars .nv-bar-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container\n            .select(\".nv-bars .nv-bar.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        forceX:  {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData: {get: function(){return padData;}, set: function(_){padData=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.historicalBarChart = function(bar_model) {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var bars = bar_model || nv.models.historicalBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        ;\n\n\n    var margin = {top: 30, right: 90, bottom: 50, left: 90}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = false\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , useInteractiveGuideline = false\n        , x\n        , y\n        , state = {}\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('tooltipHide', 'stateChange', 'changeState', 'renderEnd')\n        , transitionDuration = 250\n        ;\n\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient( (rightAlignYAxis) ? 'right' : 'left');\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, 0);\n\n    function chart(selection) {\n        selection.each(function(data) {\n            renderWatch.reset();\n            renderWatch.models(bars);\n            if (showXAxis) renderWatch.models(xAxis);\n            if (showYAxis) renderWatch.models(yAxis);\n\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().duration(transitionDuration).call(chart) };\n            chart.container = this;\n\n            //set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = bars.xScale();\n            y = bars.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-historicalBarChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBarChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n            bars\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n            barsWrap.transition().call(bars);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .transition()\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .transition()\n                    .call(yAxis);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                bars.clearHighlights();\n\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        bars.highlightPoint(pointIndex,true);\n                        var point = series.values[pointIndex];\n                        if (point === undefined) return;\n                        if (singlePoint === undefined) singlePoint = point;\n                        if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: chart.y()(point, pointIndex),\n                            color: color(series,series.seriesIndex),\n                            data: series.values[pointIndex]\n                        });\n                    });\n\n                var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex));\n                interactiveLayer.tooltip\n                    .valueFormatter(function(d,i) {\n                        return yAxis.tickFormat()(d);\n                    })\n                    .data({\n                        value: xValue,\n                        index: pointIndex,\n                        series: allData\n                    })();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                dispatch.tooltipHide();\n                bars.clearHighlights();\n            });\n\n            legend.dispatch.on('legendClick', function(d,i) {\n                d.disabled = !d.disabled;\n\n                if (!data.filter(function(d) { return !d.disabled }).length) {\n                    data.map(function(d) {\n                        d.disabled = false;\n                        wrap.selectAll('.nv-series').classed('disabled', false);\n                        return d;\n                    });\n                }\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n\n                selection.transition().call(chart);\n            });\n\n            legend.dispatch.on('legendDblclick', function(d) {\n                //Double clicking should always enable current series, and disabled all others.\n                data.forEach(function(d) {\n                    d.disabled = true;\n                });\n                d.disabled = false;\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                chart.update();\n            });\n        });\n\n        renderWatch.renderEnd('historicalBarChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    bars.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    bars.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bars.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.bars = bars;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            bars.color(color);\n        }},\n        duration:    {get: function(){return transitionDuration;}, set: function(_){\n            transitionDuration=_;\n            renderWatch.reset(transitionDuration);\n            yAxis.duration(transitionDuration);\n            xAxis.duration(transitionDuration);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (_ === true) {\n                chart.interactive(false);\n            }\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, bars);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\n\n// ohlcChart is just a historical chart with ohlc bars and some tweaks\nnv.models.ohlcBarChart = function() {\n    var chart = nv.models.historicalBarChart(nv.models.ohlcBar());\n\n    // special default tooltip since we show multiple values per x\n    chart.useInteractiveGuideline(true);\n    chart.interactiveLayer.tooltip.contentGenerator(function(data) {\n        // we assume only one series exists for this chart\n        var d = data.series[0].data;\n        // match line colors as defined in nv.d3.css\n        var color = d.open < d.close ? \"2ca02c\" : \"d62728\";\n        return '' +\n            '<h3 style=\"color: #' + color + '\">' + data.value + '</h3>' +\n            '<table>' +\n            '<tr><td>open:</td><td>' + chart.yAxis.tickFormat()(d.open) + '</td></tr>' +\n            '<tr><td>close:</td><td>' + chart.yAxis.tickFormat()(d.close) + '</td></tr>' +\n            '<tr><td>high</td><td>' + chart.yAxis.tickFormat()(d.high) + '</td></tr>' +\n            '<tr><td>low:</td><td>' + chart.yAxis.tickFormat()(d.low) + '</td></tr>' +\n            '</table>';\n    });\n    return chart;\n};\n\n// candlestickChart is just a historical chart with candlestick bars and some tweaks\nnv.models.candlestickBarChart = function() {\n    var chart = nv.models.historicalBarChart(nv.models.candlestickBar());\n\n    // special default tooltip since we show multiple values per x\n    chart.useInteractiveGuideline(true);\n    chart.interactiveLayer.tooltip.contentGenerator(function(data) {\n        // we assume only one series exists for this chart\n        var d = data.series[0].data;\n        // match line colors as defined in nv.d3.css\n        var color = d.open < d.close ? \"2ca02c\" : \"d62728\";\n        return '' +\n            '<h3 style=\"color: #' + color + '\">' + data.value + '</h3>' +\n            '<table>' +\n            '<tr><td>open:</td><td>' + chart.yAxis.tickFormat()(d.open) + '</td></tr>' +\n            '<tr><td>close:</td><td>' + chart.yAxis.tickFormat()(d.close) + '</td></tr>' +\n            '<tr><td>high</td><td>' + chart.yAxis.tickFormat()(d.high) + '</td></tr>' +\n            '<tr><td>low:</td><td>' + chart.yAxis.tickFormat()(d.low) + '</td></tr>' +\n            '</table>';\n    });\n    return chart;\n};\nnv.models.legend = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , width = 400\n        , height = 20\n        , getKey = function(d) { return d.key }\n        , keyFormatter = function (d) { return d }\n        , color = nv.utils.getColor()\n        , maxKeyLength = 20 //default value for key lengths\n        , align = true\n        , padding = 32 //define how much space between legend items. - recommend 32 for furious version\n        , rightAlign = true\n        , updateState = true   //If true, legend will update data.disabled and trigger a 'stateChange' dispatch.\n        , enableDoubleClick = true   //If true, legend will enable double click handling\n        , radioButtonMode = false   //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time)\n        , expanded = false\n        , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange')\n        , vers = 'classic' //Options are \"classic\" and \"furious\"\n        ;\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-legend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g');\n            var g = wrap.select('g');\n\n            if (rightAlign)\n                wrap.attr('transform', 'translate(' + (- margin.right) + ',' + margin.top + ')');\n            else\n                wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var series = g.selectAll('.nv-series')\n                .data(function(d) {\n                    if(vers != 'furious') return d;\n\n                    return d.filter(function(n) {\n                        return expanded ? true : !n.disengaged;\n                    });\n                });\n\n            var seriesEnter = series.enter().append('g').attr('class', 'nv-series');\n            var seriesShape;\n\n            var versPadding;\n            switch(vers) {\n                case 'furious' :\n                    versPadding = 23;\n                    break;\n                case 'classic' :\n                    versPadding = 20;\n            }\n\n            if(vers == 'classic') {\n                seriesEnter.append('circle')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('r', 5);\n\n                seriesShape = series.select('.nv-legend-symbol');\n            } else if (vers == 'furious') {\n                seriesEnter.append('rect')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('rx', 3)\n                    .attr('ry', 3);\n                seriesShape = series.select('.nv-legend-symbol');\n\n                seriesEnter.append('g')\n                    .attr('class', 'nv-check-box')\n                    .property('innerHTML','<path d=\"M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z\" class=\"nv-box\"></path><path d=\"M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511\" class=\"nv-check\"></path>')\n                    .attr('transform', 'translate(-10,-8)scale(0.5)');\n\n                var seriesCheckbox = series.select('.nv-check-box');\n\n                seriesCheckbox.each(function(d,i) {\n                    d3.select(this).selectAll('path')\n                        .attr('stroke', setTextColor(d,i));\n                });\n            }\n\n            seriesEnter.append('text')\n                .attr('text-anchor', 'start')\n                .attr('class','nv-legend-text')\n                .attr('dy', '.32em')\n                .attr('dx', '8');\n\n            var seriesText = series.select('text.nv-legend-text');\n\n            series\n                .on('mouseover', function(d,i) {\n                    dispatch.legendMouseover(d,i);  //TODO: Make consistent with other event objects\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.legendMouseout(d,i);\n                })\n                .on('click', function(d,i) {\n                    dispatch.legendClick(d,i);\n                    // make sure we re-get data in case it was modified\n                    var data = series.data();\n                    if (updateState) {\n                        if(vers =='classic') {\n                            if (radioButtonMode) {\n                                //Radio button mode: set every series to disabled,\n                                //  and enable the clicked series.\n                                data.forEach(function(series) { series.disabled = true});\n                                d.disabled = false;\n                            }\n                            else {\n                                d.disabled = !d.disabled;\n                                if (data.every(function(series) { return series.disabled})) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) { series.disabled = false});\n                                }\n                            }\n                        } else if(vers == 'furious') {\n                            if(expanded) {\n                                d.disengaged = !d.disengaged;\n                                d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled;\n                                d.disabled = d.disengaged || d.userDisabled;\n                            } else if (!expanded) {\n                                d.disabled = !d.disabled;\n                                d.userDisabled = d.disabled;\n                                var engaged = data.filter(function(d) { return !d.disengaged; });\n                                if (engaged.every(function(series) { return series.userDisabled })) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) {\n                                        series.disabled = series.userDisabled = false;\n                                    });\n                                }\n                            }\n                        }\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled }),\n                            disengaged: data.map(function(d) { return !!d.disengaged })\n                        });\n\n                    }\n                })\n                .on('dblclick', function(d,i) {\n                    if (enableDoubleClick) {\n                        if (vers == 'furious' && expanded) return;\n                        dispatch.legendDblclick(d, i);\n                        if (updateState) {\n                            // make sure we re-get data in case it was modified\n                            var data = series.data();\n                            //the default behavior of NVD3 legends, when double clicking one,\n                            // is to set all other series' to false, and make the double clicked series enabled.\n                            data.forEach(function (series) {\n                                series.disabled = true;\n                                if (vers == 'furious') series.userDisabled = series.disabled;\n                            });\n                            d.disabled = false;\n                            if (vers == 'furious') d.userDisabled = d.disabled;\n                            dispatch.stateChange({\n                                disabled: data.map(function (d) {\n                                    return !!d.disabled\n                                })\n                            });\n                        }\n                    }\n                });\n\n            series.classed('nv-disabled', function(d) { return d.userDisabled });\n            series.exit().remove();\n\n            seriesText\n                .attr('fill', setTextColor)\n                .text(function (d) { return keyFormatter(getKey(d)) });\n\n            //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option)\n            // NEW ALIGNING CODE, TODO: clean up\n            var legendWidth = 0;\n            if (align) {\n\n                var seriesWidths = [];\n                series.each(function(d,i) {\n                    var legendText;\n                    if (keyFormatter(getKey(d)) && keyFormatter(getKey(d)).length > maxKeyLength) {\n                        var trimmedKey = keyFormatter(getKey(d)).substring(0, maxKeyLength);\n                        legendText = d3.select(this).select('text').text(trimmedKey + \"...\");\n                        d3.select(this).append(\"svg:title\").text(keyFormatter(getKey(d)));\n                    } else {\n                        legendText = d3.select(this).select('text');\n                    }\n                    var nodeTextLength;\n                    try {\n                        nodeTextLength = legendText.node().getComputedTextLength();\n                        // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead\n                        if(nodeTextLength <= 0) throw Error();\n                    }\n                    catch(e) {\n                        nodeTextLength = nv.utils.calcApproxTextWidth(legendText);\n                    }\n\n                    seriesWidths.push(nodeTextLength + padding);\n                });\n\n                var seriesPerRow = 0;\n                var columnWidths = [];\n                legendWidth = 0;\n\n                while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {\n                    columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];\n                    legendWidth += seriesWidths[seriesPerRow++];\n                }\n                if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row\n\n                while ( legendWidth > availableWidth && seriesPerRow > 1 ) {\n                    columnWidths = [];\n                    seriesPerRow--;\n\n                    for (var k = 0; k < seriesWidths.length; k++) {\n                        if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )\n                            columnWidths[k % seriesPerRow] = seriesWidths[k];\n                    }\n\n                    legendWidth = columnWidths.reduce(function(prev, cur, index, array) {\n                        return prev + cur;\n                    });\n                }\n\n                var xPositions = [];\n                for (var i = 0, curX = 0; i < seriesPerRow; i++) {\n                    xPositions[i] = curX;\n                    curX += columnWidths[i];\n                }\n\n                series\n                    .attr('transform', function(d, i) {\n                        return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                if (rightAlign) {\n                    g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');\n                }\n                else {\n                    g.attr('transform', 'translate(0' + ',' + margin.top + ')');\n                }\n\n                height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding);\n\n            } else {\n\n                var ypos = 5,\n                    newxpos = 5,\n                    maxwidth = 0,\n                    xpos;\n                series\n                    .attr('transform', function(d, i) {\n                        var length = d3.select(this).select('text').node().getComputedTextLength() + padding;\n                        xpos = newxpos;\n\n                        if (width < margin.left + margin.right + xpos + length) {\n                            newxpos = xpos = 5;\n                            ypos += versPadding;\n                        }\n\n                        newxpos += length;\n                        if (newxpos > maxwidth) maxwidth = newxpos;\n\n                        if(legendWidth < xpos + maxwidth) {\n                            legendWidth = xpos + maxwidth;\n                        }\n                        return 'translate(' + xpos + ',' + ypos + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');\n\n                height = margin.top + margin.bottom + ypos + 15;\n            }\n\n            if(vers == 'furious') {\n                // Size rectangles after text is placed\n                seriesShape\n                    .attr('width', function(d,i) {\n                        return seriesText[0][i].getComputedTextLength() + 27;\n                    })\n                    .attr('height', 18)\n                    .attr('y', -9)\n                    .attr('x', -15);\n\n                // The background for the expanded legend (UI)\n                gEnter.insert('rect',':first-child')\n                    .attr('class', 'nv-legend-bg')\n                    .attr('fill', '#eee')\n                    // .attr('stroke', '#444')\n                    .attr('opacity',0);\n\n                var seriesBG = g.select('.nv-legend-bg');\n\n                seriesBG\n                .transition().duration(300)\n                    .attr('x', -versPadding )\n                    .attr('width', legendWidth + versPadding - 12)\n                    .attr('height', height + 10)\n                    .attr('y', -margin.top - 10)\n                    .attr('opacity', expanded ? 1 : 0);\n\n\n            }\n\n            seriesShape\n                .style('fill', setBGColor)\n                .style('fill-opacity', setBGOpacity)\n                .style('stroke', setBGColor);\n        });\n\n        function setTextColor(d,i) {\n            if(vers != 'furious') return '#000';\n            if(expanded) {\n                return d.disengaged ? '#000' : '#fff';\n            } else if (!expanded) {\n                if(!d.color) d.color = color(d,i);\n                return !!d.disabled ? d.color : '#fff';\n            }\n        }\n\n        function setBGColor(d,i) {\n            if(expanded && vers == 'furious') {\n                return d.disengaged ? '#eee' : d.color || color(d,i);\n            } else {\n                return d.color || color(d,i);\n            }\n        }\n\n\n        function setBGOpacity(d,i) {\n            if(expanded && vers == 'furious') {\n                return 1;\n            } else {\n                return !!d.disabled ? 0 : 1;\n            }\n        }\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:          {get: function(){return width;}, set: function(_){width=_;}},\n        height:         {get: function(){return height;}, set: function(_){height=_;}},\n        key:            {get: function(){return getKey;}, set: function(_){getKey=_;}},\n        keyFormatter:   {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        align:          {get: function(){return align;}, set: function(_){align=_;}},\n        maxKeyLength:   {get: function(){return maxKeyLength;}, set: function(_){maxKeyLength=_;}},\n        rightAlign:     {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}},\n        padding:        {get: function(){return padding;}, set: function(_){padding=_;}},\n        updateState:    {get: function(){return updateState;}, set: function(_){updateState=_;}},\n        enableDoubleClick: {get: function(){return enableDoubleClick;}, set: function(_){enableDoubleClick=_;}},\n        radioButtonMode:{get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}},\n        expanded:       {get: function(){return expanded;}, set: function(_){expanded=_;}},\n        vers:           {get: function(){return vers;}, set: function(_){vers=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.line = function() {\n    \"use strict\";\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var  scatter = nv.models.scatter()\n        ;\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , container = null\n        , strokeWidth = 1.5\n        , color = nv.utils.defaultColor() // a function that returns a color\n        , getX = function(d) { return d.x } // accessor to get the x value from a data point\n        , getY = function(d) { return d.y } // accessor to get the y value from a data point\n        , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined\n        , isArea = function(d) { return d.area } // decides if a line is an area or just a line\n        , clipEdge = false // if true, masks lines within x and y scale\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , interpolate = \"linear\" // controls the line interpolation\n        , duration = 250\n        , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout', 'renderEnd')\n        ;\n\n    scatter\n        .pointSize(16) // default size\n        .pointDomain([16,256]) //set to speed up calculation, needs to be unset if there is a custom size accessor\n    ;\n\n    //============================================================\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0 //used to store previous scales\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        ;\n\n    //============================================================\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-line').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-line');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            scatter\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var scatterWrap = wrap.select('.nv-scatterWrap');\n            scatterWrap.call(scatter);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + scatter.id())\n                .append('rect');\n\n            wrap.select('#nv-edge-clip-' + scatter.id() + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', (availableHeight > 0) ? availableHeight : 0);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : '');\n            scatterWrap\n                .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : '');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('stroke-width', function(d) { return d.strokeWidth || strokeWidth })\n                .style('fill-opacity', 1e-6);\n\n            groups.exit().remove();\n\n            groups\n                .attr('class', function(d,i) {\n                    return (d.classed || '') + ' nv-group nv-series-' + i;\n                })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i)});\n            groups.watchTransition(renderWatch, 'line: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', function(d) { return d.fillOpacity || .5});\n\n            var areaPaths = groups.selectAll('path.nv-area')\n                .data(function(d) { return isArea(d) ? [d] : [] }); // this is done differently than lines because I need to check if series is an area\n            areaPaths.enter().append('path')\n                .attr('class', 'nv-area')\n                .attr('d', function(d) {\n                    return d3.svg.area()\n                        .interpolate(interpolate)\n                        .defined(defined)\n                        .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) })\n                        .y0(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })\n                        .y1(function(d,i) { return y0( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })\n                        //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this\n                        .apply(this, [d.values])\n                });\n            groups.exit().selectAll('path.nv-area')\n                .remove();\n\n            areaPaths.watchTransition(renderWatch, 'line: areaPaths')\n                .attr('d', function(d) {\n                    return d3.svg.area()\n                        .interpolate(interpolate)\n                        .defined(defined)\n                        .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })\n                        .y0(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })\n                        .y1(function(d,i) { return y( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })\n                        //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this\n                        .apply(this, [d.values])\n                });\n\n            var linePaths = groups.selectAll('path.nv-line')\n                .data(function(d) { return [d.values] });\n\n            linePaths.enter().append('path')\n                .attr('class', 'nv-line')\n                .attr('d',\n                    d3.svg.line()\n                    .interpolate(interpolate)\n                    .defined(defined)\n                    .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) })\n                    .y(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })\n            );\n\n            linePaths.watchTransition(renderWatch, 'line: linePaths')\n                .attr('d',\n                    d3.svg.line()\n                    .interpolate(interpolate)\n                    .defined(defined)\n                    .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })\n                    .y(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })\n            );\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n        });\n        renderWatch.renderEnd('line immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    // Pass through events\n    scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); });\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        defined: {get: function(){return defined;}, set: function(_){defined=_;}},\n        interpolate:      {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            scatter.duration(duration);\n        }},\n        isArea: {get: function(){return isArea;}, set: function(_){\n            isArea = d3.functor(_);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            scatter.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            scatter.y(_);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            scatter.color(color);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.lineChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        , focus = nv.models.focus(nv.models.line())\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , useInteractiveGuideline = false\n        , x\n        , y\n        , focusEnable = false\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , duration = 250\n        ;\n\n    // set options on sub-objects for this chart\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient(rightAlignYAxis ? 'right' : 'left');\n\n    lines.clipEdge(true).duration(0);\n\n    tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    interactiveLayer.tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled; })\n            };\n        };\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        };\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(lines);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n            chart.update = function() {\n                if( duration === 0 ) {\n                    container.call( chart );\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled; });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length; }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            /* Update `main' graph on brush update. */\n            focus.dispatch.on(\"onBrush\", function(extent) {\n                onBrush(extent);\n            });\n\n            // Setup Scales\n            x = lines.xScale();\n            y = lines.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-lineChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-lineChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-background').append('rect');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y nv-axis');\n            focusEnter.append('g').attr('class', 'nv-linesWrap');\n            focusEnter.append('g').attr('class', 'nv-interactive');\n\n            var contextEnter = gEnter.append('g').attr('class', 'nv-focusWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (legendPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(0,' + (availableHeight + xAxis.height())  +')');\n                } else if (legendPosition === 'top') {\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                    }\n\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + (-margin.top) +')');\n                }\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            g.select('.nv-focus .nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            lines\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var linesWrap = g.select('.nv-linesWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n\n            // Setup Main (Focus) Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks(nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n            }\n\n            //============================================================\n            // Update Axes\n            //============================================================\n            function updateXAxis() {\n              if(showXAxis) {\n                g.select('.nv-focus .nv-x.nv-axis')\n                  .transition()\n                  .duration(duration)\n                  .call(xAxis)\n                ;\n              }\n            }\n\n            function updateYAxis() {\n              if(showYAxis) {\n                g.select('.nv-focus .nv-y.nv-axis')\n                  .transition()\n                  .duration(duration)\n                  .call(yAxis)\n                ;\n              }\n            }\n\n            g.select('.nv-focus .nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + availableHeight + ')');\n\n            //============================================================\n            // Update Focus\n            //============================================================\n            if (!focusEnable && focus.brush.extent() === null) {\n                linesWrap.transition().call(lines);\n                updateXAxis();\n                updateYAxis();\n            } else {\n                focus.width(availableWidth);\n                g.select('.nv-focusWrap')\n                    .style('display', focusEnable ? 'initial' : 'none')\n                    .attr('transform', 'translate(0,' + ( availableHeight + margin.bottom + focus.margin().top) + ')')\n                    .call(focus);\n                var extent = focus.brush.empty() ? focus.xDomain() : focus.brush.extent();\n                if (extent !== null) {\n                    onBrush(extent);\n                }\n            }\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                lines.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled && !series.disableTooltip;\n                    })\n                    .forEach(function(series,i) {\n                        var extent = focus.brush.extent() !== null ? (focus.brush.empty() ? focus.xScale().domain() : focus.brush.extent()) : x.domain();\n                        var currentValues = series.values.filter(function(d,i) {\n                            // Checks if the x point is between the extents, handling case where extent[0] is greater than extent[1]\n                            // (e.g. x domain is manually set to reverse the x-axis)\n                            if(extent[0] <= extent[1]) {\n                                return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                            } else {\n                                return lines.x()(d,i) >= extent[1] && lines.x()(d,i) <= extent[0];\n                            }\n                        });\n\n                        if (currentValues.length > 0) {\n                            pointIndex = nv.interactiveBisect(currentValues, e.pointXValue, lines.x());\n                            var point = currentValues[pointIndex];\n                            var pointYValue = chart.y()(point, pointIndex);\n                            if (pointYValue !== null) {\n                                lines.highlightPoint(i, series.values.indexOf(point), true);\n                            }\n                            if (point === undefined) return;\n                            if (singlePoint === undefined) singlePoint = point;\n                            if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                            allData.push({\n                                key: series.key,\n                                value: pointYValue,\n                                color: color(series,series.seriesIndex),\n                                data: point\n                            });\n                        }\n                    });\n                //Highlight the tooltip entry based on which point the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);\n                    var threshold = 0.03 * domainExtent;\n                    var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value;}),yValue,threshold);\n                    if (indexToHighlight !== null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                var defaultValueFormatter = function(d,i) {\n                    return d == null ? \"N/A\" : yAxis.tickFormat()(d);\n                };\n\n                if (typeof pointIndex !== 'undefined') {\n                    interactiveLayer.tooltip\n                        .valueFormatter(interactiveLayer.tooltip.valueFormatter() || defaultValueFormatter)\n                        .data({\n                            value: chart.x()( singlePoint,pointIndex ),\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                }\n            });\n\n            interactiveLayer.dispatch.on('elementClick', function(e) {\n                var pointXLocation, allData = [];\n\n                data.filter(function(series, i) {\n                    series.seriesIndex = i;\n                    return !series.disabled;\n                }).forEach(function(series) {\n                    var pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                    var point = series.values[pointIndex];\n                    if (typeof point === 'undefined') return;\n                    if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                    var yPos = chart.yScale()(chart.y()(point,pointIndex));\n                    allData.push({\n                        point: point,\n                        pointIndex: pointIndex,\n                        pos: [pointXLocation, yPos],\n                        seriesIndex: series.seriesIndex,\n                        series: series\n                    });\n                });\n\n                lines.dispatch.elementClick(allData);\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                lines.clearHighlights();\n            });\n\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight / 3;\n                return 'M' + (0.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (0.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n\n            function onBrush(extent) {\n                // Update Main (Focus)\n                var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')\n                    .datum(\n                    data.filter(function(d) { return !d.disabled; })\n                        .map(function(d,i) {\n                            return {\n                                key: d.key,\n                                area: d.area,\n                                classed: d.classed,\n                                values: d.values.filter(function(d,i) {\n                                    return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                                }),\n                                disableTooltip: d.disableTooltip\n                            };\n                        })\n                );\n                focusLinesWrap.transition().duration(duration).call(lines);\n\n                // Update Main (Focus) Axes\n                updateXAxis();\n                updateYAxis();\n            }\n        });\n\n        renderWatch.renderEnd('lineChart immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        if(!evt.series.disableTooltip){\n            tooltip.data(evt).hidden(false);\n        }\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.lines = lines;\n    chart.legend = legend;\n    chart.focus = focus;\n    chart.xAxis = xAxis;\n    chart.x2Axis = focus.xAxis\n    chart.yAxis = yAxis;\n    chart.y2Axis = focus.yAxis\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n    chart.state = state;\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        // Focus options, mostly passed onto focus model.\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:     {get: function(){return focus.height();}, set: function(_){focus.height(_);}},\n        focusShowAxisX:    {get: function(){return focus.showXAxis();}, set: function(_){focus.showXAxis(_);}},\n        focusShowAxisY:    {get: function(){return focus.showYAxis();}, set: function(_){focus.showYAxis(_);}},\n        brushExtent: {get: function(){return focus.brushExtent();}, set: function(_){focus.brushExtent(_);}},\n\n        // options that require extra logic in the setter\n        focusMargin: {get: function(){return focus.margin}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            focus.margin.right  = _.right  !== undefined ? _.right  : focus.margin.right;\n            focus.margin.bottom = _.bottom !== undefined ? _.bottom : focus.margin.bottom;\n            focus.margin.left   = _.left   !== undefined ? _.left   : focus.margin.left;\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            lines.duration(duration);\n            focus.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            lines.color(color);\n            focus.color(color);\n        }},\n        interpolate: {get: function(){return lines.interpolate();}, set: function(_){\n            lines.interpolate(_);\n            focus.interpolate(_);\n        }},\n        xTickFormat: {get: function(){return xAxis.tickFormat();}, set: function(_){\n            xAxis.tickFormat(_);\n            focus.xTickFormat(_);\n        }},\n        yTickFormat: {get: function(){return yAxis.tickFormat();}, set: function(_){\n            yAxis.tickFormat(_);\n            focus.yTickFormat(_);\n        }},\n        x: {get: function(){return lines.x();}, set: function(_){\n            lines.x(_);\n            focus.x(_);\n        }},\n        y: {get: function(){return lines.y();}, set: function(_){\n            lines.y(_);\n            focus.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (useInteractiveGuideline) {\n                lines.interactive(false);\n                lines.useVoronoi(false);\n            }\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.lineWithFocusChart = function() {\n  return nv.models.lineChart()\n    .margin({ bottom: 30 })\n    .focusEnable( true );\n};\nnv.models.linePlusBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , lines2 = nv.models.line()\n        , bars = nv.models.historicalBar()\n        , bars2 = nv.models.historicalBar()\n        , xAxis = nv.models.axis()\n        , x2Axis = nv.models.axis()\n        , y1Axis = nv.models.axis()\n        , y2Axis = nv.models.axis()\n        , y3Axis = nv.models.axis()\n        , y4Axis = nv.models.axis()\n        , legend = nv.models.legend()\n        , brush = d3.svg.brush()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 30, bottom: 30, left: 60}\n        , marginTop = null\n        , margin2 = {top: 0, right: 30, bottom: 20, left: 60}\n        , width = null\n        , height = null\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , color = nv.utils.defaultColor()\n        , showLegend = true\n        , focusEnable = true\n        , focusShowAxisY = false\n        , focusShowAxisX = true\n        , focusHeight = 50\n        , extent\n        , brushExtent = null\n        , x\n        , x2\n        , y1\n        , y2\n        , y3\n        , y4\n        , noData = null\n        , dispatch = d3.dispatch('brush', 'stateChange', 'changeState')\n        , transitionDuration = 0\n        , state = nv.utils.state()\n        , defaultState = null\n        , legendLeftAxisHint = ' (left axis)'\n        , legendRightAxisHint = ' (right axis)'\n        , switchYAxisOrder = false\n        ;\n\n    lines.clipEdge(true);\n    lines2.interactive(false);\n    // We don't want any points emitted for the focus chart's scatter graph.\n    lines2.pointActive(function(d) { return false });\n    xAxis.orient('bottom').tickPadding(5);\n    y1Axis.orient('left');\n    y2Axis.orient('right');\n    x2Axis.orient('bottom').tickPadding(5);\n    y3Axis.orient('left');\n    y4Axis.orient('right');\n\n    tooltip.headerEnabled(true).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var getBarsAxis = function() {\n        return switchYAxisOrder\n            ? { main: y2Axis, focus: y4Axis }\n            : { main: y1Axis, focus: y3Axis }\n    }\n\n    var getLinesAxis = function() {\n        return switchYAxisOrder\n            ? { main: y1Axis, focus: y3Axis }\n            : { main: y2Axis, focus: y4Axis }\n    }\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var allDisabled = function(data) {\n      return data.every(function(series) {\n        return series.disabled;\n      });\n    }\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight1 = nv.utils.availableHeight(height, container, margin)\n                    - (focusEnable ? focusHeight : 0),\n                availableHeight2 = focusHeight - margin2.top - margin2.bottom;\n\n            chart.update = function() { container.transition().duration(transitionDuration).call(chart); };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            var dataBars = data.filter(function(d) { return !d.disabled && d.bar });\n            var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240\n\n            if (dataBars.length && !switchYAxisOrder) {\n                x = bars.xScale();\n            } else {\n                x = lines.xScale();\n            }\n\n            x2 = x2Axis.scale();\n\n            // select the scales and series based on the position of the yAxis\n            y1 = switchYAxisOrder ? lines.yScale() : bars.yScale();\n            y2 = switchYAxisOrder ? bars.yScale() : lines.yScale();\n            y3 = switchYAxisOrder ? lines2.yScale() : bars2.yScale();\n            y4 = switchYAxisOrder ? bars2.yScale() : lines2.yScale();\n\n            var series1 = data\n                .filter(function(d) { return !d.disabled && (switchYAxisOrder ? !d.bar : d.bar) })\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i) }\n                    })\n                });\n\n            var series2 = data\n                .filter(function(d) { return !d.disabled && (switchYAxisOrder ? d.bar : !d.bar) })\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i) }\n                    })\n                });\n\n            x.range([0, availableWidth]);\n\n            x2  .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } ))\n                .range([0, availableWidth]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            // this is the main chart\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            focusEnter.append('g').attr('class', 'nv-barsWrap');\n            focusEnter.append('g').attr('class', 'nv-linesWrap');\n\n            // context chart is where you can focus in\n            var contextEnter = gEnter.append('g').attr('class', 'nv-context');\n            contextEnter.append('g').attr('class', 'nv-x nv-axis');\n            contextEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            contextEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            contextEnter.append('g').attr('class', 'nv-barsWrap');\n            contextEnter.append('g').attr('class', 'nv-linesWrap');\n            contextEnter.append('g').attr('class', 'nv-brushBackground');\n            contextEnter.append('g').attr('class', 'nv-x nv-brush');\n\n            //============================================================\n            // Legend\n            //------------------------------------------------------------\n\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;\n                var legendXPosition = legend.align() ? legendWidth : 0;\n\n                legend.width(legendWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data.map(function(series) {\n                        series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;\n                        if(switchYAxisOrder) {\n                            series.key = series.originalKey + (series.bar ? legendRightAxisHint : legendLeftAxisHint);\n                        } else {\n                            series.key = series.originalKey + (series.bar ? legendLeftAxisHint : legendRightAxisHint);\n                        }\n                        return series;\n                    }))\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    // FIXME: shouldn't this be \"- (focusEnabled ? focusHeight : 0)\"?\n                    availableHeight1 = nv.utils.availableHeight(height, container, margin) - focusHeight;\n                }\n\n                g.select('.nv-legendWrap')\n                    .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            //============================================================\n            // Context chart (focus chart) components\n            //------------------------------------------------------------\n\n            // hide or show the focus context chart\n            g.select('.nv-context').style('display', focusEnable ? 'initial' : 'none');\n\n            bars2\n                .width(availableWidth)\n                .height(availableHeight2)\n                .color(data.map(function (d, i) {\n                    return d.color || color(d, i);\n                }).filter(function (d, i) {\n                    return !data[i].disabled && data[i].bar\n                }));\n            lines2\n                .width(availableWidth)\n                .height(availableHeight2)\n                .color(data.map(function (d, i) {\n                    return d.color || color(d, i);\n                }).filter(function (d, i) {\n                    return !data[i].disabled && !data[i].bar\n                }));\n\n            var bars2Wrap = g.select('.nv-context .nv-barsWrap')\n                .datum(dataBars.length ? dataBars : [\n                    {values: []}\n                ]);\n            var lines2Wrap = g.select('.nv-context .nv-linesWrap')\n                .datum(allDisabled(dataLines) ?\n                       [{values: []}] :\n                       dataLines.filter(function(dataLine) {\n                         return !dataLine.disabled;\n                       }));\n\n            g.select('.nv-context')\n                .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')');\n\n            bars2Wrap.transition().call(bars2);\n            lines2Wrap.transition().call(lines2);\n\n            // context (focus chart) axis controls\n            if (focusShowAxisX) {\n                x2Axis\n                    ._ticks( nv.utils.calcTicksX(availableWidth / 100, data))\n                    .tickSize(-availableHeight2, 0);\n                g.select('.nv-context .nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y3.range()[0] + ')');\n                g.select('.nv-context .nv-x.nv-axis').transition()\n                    .call(x2Axis);\n            }\n\n            if (focusShowAxisY) {\n                y3Axis\n                    .scale(y3)\n                    ._ticks( availableHeight2 / 36 )\n                    .tickSize( -availableWidth, 0);\n                y4Axis\n                    .scale(y4)\n                    ._ticks( availableHeight2 / 36 )\n                    .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none\n\n                g.select('.nv-context .nv-y3.nv-axis')\n                    .style('opacity', dataBars.length ? 1 : 0)\n                    .attr('transform', 'translate(0,' + x2.range()[0] + ')');\n                g.select('.nv-context .nv-y2.nv-axis')\n                    .style('opacity', dataLines.length ? 1 : 0)\n                    .attr('transform', 'translate(' + x2.range()[1] + ',0)');\n\n                g.select('.nv-context .nv-y1.nv-axis').transition()\n                    .call(y3Axis);\n                g.select('.nv-context .nv-y2.nv-axis').transition()\n                    .call(y4Axis);\n            }\n\n            // Setup Brush\n            brush.x(x2).on('brush', onBrush);\n\n            if (brushExtent) brush.extent(brushExtent);\n\n            var brushBG = g.select('.nv-brushBackground').selectAll('g')\n                .data([brushExtent || brush.extent()]);\n\n            var brushBGenter = brushBG.enter()\n                .append('g');\n\n            brushBGenter.append('rect')\n                .attr('class', 'left')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight2);\n\n            brushBGenter.append('rect')\n                .attr('class', 'right')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight2);\n\n            var gBrush = g.select('.nv-x.nv-brush')\n                .call(brush);\n            gBrush.selectAll('rect')\n                //.attr('y', -5)\n                .attr('height', availableHeight2);\n            gBrush.selectAll('.resize').append('path').attr('d', resizePath);\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight2 / 3;\n                return 'M' + (.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n\n\n            function updateBrushBG() {\n                if (!brush.empty()) brush.extent(brushExtent);\n                brushBG\n                    .data([brush.empty() ? x2.domain() : brushExtent])\n                    .each(function(d,i) {\n                        var leftWidth = x2(d[0]) - x2.range()[0],\n                            rightWidth = x2.range()[1] - x2(d[1]);\n                        d3.select(this).select('.left')\n                            .attr('width',  leftWidth < 0 ? 0 : leftWidth);\n\n                        d3.select(this).select('.right')\n                            .attr('x', x2(d[1]))\n                            .attr('width', rightWidth < 0 ? 0 : rightWidth);\n                    });\n            }\n\n            function onBrush() {\n                brushExtent = brush.empty() ? null : brush.extent();\n                extent = brush.empty() ? x2.domain() : brush.extent();\n                dispatch.brush({extent: extent, brush: brush});\n                updateBrushBG();\n\n                // Prepare Main (Focus) Bars and Lines\n                bars\n                    .width(availableWidth)\n                    .height(availableHeight1)\n                    .color(data.map(function(d,i) {\n                        return d.color || color(d, i);\n                    }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));\n\n                lines\n                    .width(availableWidth)\n                    .height(availableHeight1)\n                    .color(data.map(function(d,i) {\n                        return d.color || color(d, i);\n                    }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));\n\n                var focusBarsWrap = g.select('.nv-focus .nv-barsWrap')\n                    .datum(!dataBars.length ? [{values:[]}] :\n                        dataBars\n                            .map(function(d,i) {\n                                return {\n                                    key: d.key,\n                                    values: d.values.filter(function(d,i) {\n                                        return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <= extent[1];\n                                    })\n                                }\n                            })\n                );\n\n                var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')\n                    .datum(allDisabled(dataLines) ? [{values:[]}] :\n                           dataLines\n                           .filter(function(dataLine) { return !dataLine.disabled; })\n                           .map(function(d,i) {\n                                return {\n                                    area: d.area,\n                                    fillOpacity: d.fillOpacity,\n                                    strokeWidth: d.strokeWidth,\n                                    key: d.key,\n                                    values: d.values.filter(function(d,i) {\n                                        return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                                    })\n                                }\n                            })\n                );\n\n                // Update Main (Focus) X Axis\n                if (dataBars.length && !switchYAxisOrder) {\n                    x = bars.xScale();\n                } else {\n                    x = lines.xScale();\n                }\n\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight1, 0);\n\n                xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]);\n\n                g.select('.nv-x.nv-axis').transition().duration(transitionDuration)\n                    .call(xAxis);\n\n                // Update Main (Focus) Bars and Lines\n                focusBarsWrap.transition().duration(transitionDuration).call(bars);\n                focusLinesWrap.transition().duration(transitionDuration).call(lines);\n\n                // Setup and Update Main (Focus) Y Axes\n                g.select('.nv-focus .nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y1.range()[0] + ')');\n\n                y1Axis\n                    .scale(y1)\n                    ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) )\n                    .tickSize(-availableWidth, 0);\n                y2Axis\n                    .scale(y2)\n                    ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) );\n\n                // Show the y2 rules only if y1 has none\n                if(!switchYAxisOrder) {\n                    y2Axis.tickSize(dataBars.length ? 0 : -availableWidth, 0);\n                } else {\n                    y2Axis.tickSize(dataLines.length ? 0 : -availableWidth, 0);\n                }\n\n                // Calculate opacity of the axis\n                var barsOpacity = dataBars.length ? 1 : 0;\n                var linesOpacity = dataLines.length && !allDisabled(dataLines) ? 1 : 0;\n\n                var y1Opacity = switchYAxisOrder ? linesOpacity : barsOpacity;\n                var y2Opacity = switchYAxisOrder ? barsOpacity : linesOpacity;\n\n                g.select('.nv-focus .nv-y1.nv-axis')\n                    .style('opacity', y1Opacity);\n                g.select('.nv-focus .nv-y2.nv-axis')\n                    .style('opacity', y2Opacity)\n                    .attr('transform', 'translate(' + x.range()[1] + ',0)');\n\n                g.select('.nv-focus .nv-y1.nv-axis').transition().duration(transitionDuration)\n                    .call(y1Axis);\n                g.select('.nv-focus .nv-y2.nv-axis').transition().duration(transitionDuration)\n                    .call(y2Axis);\n            }\n\n            onBrush();\n\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip\n            .duration(100)\n            .valueFormatter(function(d, i) {\n                return getLinesAxis().main.tickFormat()(d, i);\n            })\n            .data(evt)\n            .hidden(false);\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n\n    bars.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.value = chart.x()(evt.data);\n        evt['series'] = {\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip\n            .duration(0)\n            .valueFormatter(function(d, i) {\n                return getBarsAxis().main.tickFormat()(d, i);\n            })\n            .data(evt)\n            .hidden(false);\n    });\n\n    bars.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bars.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.legend = legend;\n    chart.lines = lines;\n    chart.lines2 = lines2;\n    chart.bars = bars;\n    chart.bars2 = bars2;\n    chart.xAxis = xAxis;\n    chart.x2Axis = x2Axis;\n    chart.y1Axis = y1Axis;\n    chart.y2Axis = y2Axis;\n    chart.y3Axis = y3Axis;\n    chart.y4Axis = y4Axis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        brushExtent:    {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:    {get: function(){return focusHeight;}, set: function(_){focusHeight=_;}},\n        focusShowAxisX:    {get: function(){return focusShowAxisX;}, set: function(_){focusShowAxisX=_;}},\n        focusShowAxisY:    {get: function(){return focusShowAxisY;}, set: function(_){focusShowAxisY=_;}},\n        legendLeftAxisHint:    {get: function(){return legendLeftAxisHint;}, set: function(_){legendLeftAxisHint=_;}},\n        legendRightAxisHint:    {get: function(){return legendRightAxisHint;}, set: function(_){legendRightAxisHint=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        focusMargin: {get: function(){return margin2;}, set: function(_){\n            margin2.top    = _.top    !== undefined ? _.top    : margin2.top;\n            margin2.right  = _.right  !== undefined ? _.right  : margin2.right;\n            margin2.bottom = _.bottom !== undefined ? _.bottom : margin2.bottom;\n            margin2.left   = _.left   !== undefined ? _.left   : margin2.left;\n        }},\n        duration: {get: function(){return transitionDuration;}, set: function(_){\n            transitionDuration = _;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            lines.x(_);\n            lines2.x(_);\n            bars.x(_);\n            bars2.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            lines.y(_);\n            lines2.y(_);\n            bars.y(_);\n            bars2.y(_);\n        }},\n        switchYAxisOrder:    {get: function(){return switchYAxisOrder;}, set: function(_){\n            // Switch the tick format for the yAxis\n            if(switchYAxisOrder !== _) {\n                var y1 = y1Axis;\n                y1Axis = y2Axis;\n                y2Axis = y1;\n\n                var y3 = y3Axis;\n                y3Axis = y4Axis;\n                y4Axis = y3;\n            }\n            switchYAxisOrder=_;\n\n            y1Axis.orient('left');\n            y2Axis.orient('right');\n            y3Axis.orient('left');\n            y4Axis.orient('right');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.multiBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , clipEdge = true\n        , stacked = false\n        , stackOffset = 'zero' // options include 'silhouette', 'wiggle', 'expand', 'zero', or a custom function\n        , color = nv.utils.defaultColor()\n        , hideable = false\n        , barColor = null // adding the ability to set the color for each rather than the whole group\n        , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled\n        , duration = 500\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , groupSpacing = 0.1\n        , fillOpacity = 0.75\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0 //used to store previous scales\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        ;\n\n    var last_datalength = 0;\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n            var nonStackableCount = 0;\n            // This function defines the requirements for render complete\n            var endFn = function(d, i) {\n                if (d.series === data.length - 1 && i === data[0].values.length - 1)\n                    return true;\n                return false;\n            };\n\n            if(hideable && data.length) hideable = [{\n                values: data[0].values.map(function(d) {\n                        return {\n                            x: d.x,\n                            y: 0,\n                            series: d.series,\n                            size: 0.01\n                        };}\n                )}];\n\n            if (stacked) {\n                var parsed = d3.layout.stack()\n                    .offset(stackOffset)\n                    .values(function(d){ return d.values })\n                    .y(getY)\n                (!data.length && hideable ? hideable : data);\n\n                parsed.forEach(function(series, i){\n                    // if series is non-stackable, use un-parsed data\n                    if (series.nonStackable) {\n                        data[i].nonStackableSeries = nonStackableCount++;\n                        parsed[i] = data[i];\n                    } else {\n                        // don't stack this seires on top of the nonStackable seriees\n                        if (i > 0 && parsed[i - 1].nonStackable){\n                            parsed[i].values.map(function(d,j){\n                                d.y0 -= parsed[i - 1].values[j].y;\n                                d.y1 = d.y0 + d.y;\n                            });\n                        }\n                    }\n                });\n                data = parsed;\n            }\n            //add series index and key to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                    point.key = series.key;\n                });\n            });\n\n            // HACK for negative value stacking\n            if (stacked && data.length > 0) {\n                data[0].values.map(function(d,i) {\n                    var posBase = 0, negBase = 0;\n                    data.map(function(d, idx) {\n                        if (!data[idx].nonStackable) {\n                            var f = d.values[i]\n                            f.size = Math.abs(f.y);\n                            if (f.y<0)  {\n                                f.y1 = negBase;\n                                negBase = negBase - f.size;\n                            } else\n                            {\n                                f.y1 = f.size + posBase;\n                                posBase = posBase + f.size;\n                            }\n                        }\n\n                    });\n                });\n            }\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d, idx) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1, idx:idx }\n                    })\n                });\n\n            x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableWidth], groupSpacing);\n\n            y.domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) {\n                var domain = d.y;\n                // increase the domain range if this series is stackable\n                if (stacked && !data[d.idx].nonStackable) {\n                    if (d.y > 0){\n                        domain = d.y1\n                    } else {\n                        domain = d.y1 + d.y\n                    }\n                }\n                return domain;\n            }).concat(forceY)))\n            .range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multibar').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect');\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d,i) { return i });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n\n            var exitTransition = renderWatch\n                .transition(groups.exit().selectAll('rect.nv-bar'), 'multibarExit', Math.min(100, duration))\n                .attr('y', function(d, i, j) {\n                    var yVal = y0(0) || 0;\n                    if (stacked) {\n                        if (data[d.series] && !data[d.series].nonStackable) {\n                            yVal = y0(d.y0);\n                        }\n                    }\n                    return yVal;\n                })\n                .attr('height', 0)\n                .remove();\n            if (exitTransition.delay)\n                exitTransition.delay(function(d,i) {\n                    var delay = i * (duration / (last_datalength + 1)) - i;\n                    return delay;\n                });\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i) });\n            groups\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', fillOpacity);\n\n            var bars = groups.selectAll('rect.nv-bar')\n                .data(function(d) { return (hideable && !data.length) ? hideable.values : d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('rect')\n                    .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n                    .attr('x', function(d,i,j) {\n                        return stacked && !data[j].nonStackable ? 0 : (j * x.rangeBand() / data.length )\n                    })\n                    .attr('y', function(d,i,j) { return y0(stacked && !data[j].nonStackable ? d.y0 : 0) || 0 })\n                    .attr('height', 0)\n                    .attr('width', function(d,i,j) { return x.rangeBand() / (stacked && !data[j].nonStackable ? 1 : data.length) })\n                    .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })\n                ;\n            bars\n                .style('fill', function(d,i,j){ return color(d, j, i);  })\n                .style('stroke', function(d,i,j){ return color(d, j, i); })\n                .on('mouseover', function(d,i,j) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i,j) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i,j) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i,j) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })\n\n            if (barColor) {\n                if (!disabled) disabled = data.map(function() { return true });\n                bars\n                    .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); })\n                    .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); });\n            }\n\n            var barSelection =\n                bars.watchTransition(renderWatch, 'multibar', Math.min(250, duration))\n                    .delay(function(d,i) {\n                        return i * duration / data[0].values.length;\n                    });\n            if (stacked){\n                barSelection\n                    .attr('y', function(d,i,j) {\n                        var yVal = 0;\n                        // if stackable, stack it on top of the previous series\n                        if (!data[j].nonStackable) {\n                            yVal = y(d.y1);\n                        } else {\n                            if (getY(d,i) < 0){\n                                yVal = y(0);\n                            } else {\n                                if (y(0) - y(getY(d,i)) < -1){\n                                    yVal = y(0) - 1;\n                                } else {\n                                    yVal = y(getY(d, i)) || 0;\n                                }\n                            }\n                        }\n                        return yVal;\n                    })\n                    .attr('height', function(d,i,j) {\n                        if (!data[j].nonStackable) {\n                            return Math.max(Math.abs(y(d.y+d.y0) - y(d.y0)), 0);\n                        } else {\n                            return Math.max(Math.abs(y(getY(d,i)) - y(0)), 0) || 0;\n                        }\n                    })\n                    .attr('x', function(d,i,j) {\n                        var width = 0;\n                        if (data[j].nonStackable) {\n                            width = d.series * x.rangeBand() / data.length;\n                            if (data.length !== nonStackableCount){\n                                width = data[j].nonStackableSeries * x.rangeBand()/(nonStackableCount*2);\n                            }\n                        }\n                        return width;\n                    })\n                    .attr('width', function(d,i,j){\n                        if (!data[j].nonStackable) {\n                            return x.rangeBand();\n                        } else {\n                            // if all series are nonStacable, take the full width\n                            var width = (x.rangeBand() / nonStackableCount);\n                            // otherwise, nonStackable graph will be only taking the half-width\n                            // of the x rangeBand\n                            if (data.length !== nonStackableCount) {\n                                width = x.rangeBand()/(nonStackableCount*2);\n                            }\n                            return width;\n                        }\n                    });\n            }\n            else {\n                barSelection\n                    .attr('x', function(d,i) {\n                        return d.series * x.rangeBand() / data.length;\n                    })\n                    .attr('width', x.rangeBand() / data.length)\n                    .attr('y', function(d,i) {\n                        return getY(d,i) < 0 ?\n                            y(0) :\n                                y(0) - y(getY(d,i)) < 1 ?\n                            y(0) - 1 :\n                            y(getY(d,i)) || 0;\n                    })\n                    .attr('height', function(d,i) {\n                        return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0;\n                    });\n            }\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n            // keep track of the last data value length for transition calculations\n            if (data[0] && data[0].values) {\n                last_datalength = data[0].values.length;\n            }\n\n        });\n\n        renderWatch.renderEnd('multibar immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}},\n        stackOffset: {get: function(){return stackOffset;}, set: function(_){stackOffset=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        disabled:    {get: function(){return disabled;}, set: function(_){disabled=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        hideable:    {get: function(){return hideable;}, set: function(_){hideable=_;}},\n        groupSpacing:{get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}},\n        fillOpacity: {get: function(){return fillOpacity;}, set: function(_){fillOpacity=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        barColor:  {get: function(){return barColor;}, set: function(_){\n            barColor = _ ? nv.utils.getColor(_) : null;\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.multiBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var multibar = nv.models.multiBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , interactiveLayer = nv.interactiveGuideline()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , controlLabels = {}\n        , showLegend = true\n        , legendPosition = null\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , reduceXTicks = true // if false a tick will show for every data point\n        , staggerLabels = false\n        , wrapLabels = false\n        , rotateLabels = 0\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , controlWidth = function() { return showControls ? 180 : 0 }\n        , duration = 250\n        , useInteractiveGuideline = false\n        ;\n\n    state.stacked = false // DEPRECATED Maintained for backward compatibility\n\n    multibar.stacked(false);\n    xAxis\n        .orient('bottom')\n        .tickPadding(7)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .valueFormatter(function(d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .valueFormatter(function (d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function (d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    var stacked = false;\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                stacked: stacked\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.stacked !== undefined)\n                stacked = state.stacked;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(multibar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition()\n                        .duration(duration)\n                        .call(chart);\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = multibar.xScale();\n            y = multibar.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multiBarWithLegend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarWithLegend').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                if (legendPosition === 'bottom') {\n                    legend.width(availableWidth - margin.right);\n\n                     g.select('.nv-legendWrap')\n                         .datum(data)\n                         .call(legend);\n\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(0,' + (availableHeight + xAxis.height())  +')');\n                } else {\n                    legend.width(availableWidth - controlWidth());\n\n                    g.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');\n                }\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },\n                    { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }\n                ];\n\n                controls.width(controlWidth()).color(['#444', '#444', '#444']);\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n                    .call(controls);\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Main Chart Component(s)\n            multibar\n                .disabled(data.map(function(series) { return series.disabled }))\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.call(multibar);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis > g').selectAll('g');\n\n                xTicks\n                    .selectAll('line, text')\n                    .style('opacity', 1)\n\n                if (staggerLabels) {\n                    var getTranslate = function(x,y) {\n                        return \"translate(\" + x + \",\" + y + \")\";\n                    };\n\n                    var staggerUp = 5, staggerDown = 17;  //pixels to stagger by\n                    // Issue #140\n                    xTicks\n                        .selectAll(\"text\")\n                        .attr('transform', function(d,i,j) {\n                            return  getTranslate(0, (j % 2 == 0 ? staggerUp : staggerDown));\n                        });\n\n                    var totalInBetweenTicks = d3.selectAll(\".nv-x.nv-axis .nv-wrap g g text\")[0].length;\n                    g.selectAll(\".nv-x.nv-axis .nv-axisMaxMin text\")\n                        .attr(\"transform\", function(d,i) {\n                            return getTranslate(0, (i === 0 || totalInBetweenTicks % 2 !== 0) ? staggerDown : staggerUp);\n                        });\n                }\n\n                if (wrapLabels) {\n                    g.selectAll('.tick text')\n                        .call(nv.utils.wrapTicks, chart.xAxis.rangeBand())\n                }\n\n                if (reduceXTicks)\n                    xTicks\n                        .filter(function(d,i) {\n                            return i % Math.ceil(data[0].values.length / (availableWidth / 100)) !== 0;\n                        })\n                        .selectAll('text, line')\n                        .style('opacity', 0);\n\n                if(rotateLabels)\n                    xTicks\n                        .selectAll('.tick text')\n                        .attr('transform', 'rotate(' + rotateLabels + ' 0,0)')\n                        .style('text-anchor', rotateLabels > 0 ? 'start' : 'end');\n\n                g.select('.nv-x.nv-axis').selectAll('g.nv-axisMaxMin text')\n                    .style('opacity', 1);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                switch (d.key) {\n                    case 'Grouped':\n                    case controlLabels.grouped:\n                        multibar.stacked(false);\n                        break;\n                    case 'Stacked':\n                    case controlLabels.stacked:\n                        multibar.stacked(true);\n                        break;\n                }\n\n                state.stacked = multibar.stacked();\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                if (typeof e.stacked !== 'undefined') {\n                    multibar.stacked(e.stacked);\n                    state.stacked = e.stacked;\n                    stacked = e.stacked;\n                }\n                chart.update();\n            });\n\n            if (useInteractiveGuideline) {\n                interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                    if (e.pointXValue == undefined) return;\n\n                    var singlePoint, pointIndex, pointXLocation, xValue, allData = [];\n                    data\n                        .filter(function(series, i) {\n                            series.seriesIndex = i;\n                            return !series.disabled;\n                        })\n                        .forEach(function(series,i) {\n                            pointIndex = x.domain().indexOf(e.pointXValue)\n\n                            var point = series.values[pointIndex];\n                            if (point === undefined) return;\n\n                            xValue = point.x;\n                            if (singlePoint === undefined) singlePoint = point;\n                            if (pointXLocation === undefined) pointXLocation = e.mouseX\n                            allData.push({\n                                key: series.key,\n                                value: chart.y()(point, pointIndex),\n                                color: color(series,series.seriesIndex),\n                                data: series.values[pointIndex]\n                            });\n                        });\n\n                    interactiveLayer.tooltip\n                        .data({\n                            value: xValue,\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                });\n\n                interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                    interactiveLayer.tooltip.hidden(true);\n                });\n            }\n            else {\n                multibar.dispatch.on('elementMouseover.tooltip', function(evt) {\n                    evt.value = chart.x()(evt.data);\n                    evt['series'] = {\n                        key: evt.data.key,\n                        value: chart.y()(evt.data),\n                        color: evt.color\n                    };\n                    tooltip.data(evt).hidden(false);\n                });\n\n                multibar.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n\n                multibar.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n            }\n        });\n\n        renderWatch.renderEnd('multibarchart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.multibar = multibar;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.state = state;\n    chart.tooltip = tooltip;\n    chart.interactiveLayer = interactiveLayer;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        reduceXTicks:    {get: function(){return reduceXTicks;}, set: function(_){reduceXTicks=_;}},\n        rotateLabels:    {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        staggerLabels:    {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        wrapLabels:   {get: function(){return wrapLabels;}, set: function(_){wrapLabels=!!_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            multibar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n        }},\n        barColor:  {get: function(){return multibar.barColor;}, set: function(_){\n            multibar.barColor(_);\n            legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();})\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, multibar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.multiBarHorizontal = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getYerr = function(d) { return d.yErr }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , color = nv.utils.defaultColor()\n        , barColor = null // adding the ability to set the color for each rather than the whole group\n        , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled\n        , stacked = false\n        , showValues = false\n        , showBarLabels = false\n        , valuePadding = 60\n        , groupSpacing = 0.1\n        , fillOpacity = 0.75\n        , valueFormat = d3.format(',.2f')\n        , delay = 1200\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , duration = 250\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0; //used to store previous scales\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            if (stacked)\n                data = d3.layout.stack()\n                    .offset('zero')\n                    .values(function(d){ return d.values })\n                    .y(getY)\n                (data);\n\n            //add series index and key to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                    point.key = series.key;\n                });\n            });\n\n            // HACK for negative value stacking\n            if (stacked)\n                data[0].values.map(function(d,i) {\n                    var posBase = 0, negBase = 0;\n                    data.map(function(d) {\n                        var f = d.values[i]\n                        f.size = Math.abs(f.y);\n                        if (f.y<0)  {\n                            f.y1 = negBase - f.size;\n                            negBase = negBase - f.size;\n                        } else\n                        {\n                            f.y1 = posBase;\n                            posBase = posBase + f.size;\n                        }\n                    });\n                });\n\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 }\n                    })\n                });\n\n            x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableHeight], groupSpacing);\n\n            y.domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return stacked ? (d.y > 0 ? d.y1 + d.y : d.y1 ) : d.y }).concat(forceY)))\n\n            if (showValues && !stacked)\n                y.range(yRange || [(y.domain()[0] < 0 ? valuePadding : 0), availableWidth - (y.domain()[1] > 0 ? valuePadding : 0) ]);\n            else\n                y.range(yRange || [0, availableWidth]);\n\n            x0 = x0 || x;\n            y0 = y0 || d3.scale.linear().domain(y.domain()).range([y(0),y(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-multibarHorizontal').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibarHorizontal');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d,i) { return i });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit().watchTransition(renderWatch, 'multibarhorizontal: exit groups')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6)\n                .remove();\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i) });\n            groups.watchTransition(renderWatch, 'multibarhorizontal: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', fillOpacity);\n\n            var bars = groups.selectAll('g.nv-bar')\n                .data(function(d) { return d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('g')\n                .attr('transform', function(d,i,j) {\n                    return 'translate(' + y0(stacked ? d.y0 : 0) + ',' + (stacked ? 0 : (j * x.rangeBand() / data.length ) + x(getX(d,i))) + ')'\n                });\n\n            barsEnter.append('rect')\n                .attr('width', 0)\n                .attr('height', x.rangeBand() / (stacked ? 1 : data.length) )\n\n            bars\n                .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            if (getYerr(data[0],0)) {\n                barsEnter.append('polyline');\n\n                bars.select('polyline')\n                    .attr('fill', 'none')\n                    .attr('points', function(d,i) {\n                        var xerr = getYerr(d,i)\n                            , mid = 0.8 * x.rangeBand() / ((stacked ? 1 : data.length) * 2);\n                        xerr = xerr.length ? xerr : [-Math.abs(xerr), Math.abs(xerr)];\n                        xerr = xerr.map(function(e) { return y(e + ((getY(d,i) < 0) ? 0 : getY(d,i))) - y(0); });\n                        var a = [[xerr[0],-mid], [xerr[0],mid], [xerr[0],0], [xerr[1],0], [xerr[1],-mid], [xerr[1],mid]];\n                        return a.map(function (path) { return path.join(',') }).join(' ');\n                    })\n                    .attr('transform', function(d,i) {\n                        var mid = x.rangeBand() / ((stacked ? 1 : data.length) * 2);\n                        return 'translate(0, ' + mid + ')';\n                    });\n            }\n\n            barsEnter.append('text');\n\n            if (showValues && !stacked) {\n                bars.select('text')\n                    .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' })\n                    .attr('y', x.rangeBand() / (data.length * 2))\n                    .attr('dy', '.32em')\n                    .text(function(d,i) {\n                        var t = valueFormat(getY(d,i))\n                            , yerr = getYerr(d,i);\n                        if (yerr === undefined)\n                            return t;\n                        if (!yerr.length)\n                            return t + '±' + valueFormat(Math.abs(yerr));\n                        return t + '+' + valueFormat(Math.abs(yerr[1])) + '-' + valueFormat(Math.abs(yerr[0]));\n                    });\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .select('text')\n                    .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 : y(getY(d,i)) - y(0) + 4 })\n            } else {\n                bars.selectAll('text').text('');\n            }\n\n            if (showBarLabels && !stacked) {\n                barsEnter.append('text').classed('nv-bar-label',true);\n                bars.select('text.nv-bar-label')\n                    .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'start' : 'end' })\n                    .attr('y', x.rangeBand() / (data.length * 2))\n                    .attr('dy', '.32em')\n                    .text(function(d,i) { return getX(d,i) });\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .select('text.nv-bar-label')\n                    .attr('x', function(d,i) { return getY(d,i) < 0 ? y(0) - y(getY(d,i)) + 4 : -4 });\n            }\n            else {\n                bars.selectAll('text.nv-bar-label').text('');\n            }\n\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n\n            if (barColor) {\n                if (!disabled) disabled = data.map(function() { return true });\n                bars\n                    .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); })\n                    .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); });\n            }\n\n            if (stacked)\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .attr('transform', function(d,i) {\n                        return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) + ')'\n                    })\n                    .select('rect')\n                    .attr('width', function(d,i) {\n                        return Math.abs(y(getY(d,i) + d.y0) - y(d.y0)) || 0\n                    })\n                    .attr('height', x.rangeBand() );\n            else\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .attr('transform', function(d,i) {\n                        //TODO: stacked must be all positive or all negative, not both?\n                        return 'translate(' +\n                            (getY(d,i) < 0 ? y(getY(d,i)) : y(0))\n                            + ',' +\n                            (d.series * x.rangeBand() / data.length\n                                +\n                                x(getX(d,i)) )\n                            + ')'\n                    })\n                    .select('rect')\n                    .attr('height', x.rangeBand() / data.length )\n                    .attr('width', function(d,i) {\n                        return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0\n                    });\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('multibarHorizontal immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        yErr:       {get: function(){return getYerr;}, set: function(_){getYerr=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}},\n        showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}},\n        // this shows the group name, seems pointless?\n        //showBarLabels:    {get: function(){return showBarLabels;}, set: function(_){showBarLabels=_;}},\n        disabled:     {get: function(){return disabled;}, set: function(_){disabled=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n        valueFormat:  {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        valuePadding: {get: function(){return valuePadding;}, set: function(_){valuePadding=_;}},\n        groupSpacing: {get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}},\n        fillOpacity:  {get: function(){return fillOpacity;}, set: function(_){fillOpacity=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        barColor:  {get: function(){return barColor;}, set: function(_){\n            barColor = _ ? nv.utils.getColor(_) : null;\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.multiBarHorizontalChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var multibar = nv.models.multiBarHorizontal()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend().height(30)\n        , controls = nv.models.legend().height(30)\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , controlsPosition = 'top'        \n        , controlLabels = {}\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , stacked = false\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        , controlWidth = function() { return showControls ? 180 : 0 }\n        , duration = 250\n        ;\n\n    state.stacked = false; // DEPRECATED Maintained for backward compatibility\n\n    multibar.stacked(stacked);\n\n    xAxis\n        .orient('left')\n        .tickPadding(5)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient('bottom')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                stacked: stacked\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.stacked !== undefined)\n                stacked = state.stacked;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(multibar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().duration(duration).call(chart) };\n            chart.container = this;\n\n            stacked = multibar.stacked();\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = multibar.xScale();\n            y = multibar.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multiBarHorizontalChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarHorizontalChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth - controlWidth());\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n                if (legendPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(' + controlWidth() + ',' + (availableHeight + xAxis.height())  +')');\n                } else if (legendPosition === 'top') {\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');\n                }                    \n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },\n                    { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }\n                ];\n\n                controls.width(controlWidth()).color(['#444', '#444', '#444']);\n\n                if (controlsPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                    g.select('.nv-controlsWrap')\n                        .datum(controlsData)\n                        .attr('transform', 'translate(0,' + (availableHeight + xAxis.height()) +')')\n                        .call(controls);  \n\n                } else if (controlsPosition === 'top') {\n                    g.select('.nv-controlsWrap')\n                        .datum(controlsData)\n                        .attr('transform', 'translate(0,' + (-margin.top) +')')\n                        .call(controls);                        \n                }\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            multibar\n                .disabled(data.map(function(series) { return series.disabled }))\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.transition().call(multibar);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/24, data) )\n                    .tickSize(-availableWidth, 0);\n\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n\n                xTicks\n                    .selectAll('line, text');\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(0,' + availableHeight + ')');\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select(\".nv-zeroLine line\")\n                .attr(\"x1\", y(0))\n                .attr(\"x2\", y(0))\n                .attr(\"y1\", 0)\n                .attr(\"y2\", -availableHeight)\n            ;\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                switch (d.key) {\n                    case 'Grouped':\n                    case controlLabels.grouped:\n                        multibar.stacked(false);\n                        break;\n                    case 'Stacked':\n                    case controlLabels.stacked:\n                        multibar.stacked(true);\n                        break;\n                }\n\n                state.stacked = multibar.stacked();\n                dispatch.stateChange(state);\n                stacked = multibar.stacked();\n\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.stacked !== 'undefined') {\n                    multibar.stacked(e.stacked);\n                    state.stacked = e.stacked;\n                    stacked = e.stacked;\n                }\n\n                chart.update();\n            });\n        });\n        renderWatch.renderEnd('multibar horizontal chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    multibar.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.value = chart.x()(evt.data);\n        evt['series'] = {\n            key: evt.data.key,\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    multibar.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    multibar.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.multibar = multibar;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.state = state;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        controlsPosition: {get: function(){return controlsPosition;}, set: function(_){controlsPosition=_;}},\n        showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            multibar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        barColor:  {get: function(){return multibar.barColor;}, set: function(_){\n            multibar.barColor(_);\n            legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();})\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, multibar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\nnv.models.multiChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60},\n        marginTop = null,\n        color = nv.utils.defaultColor(),\n        width = null,\n        height = null,\n        showLegend = true,\n        noData = null,\n        yDomain1,\n        yDomain2,\n        getX = function(d) { return d.x },\n        getY = function(d) { return d.y},\n        interpolate = 'linear',\n        useVoronoi = true,\n        interactiveLayer = nv.interactiveGuideline(),\n        useInteractiveGuideline = false,\n        legendRightAxisHint = ' (right axis)',\n        duration = 250\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x = d3.scale.linear(),\n        yScale1 = d3.scale.linear(),\n        yScale2 = d3.scale.linear(),\n\n        lines1 = nv.models.line().yScale(yScale1).duration(duration),\n        lines2 = nv.models.line().yScale(yScale2).duration(duration),\n\n        scatters1 = nv.models.scatter().yScale(yScale1).duration(duration),\n        scatters2 = nv.models.scatter().yScale(yScale2).duration(duration),\n\n        bars1 = nv.models.multiBar().stacked(false).yScale(yScale1).duration(duration),\n        bars2 = nv.models.multiBar().stacked(false).yScale(yScale2).duration(duration),\n\n        stack1 = nv.models.stackedArea().yScale(yScale1).duration(duration),\n        stack2 = nv.models.stackedArea().yScale(yScale2).duration(duration),\n\n        xAxis = nv.models.axis().scale(x).orient('bottom').tickPadding(5).duration(duration),\n        yAxis1 = nv.models.axis().scale(yScale1).orient('left').duration(duration),\n        yAxis2 = nv.models.axis().scale(yScale2).orient('right').duration(duration),\n\n        legend = nv.models.legend().height(30),\n        tooltip = nv.models.tooltip(),\n        dispatch = d3.dispatch();\n\n    var charts = [lines1, lines2, scatters1, scatters2, bars1, bars2, stack1, stack2];\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            chart.update = function() { container.transition().call(chart); };\n            chart.container = this;\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            var dataLines1 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 1});\n            var dataLines2 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 2});\n            var dataScatters1 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 1});\n            var dataScatters2 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 2});\n            var dataBars1 =  data.filter(function(d) {return d.type == 'bar'  && d.yAxis == 1});\n            var dataBars2 =  data.filter(function(d) {return d.type == 'bar'  && d.yAxis == 2});\n            var dataStack1 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 1});\n            var dataStack2 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 2});\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var series1 = data.filter(function(d) {return !d.disabled && d.yAxis == 1})\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d), y: getY(d) }\n                    })\n                });\n\n            var series2 = data.filter(function(d) {return !d.disabled && d.yAxis == 2})\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d), y: getY(d) }\n                    })\n                });\n\n            x   .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x }))\n                .range([0, availableWidth]);\n\n            var wrap = container.selectAll('g.wrap.multiChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3 multiChart').append('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            gEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            gEnter.append('g').attr('class', 'stack1Wrap');\n            gEnter.append('g').attr('class', 'stack2Wrap');\n            gEnter.append('g').attr('class', 'bars1Wrap');\n            gEnter.append('g').attr('class', 'bars2Wrap');\n            gEnter.append('g').attr('class', 'scatters1Wrap');\n            gEnter.append('g').attr('class', 'scatters2Wrap');\n            gEnter.append('g').attr('class', 'lines1Wrap');\n            gEnter.append('g').attr('class', 'lines2Wrap');\n            gEnter.append('g').attr('class', 'legendWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            var g = wrap.select('g');\n\n            var color_array = data.map(function(d,i) {\n                return data[i].color || color(d, i);\n            });\n\n            // Legend\n            if (!showLegend) {\n                g.select('.legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;\n                var legendXPosition = legend.align() ? legendWidth : 0;\n\n                legend.width(legendWidth);\n                legend.color(color_array);\n\n                g.select('.legendWrap')\n                    .datum(data.map(function(series) {\n                        series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;\n                        series.key = series.originalKey + (series.yAxis == 1 ? '' : legendRightAxisHint);\n                        return series;\n                    }))\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                g.select('.legendWrap')\n                    .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')');\n            }\n\n            lines1\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'line'}));\n            lines2\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'line'}));\n            scatters1\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'scatter'}));\n            scatters2\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'scatter'}));\n            bars1\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'bar'}));\n            bars2\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'bar'}));\n            stack1\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'area'}));\n            stack2\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'area'}));\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var lines1Wrap = g.select('.lines1Wrap')\n                .datum(dataLines1.filter(function(d){return !d.disabled}));\n            var scatters1Wrap = g.select('.scatters1Wrap')\n                .datum(dataScatters1.filter(function(d){return !d.disabled}));\n            var bars1Wrap = g.select('.bars1Wrap')\n                .datum(dataBars1.filter(function(d){return !d.disabled}));\n            var stack1Wrap = g.select('.stack1Wrap')\n                .datum(dataStack1.filter(function(d){return !d.disabled}));\n            var lines2Wrap = g.select('.lines2Wrap')\n                .datum(dataLines2.filter(function(d){return !d.disabled}));\n            var scatters2Wrap = g.select('.scatters2Wrap')\n                .datum(dataScatters2.filter(function(d){return !d.disabled}));\n            var bars2Wrap = g.select('.bars2Wrap')\n                .datum(dataBars2.filter(function(d){return !d.disabled}));\n            var stack2Wrap = g.select('.stack2Wrap')\n                .datum(dataStack2.filter(function(d){return !d.disabled}));\n\n            var extraValue1BarStacked = [];\n            if (bars1.stacked() && dataBars1.length) {\n                var extraValue1BarStacked = dataBars1.filter(function(d){return !d.disabled}).map(function(a){return a.values});\n                \n                if (extraValue1BarStacked.length > 0)\n                    extraValue1BarStacked = extraValue1BarStacked.reduce(function(a,b){\n                        return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})\n                    });\n            }\n            if (dataBars1.length) {\n                extraValue1BarStacked.push({x:0, y:0});\n            }\n            \n            var extraValue2BarStacked = [];\n            if (bars2.stacked() && dataBars2.length) {\n                var extraValue2BarStacked = dataBars2.filter(function(d){return !d.disabled}).map(function(a){return a.values});\n                \n                if (extraValue2BarStacked.length > 0)\n                    extraValue2BarStacked = extraValue2BarStacked.reduce(function(a,b){\n                        return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})\n                    });\n            }\n            if (dataBars2.length) {\n                extraValue2BarStacked.push({x:0, y:0});\n            }\n            \n            yScale1 .domain(yDomain1 || d3.extent(d3.merge(series1).concat(extraValue1BarStacked), function(d) { return d.y } ))\n                .range([0, availableHeight]);\n\n            yScale2 .domain(yDomain2 || d3.extent(d3.merge(series2).concat(extraValue2BarStacked), function(d) { return d.y } ))\n                .range([0, availableHeight]);\n\n            lines1.yDomain(yScale1.domain());\n            scatters1.yDomain(yScale1.domain());\n            bars1.yDomain(yScale1.domain());\n            stack1.yDomain(yScale1.domain());\n\n            lines2.yDomain(yScale2.domain());\n            scatters2.yDomain(yScale2.domain());\n            bars2.yDomain(yScale2.domain());\n            stack2.yDomain(yScale2.domain());\n\n            if(dataStack1.length){d3.transition(stack1Wrap).call(stack1);}\n            if(dataStack2.length){d3.transition(stack2Wrap).call(stack2);}\n\n            if(dataBars1.length){d3.transition(bars1Wrap).call(bars1);}\n            if(dataBars2.length){d3.transition(bars2Wrap).call(bars2);}\n\n            if(dataLines1.length){d3.transition(lines1Wrap).call(lines1);}\n            if(dataLines2.length){d3.transition(lines2Wrap).call(lines2);}\n\n            if(dataScatters1.length){d3.transition(scatters1Wrap).call(scatters1);}\n            if(dataScatters2.length){d3.transition(scatters2Wrap).call(scatters2);}\n\n            xAxis\n                ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                .tickSize(-availableHeight, 0);\n\n            g.select('.nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + availableHeight + ')');\n            d3.transition(g.select('.nv-x.nv-axis'))\n                .call(xAxis);\n\n            yAxis1\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n\n            d3.transition(g.select('.nv-y1.nv-axis'))\n                .call(yAxis1);\n\n            yAxis2\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n            d3.transition(g.select('.nv-y2.nv-axis'))\n                .call(yAxis2);\n\n            g.select('.nv-y1.nv-axis')\n                .classed('nv-disabled', series1.length ? false : true)\n                .attr('transform', 'translate(' + x.range()[0] + ',0)');\n\n            g.select('.nv-y2.nv-axis')\n                .classed('nv-disabled', series2.length ? false : true)\n                .attr('transform', 'translate(' + x.range()[1] + ',0)');\n\n            legend.dispatch.on('stateChange', function(newState) {\n                chart.update();\n            });\n\n            if(useInteractiveGuideline){\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching\n            //------------------------------------------------------------\n\n            function mouseover_line(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.value = evt.point.x;\n                evt.series = {\n                    value: evt.point.y,\n                    color: evt.point.color,\n                    key: evt.series.key\n                };\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_scatter(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.value = evt.point.x;\n                evt.series = {\n                    value: evt.point.y,\n                    color: evt.point.color,\n                    key: evt.series.key\n                };\n                tooltip\n                    .duration(100)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_stack(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.point['x'] = stack1.x()(evt.point);\n                evt.point['y'] = stack1.y()(evt.point);\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_bar(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n\n                evt.value = bars1.x()(evt.data);\n                evt['series'] = {\n                    value: bars1.y()(evt.data),\n                    color: evt.color,\n                    key: evt.data.key\n                };\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n\n\n            function clearHighlights() {\n              for(var i=0, il=charts.length; i < il; i++){\n                var chart = charts[i];\n                try {\n                  chart.clearHighlights();\n                } catch(e){}\n              }\n            }\n\n            function highlightPoint(serieIndex, pointIndex, b){\n              for(var i=0, il=charts.length; i < il; i++){\n                var chart = charts[i];\n                try {\n                  chart.highlightPoint(serieIndex, pointIndex, b);\n                } catch(e){}\n              }\n            }\n\n            if(useInteractiveGuideline){\n                interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                    clearHighlights();\n                    var singlePoint, pointIndex, pointXLocation, allData = [];\n                    data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series,i) {\n                        var extent = x.domain();\n                        var currentValues = series.values.filter(function(d,i) {\n                            return chart.x()(d,i) >= extent[0] && chart.x()(d,i) <= extent[1];\n                        });\n\n                        pointIndex = nv.interactiveBisect(currentValues, e.pointXValue, chart.x());\n                        var point = currentValues[pointIndex];\n                        var pointYValue = chart.y()(point, pointIndex);\n                        if (pointYValue !== null) {\n                            highlightPoint(i, pointIndex, true);\n                        }\n                        if (point === undefined) return;\n                        if (singlePoint === undefined) singlePoint = point;\n                        if (pointXLocation === undefined) pointXLocation = x(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: pointYValue,\n                            color: color(series,series.seriesIndex),\n                            data: point,\n                            yAxis: series.yAxis == 2 ? yAxis2 : yAxis1\n                        });\n                    });\n\n                    var defaultValueFormatter = function(d,i) {\n                        var yAxis = allData[i].yAxis;\n                        return d == null ? \"N/A\" : yAxis.tickFormat()(d);\n                    };\n\n                    interactiveLayer.tooltip\n                        .headerFormatter(function(d, i) {\n                            return xAxis.tickFormat()(d, i);\n                        })\n                        .valueFormatter(interactiveLayer.tooltip.valueFormatter() || defaultValueFormatter)\n                        .data({\n                            value: chart.x()( singlePoint,pointIndex ),\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                });\n\n                interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                    clearHighlights();\n                });\n            } else {\n                lines1.dispatch.on('elementMouseover.tooltip', mouseover_line);\n                lines2.dispatch.on('elementMouseover.tooltip', mouseover_line);\n                lines1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                lines2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                scatters1.dispatch.on('elementMouseover.tooltip', mouseover_scatter);\n                scatters2.dispatch.on('elementMouseover.tooltip', mouseover_scatter);\n                scatters1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                scatters2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                stack1.dispatch.on('elementMouseover.tooltip', mouseover_stack);\n                stack2.dispatch.on('elementMouseover.tooltip', mouseover_stack);\n                stack1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                stack2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                bars1.dispatch.on('elementMouseover.tooltip', mouseover_bar);\n                bars2.dispatch.on('elementMouseover.tooltip', mouseover_bar);\n\n                bars1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n                bars2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n                bars1.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n                bars2.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n            }\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Global getters and setters\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.legend = legend;\n    chart.lines1 = lines1;\n    chart.lines2 = lines2;\n    chart.scatters1 = scatters1;\n    chart.scatters2 = scatters2;\n    chart.bars1 = bars1;\n    chart.bars2 = bars2;\n    chart.stack1 = stack1;\n    chart.stack2 = stack2;\n    chart.xAxis = xAxis;\n    chart.yAxis1 = yAxis1;\n    chart.yAxis2 = yAxis2;\n    chart.tooltip = tooltip;\n    chart.interactiveLayer = interactiveLayer;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        xScale: {get: function(){return x;}, set: function(_){ x = _; xAxis.scale(x); }},\n        yDomain1:      {get: function(){return yDomain1;}, set: function(_){yDomain1=_;}},\n        yDomain2:    {get: function(){return yDomain2;}, set: function(_){yDomain2=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        interpolate:    {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n        legendRightAxisHint:    {get: function(){return legendRightAxisHint;}, set: function(_){legendRightAxisHint=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            lines1.x(_);\n            lines2.x(_);\n            scatters1.x(_);\n            scatters2.x(_);\n            bars1.x(_);\n            bars2.x(_);\n            stack1.x(_);\n            stack2.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            lines1.y(_);\n            lines2.y(_);\n            scatters1.y(_);\n            scatters2.y(_);\n            stack1.y(_);\n            stack2.y(_);\n            bars1.y(_);\n            bars2.y(_);\n        }},\n        useVoronoi: {get: function(){return useVoronoi;}, set: function(_){\n            useVoronoi=_;\n            lines1.useVoronoi(_);\n            lines2.useVoronoi(_);\n            stack1.useVoronoi(_);\n            stack2.useVoronoi(_);\n        }},\n\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (useInteractiveGuideline) {\n                lines1.interactive(false);\n                lines1.useVoronoi(false);\n                lines2.interactive(false);\n                lines2.useVoronoi(false);\n                stack1.interactive(false);\n                stack1.useVoronoi(false);\n                stack2.interactive(false);\n                stack2.useVoronoi(false);\n                scatters1.interactive(false);\n                scatters2.interactive(false);\n            }\n        }},\n\n        duration: {get: function(){return duration;}, set: function(_) {\n            duration = _;\n            [lines1, lines2, stack1, stack2, scatters1, scatters2, xAxis, yAxis1, yAxis2].forEach(function(model){\n              model.duration(duration);\n            });\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.ohlcBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getOpen = function(d) { return d.open }\n        , getClose = function(d) { return d.close }\n        , getHigh = function(d) { return d.high }\n        , getLow = function(d) { return d.low }\n        , forceX = []\n        , forceY = []\n        , padData     = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , interactive = false\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // ohlc bar width.\n            var w = (availableWidth / data[0].values.length) * .9;\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [5 + w/2, availableWidth - w/2 - 5]);\n\n            y.domain(yDomain || [\n                    d3.min(data[0].values.map(getLow).concat(forceY)),\n                    d3.max(data[0].values.map(getHigh).concat(forceY))\n                ]\n            ).range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-ohlcBar').data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-ohlcBar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-ticks');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')\n                .data(function(d) { return d });\n            ticks.exit().remove();\n\n            ticks.enter().append('path')\n                .attr('class', function(d,i,j) { return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i })\n                .attr('d', function(d,i) {\n                    return 'm0,0l0,'\n                        + (y(getOpen(d,i))\n                            - y(getHigh(d,i)))\n                        + 'l'\n                        + (-w/2)\n                        + ',0l'\n                        + (w/2)\n                        + ',0l0,'\n                        + (y(getLow(d,i)) - y(getOpen(d,i)))\n                        + 'l0,'\n                        + (y(getClose(d,i))\n                            - y(getLow(d,i)))\n                        + 'l'\n                        + (w/2)\n                        + ',0l'\n                        + (-w/2)\n                        + ',0z';\n                })\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })\n                .attr('fill', function(d,i) { return color[0]; })\n                .attr('stroke', function(d,i) { return color[0]; })\n                .attr('x', 0 )\n                .attr('y', function(d,i) {  return y(Math.max(0, getY(d,i))) })\n                .attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) });\n\n            // the bar colors are controlled by CSS currently\n            ticks.attr('class', function(d,i,j) {\n                return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i;\n            });\n\n            d3.transition(ticks)\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })\n                .attr('d', function(d,i) {\n                    var w = (availableWidth / data[0].values.length) * .9;\n                    return 'm0,0l0,'\n                        + (y(getOpen(d,i))\n                            - y(getHigh(d,i)))\n                        + 'l'\n                        + (-w/2)\n                        + ',0l'\n                        + (w/2)\n                        + ',0l0,'\n                        + (y(getLow(d,i))\n                            - y(getOpen(d,i)))\n                        + 'l0,'\n                        + (y(getClose(d,i))\n                            - y(getLow(d,i)))\n                        + 'l'\n                        + (w/2)\n                        + ',0l'\n                        + (-w/2)\n                        + ',0z';\n                });\n        });\n\n        return chart;\n    }\n\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        chart.clearHighlights();\n        container.select(\".nv-ohlcBar .nv-tick-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container.select(\".nv-ohlcBar .nv-tick.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:   {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:   {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:   {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:   {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:   {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceX:   {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:   {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData:  {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:       {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        x:     {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:     {get: function(){return getY;}, set: function(_){getY=_;}},\n        open:  {get: function(){return getOpen();}, set: function(_){getOpen=_;}},\n        close: {get: function(){return getClose();}, set: function(_){getClose=_;}},\n        high:  {get: function(){return getHigh;}, set: function(_){getHigh=_;}},\n        low:   {get: function(){return getLow;}, set: function(_){getLow=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n// Code adapted from Jason Davies' \"Parallel Coordinates\"\n// http://bl.ocks.org/jasondavies/1341281\nnv.models.parallelCoordinates = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 30, right: 0, bottom: 10, left: 0}\n        , width = null\n        , height = null\n        , availableWidth = null\n        , availableHeight = null\n        , x = d3.scale.ordinal()\n        , y = {}\n        , undefinedValuesLabel = \"undefined values\"\n        , dimensionData = []\n        , enabledDimensions = []\n        , dimensionNames = []\n        , displayBrush = true\n        , color = nv.utils.defaultColor()\n        , filters = []\n        , active = []\n        , dragging = []\n        , axisWithUndefinedValues = []\n        , lineTension = 1\n        , foreground\n        , background\n        , dimensions\n        , line = d3.svg.line()\n        , axis = d3.svg.axis()\n        , dispatch = d3.dispatch('brushstart', 'brush', 'brushEnd', 'dimensionsOrder', \"stateChange\", 'elementClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd', 'activeChanged')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var container = d3.select(this);\n            availableWidth = nv.utils.availableWidth(width, container, margin);\n            availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n           //Convert old data to new format (name, values)\n            if (data[0].values === undefined) {\n                var newData = [];\n                data.forEach(function (d) {\n                        var val = {};\n                        var key = Object.keys(d);\n                        key.forEach(function (k) { if (k !== \"name\") val[k] = d[k] });\n                        newData.push({ key: d.name, values: val });\n                });\n                data = newData;\n            }\n\n            var dataValues = data.map(function (d) {return d.values});\n            if (active.length === 0) {\n                active = data;\n            }; //set all active before first brush call\n            \n            dimensionNames = dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; }).map(function (d) { return d.key });\n            enabledDimensions = dimensionData.filter(function (d) { return !d.disabled; });\n            \n            // Setup Scales\n            x.rangePoints([0, availableWidth], 1).domain(enabledDimensions.map(function (d) { return d.key; }));\n\n            //Set as true if all values on an axis are missing.\n            // Extract the list of dimensions and create a scale for each.\n            var oldDomainMaxValue = {};\n            var displayMissingValuesline = false;\n            var currentTicks = [];\n            \n            dimensionNames.forEach(function(d) {\n                var extent = d3.extent(dataValues, function (p) { return +p[d]; });\n                var min = extent[0];\n                var max = extent[1];\n                var onlyUndefinedValues = false;\n                //If there is no values to display on an axis, set the extent to 0\n                if (isNaN(min) || isNaN(max)) {\n                    onlyUndefinedValues = true;\n                    min = 0;\n                    max = 0;\n                }\n                //Scale axis if there is only one value\n                if (min === max) {\n                    min = min - 1;\n                    max = max + 1;\n                }\n                var f = filters.filter(function (k) { return k.dimension == d; });\n                if (f.length !== 0) {\n                    //If there is only NaN values, keep the existing domain.\n                    if (onlyUndefinedValues) {\n                        min = y[d].domain()[0];\n                        max = y[d].domain()[1];\n                    }\n                        //If the brush extent is > max (< min), keep the extent value.\n                    else if (!f[0].hasOnlyNaN && displayBrush) {\n                        min = min > f[0].extent[0] ? f[0].extent[0] : min;\n                        max = max < f[0].extent[1] ? f[0].extent[1] : max;\n                    }\n                        //If there is NaN values brushed be sure the brush extent is on the domain.\n                    else if (f[0].hasNaN) {\n                        max = max < f[0].extent[1] ? f[0].extent[1] : max;\n                        oldDomainMaxValue[d] = y[d].domain()[1];\n                        displayMissingValuesline = true;\n                    }\n                }\n                //Use 90% of (availableHeight - 12) for the axis range, 12 reprensenting the space necessary to display \"undefined values\" text.\n                //The remaining 10% are used to display the missingValue line.\n                y[d] = d3.scale.linear()\n                    .domain([min, max])\n                    .range([(availableHeight - 12) * 0.9, 0]);\n\n                axisWithUndefinedValues = [];\n                y[d].brush = d3.svg.brush().y(y[d]).on('brushstart', brushstart).on('brush', brush).on('brushend', brushend);\n            });\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-parallelCoordinates').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-parallelCoordinates');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates background');\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates foreground');\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates missingValuesline');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            line.interpolate('cardinal').tension(lineTension);\n            axis.orient('left');\n            var axisDrag = d3.behavior.drag()\n                        .on('dragstart', dragStart)\n                        .on('drag', dragMove)\n                        .on('dragend', dragEnd);\n\n            //Add missing value line at the bottom of the chart\n            var missingValuesline, missingValueslineText;\n            var step = x.range()[1] - x.range()[0];\n            step = isNaN(step) ? x.range()[0] : step;\n            if (!isNaN(step)) {\n                var lineData = [0 + step / 2, availableHeight - 12, availableWidth - step / 2, availableHeight - 12];\n                missingValuesline = wrap.select('.missingValuesline').selectAll('line').data([lineData]);\n                missingValuesline.enter().append('line');\n                missingValuesline.exit().remove();\n                missingValuesline.attr(\"x1\", function(d) { return d[0]; })\n                        .attr(\"y1\", function(d) { return d[1]; })\n                        .attr(\"x2\", function(d) { return d[2]; })\n                        .attr(\"y2\", function(d) { return d[3]; });\n    \n                //Add the text \"undefined values\" under the missing value line\n                missingValueslineText = wrap.select('.missingValuesline').selectAll('text').data([undefinedValuesLabel]);\n                missingValueslineText.append('text').data([undefinedValuesLabel]);\n                missingValueslineText.enter().append('text');\n                missingValueslineText.exit().remove();\n                missingValueslineText.attr(\"y\", availableHeight)\n                        //To have the text right align with the missingValues line, substract 92 representing the text size.\n                        .attr(\"x\", availableWidth - 92 - step / 2)\n                        .text(function(d) { return d; });\n            }\n            // Add grey background lines for context.\n            background = wrap.select('.background').selectAll('path').data(data);\n            background.enter().append('path');\n            background.exit().remove();\n            background.attr('d', path);\n\n            // Add blue foreground lines for focus.\n            foreground = wrap.select('.foreground').selectAll('path').data(data);\n            foreground.enter().append('path')\n            foreground.exit().remove();\n            foreground.attr('d', path)\n                .style(\"stroke-width\", function (d, i) {\n                if (isNaN(d.strokeWidth)) { d.strokeWidth = 1;} return d.strokeWidth;})\n                .attr('stroke', function (d, i) { return d.color || color(d, i); });\n            foreground.on(\"mouseover\", function (d, i) {\n                d3.select(this).classed('hover', true).style(\"stroke-width\", d.strokeWidth + 2 + \"px\").style(\"stroke-opacity\", 1);\n                dispatch.elementMouseover({\n                    label: d.name,\n                    color: d.color || color(d, i),\n                    values: d.values,\n                    dimensions: enabledDimensions\n                });\n\n            });\n            foreground.on(\"mouseout\", function (d, i) {\n                d3.select(this).classed('hover', false).style(\"stroke-width\", d.strokeWidth + \"px\").style(\"stroke-opacity\", 0.7);\n                dispatch.elementMouseout({\n                    label: d.name,\n                    index: i\n                });\n            });\n            foreground.on('mousemove', function (d, i) {\n                dispatch.elementMousemove();\n            });\n            foreground.on('click', function (d) {\n                dispatch.elementClick({\n                    id: d.id\n                });\n            });\n            // Add a group element for each dimension.\n            dimensions = g.selectAll('.dimension').data(enabledDimensions);\n            var dimensionsEnter = dimensions.enter().append('g').attr('class', 'nv-parallelCoordinates dimension');\n\n            dimensions.attr('transform', function(d) { return 'translate(' + x(d.key) + ',0)'; });\n            dimensionsEnter.append('g').attr('class', 'nv-axis');\n\n            // Add an axis and title.\n            dimensionsEnter.append('text')\n                .attr('class', 'nv-label')\n                .style(\"cursor\", \"move\")\n                .attr('dy', '-1em')\n                .attr('text-anchor', 'middle')\n                .on(\"mouseover\", function(d, i) {\n                    dispatch.elementMouseover({\n                        label: d.tooltip || d.key,\n                        color: d.color \n                    });\n                })\n                .on(\"mouseout\", function(d, i) {\n                    dispatch.elementMouseout({\n                        label: d.tooltip\n                    });\n                })\n                .on('mousemove', function (d, i) {\n                    dispatch.elementMousemove();\n                })\n                .call(axisDrag);\n\n            dimensionsEnter.append('g').attr('class', 'nv-brushBackground');\n            dimensions.exit().remove();\n            dimensions.select('.nv-label').text(function (d) { return d.key });\n\n            // Add and store a brush for each axis.\n            restoreBrush(displayBrush);\n\n            var actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); }),\n                    extents = actives.map(function (p) { return y[p].brush.extent(); });\n            var formerActive = active.slice(0);\n\n            //Restore active values\n            active = [];\n            foreground.style(\"display\", function (d) {\n                var isActive = actives.every(function (p, i) {\n                    if ((isNaN(d.values[p]) || isNaN(parseFloat(d.values[p]))) && extents[i][0] == y[p].brush.y().domain()[0]) {\n                        return true;\n                    }\n                    return (extents[i][0] <= d.values[p] && d.values[p] <= extents[i][1]) && !isNaN(parseFloat(d.values[p]));\n                });\n                if (isActive)\n                    active.push(d);\n                return !isActive ? \"none\" : null;\n\n            });\n\n            if (filters.length > 0 || !nv.utils.arrayEquals(active, formerActive)) {\n               dispatch.activeChanged(active);\n            }\n\n            // Returns the path for a given data point.\n            function path(d) {\n                return line(enabledDimensions.map(function (p) {\n                    //If value if missing, put the value on the missing value line\n                    if (isNaN(d.values[p.key]) || isNaN(parseFloat(d.values[p.key])) || displayMissingValuesline) {\n                        var domain = y[p.key].domain();\n                        var range = y[p.key].range();\n                        var min = domain[0] - (domain[1] - domain[0]) / 9;\n\n                        //If it's not already the case, allow brush to select undefined values\n                        if (axisWithUndefinedValues.indexOf(p.key) < 0) {\n\n                            var newscale = d3.scale.linear().domain([min, domain[1]]).range([availableHeight - 12, range[1]]);\n                            y[p.key].brush.y(newscale);\n                            axisWithUndefinedValues.push(p.key);\n                        }\n                        if (isNaN(d.values[p.key]) || isNaN(parseFloat(d.values[p.key]))) {\n                            return [x(p.key), y[p.key](min)];\n                        }\n                    }\n\n                    //If parallelCoordinate contain missing values show the missing values line otherwise, hide it.\n                    if (missingValuesline !== undefined) {\n                        if (axisWithUndefinedValues.length > 0 || displayMissingValuesline) {\n                            missingValuesline.style(\"display\", \"inline\");\n                            missingValueslineText.style(\"display\", \"inline\");\n                        } else {\n                            missingValuesline.style(\"display\", \"none\");\n                            missingValueslineText.style(\"display\", \"none\");\n                        }\n                    }\n                    return [x(p.key), y[p.key](d.values[p.key])];\n                }));\n            }\n\n            function restoreBrush(visible) {\n                filters.forEach(function (f) {\n                    //If filter brushed NaN values, keep the brush on the bottom of the axis.\n                    var brushDomain = y[f.dimension].brush.y().domain();\n                    if (f.hasOnlyNaN) {\n                        f.extent[1] = (y[f.dimension].domain()[1] - brushDomain[0]) * (f.extent[1] - f.extent[0]) / (oldDomainMaxValue[f.dimension] - f.extent[0]) + brushDomain[0];\n                    }\n                    if (f.hasNaN) {\n                        f.extent[0] = brushDomain[0];\n                    }\n                    if (visible)\n                        y[f.dimension].brush.extent(f.extent);\n                });\n                \n                dimensions.select('.nv-brushBackground')\n                    .each(function (d) {\n                        d3.select(this).call(y[d.key].brush);\n\n                    })\n                    .selectAll('rect')\n                    .attr('x', -8)\n                    .attr('width', 16);\n                \n                updateTicks();\n            }\n            \n            // Handles a brush event, toggling the display of foreground lines.\n            function brushstart() {\n                //If brush aren't visible, show it before brushing again.\n                if (displayBrush === false) {\n                    displayBrush = true;\n                    restoreBrush(true);\n                }\n            }\n            \n            // Handles a brush event, toggling the display of foreground lines.\n            function brush() {\n                actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); });\n                extents = actives.map(function(p) { return y[p].brush.extent(); });\n\n                filters = []; //erase current filters\n                actives.forEach(function(d,i) {\n                    filters[i] = {\n                        dimension: d,\n                        extent: extents[i],\n                        hasNaN: false,\n                        hasOnlyNaN: false\n                    }\n                });\n\n                active = []; //erase current active list\n                foreground.style('display', function(d) {\n                    var isActive = actives.every(function(p, i) {\n                        if ((isNaN(d.values[p]) || isNaN(parseFloat(d.values[p]))) && extents[i][0] == y[p].brush.y().domain()[0]) return true;\n                        return (extents[i][0] <= d.values[p] && d.values[p] <= extents[i][1]) && !isNaN(parseFloat(d.values[p]));\n                    });\n                    if (isActive) active.push(d);\n                    return isActive ? null : 'none';\n                });\n                \n                updateTicks();\n                \n                dispatch.brush({\n                    filters: filters,\n                    active: active\n                });\n            }\n            function brushend() {\n                var hasActiveBrush = actives.length > 0 ? true : false;\n                filters.forEach(function (f) {\n                    if (f.extent[0] === y[f.dimension].brush.y().domain()[0] && axisWithUndefinedValues.indexOf(f.dimension) >= 0)\n                        f.hasNaN = true;\n                    if (f.extent[1] < y[f.dimension].domain()[0])\n                        f.hasOnlyNaN = true;\n                });\n                dispatch.brushEnd(active, hasActiveBrush);\n            }           \n            function updateTicks() {\n                dimensions.select('.nv-axis')\n                    .each(function (d, i) {\n                        var f = filters.filter(function (k) { return k.dimension == d.key; });\n                        currentTicks[d.key] = y[d.key].domain();\n                        \n                        //If brush are available, display brush extent\n                        if (f.length != 0 && displayBrush)\n                        {\n                            currentTicks[d.key] = [];\n                            if (f[0].extent[1] > y[d.key].domain()[0]) \n                                currentTicks[d.key] = [f[0].extent[1]];\n                            if (f[0].extent[0] >= y[d.key].domain()[0])\n                                currentTicks[d.key].push(f[0].extent[0]);    \n                        }\n                            \n                        d3.select(this).call(axis.scale(y[d.key]).tickFormat(d.format).tickValues(currentTicks[d.key]));\n                });\n            }\n            function dragStart(d) {\n                dragging[d.key] = this.parentNode.__origin__ = x(d.key);\n                background.attr(\"visibility\", \"hidden\");\n            }\n            function dragMove(d) {\n                dragging[d.key] = Math.min(availableWidth, Math.max(0, this.parentNode.__origin__ += d3.event.x));\n                foreground.attr(\"d\", path);\n                enabledDimensions.sort(function (a, b) { return dimensionPosition(a.key) - dimensionPosition(b.key); });\n                enabledDimensions.forEach(function (d, i) { return d.currentPosition = i; });\n                x.domain(enabledDimensions.map(function (d) { return d.key; }));\n                dimensions.attr(\"transform\", function(d) { return \"translate(\" + dimensionPosition(d.key) + \")\"; });\n            }\n            function dragEnd(d, i) {\n                delete this.parentNode.__origin__;\n                delete dragging[d.key];\n                d3.select(this.parentNode).attr(\"transform\", \"translate(\" + x(d.key) + \")\");\n                foreground\n                  .attr(\"d\", path);\n                background\n                  .attr(\"d\", path)\n                  .attr(\"visibility\", null);\n\n                dispatch.dimensionsOrder(enabledDimensions);\n            }\n            function dimensionPosition(d) {\n                var v = dragging[d];\n                return v == null ? x(d) : v;\n            }\n        });\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:         {get: function(){return width;},           set: function(_){width= _;}},\n        height:        {get: function(){return height;},          set: function(_){height= _;}},\n        dimensionData: { get: function () { return dimensionData; }, set: function (_) { dimensionData = _; } },\n        displayBrush: { get: function () { return displayBrush; }, set: function (_) { displayBrush = _; } },\n        filters: { get: function () { return filters; }, set: function (_) { filters = _; } },\n        active: { get: function () { return active; }, set: function (_) { active = _; } },\n        lineTension:   {get: function(){return lineTension;},     set: function(_){lineTension = _;}},\n        undefinedValuesLabel : {get: function(){return undefinedValuesLabel;}, set: function(_){undefinedValuesLabel=_;}},\n        \n        // deprecated options\n        dimensions: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensions', 'use dimensionData instead');\n            if (dimensionData.length === 0) {\n                _.forEach(function (k) { dimensionData.push({ key: k }) })\n            } else {\n                _.forEach(function (k, i) { dimensionData[i].key= k })\n            }\n        }},\n        dimensionNames: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensionNames', 'use dimensionData instead');\n            dimensionNames = [];\n            if (dimensionData.length === 0) {\n                _.forEach(function (k) { dimensionData.push({ key: k }) })\n            } else {\n                _.forEach(function (k, i) { dimensionData[i].key = k })\n            }\n \n        }},\n        dimensionFormats: {get: function () { return dimensionData.map(function (d) { return d.format }); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensionFormats', 'use dimensionData instead');\n            if (dimensionData.length === 0) {\n                _.forEach(function (f) { dimensionData.push({ format: f }) })\n            } else {\n                _.forEach(function (f, i) { dimensionData[i].format = f })\n            }\n\n        }},\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    =  _.top    !== undefined ? _.top    : margin.top;\n            margin.right  =  _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom =  _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   =  _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n    nv.utils.initOptions(chart);\n    return chart;\n};\nnv.models.parallelCoordinatesChart = function () {\n        \"use strict\";\n        //============================================================\n        // Public Variables with Default Settings\n        //------------------------------------------------------------\n\n        var parallelCoordinates = nv.models.parallelCoordinates()\n        var legend = nv.models.legend()\n        var tooltip = nv.models.tooltip();\n        var dimensionTooltip = nv.models.tooltip();\n\n        var margin = { top: 0, right: 0, bottom: 0, left: 0 }\n        , marginTop = null\n        , width = null\n        , height = null\n        , showLegend = true\n        , color = nv.utils.defaultColor()\n        , state = nv.utils.state()\n        , dimensionData = []\n        , displayBrush = true\n        , defaultState = null\n        , noData = null\n        , nanValue = \"undefined\"\n        , dispatch = d3.dispatch('dimensionsOrder', 'brushEnd', 'stateChange', 'changeState', 'renderEnd')\n        , controlWidth = function () { return showControls ? 180 : 0 }\n        ;\n\n\t    //============================================================\n\n\t\t//============================================================\n        // Private Variables\n        //------------------------------------------------------------\n\n        var renderWatch = nv.utils.renderWatch(dispatch);\n\n        var stateGetter = function(data) {\n            return function() {\n                return {\n                    active: data.map(function(d) { return !d.disabled })\n                };\n            }\n        };\n\n        var stateSetter = function(data) {\n            return function(state) {\n                if(state.active !== undefined) {\n                    data.forEach(function(series, i) {\n                        series.disabled = !state.active[i];\n                    });\n                }\n            }\n        };\n\n        tooltip.contentGenerator(function(data) {\n            var str = '<table><thead><tr><td class=\"legend-color-guide\"><div style=\"background-color:' + data.color + '\"></div></td><td><strong>' + data.key + '</strong></td></tr></thead>';\n            if(data.series.length !== 0)\n            {\n                str = str + '<tbody><tr><td height =\"10px\"></td></tr>';\n                data.series.forEach(function(d){\n                    str = str + '<tr><td class=\"legend-color-guide\"><div style=\"background-color:' + d.color + '\"></div></td><td class=\"key\">' + d.key + '</td><td class=\"value\">' + d.value + '</td></tr>';\n                });\n                str = str + '</tbody>';\n            }\n            str = str + '</table>';\n            return str;\n        });\n\n        //============================================================\n        // Chart function\n        //------------------------------------------------------------\n\n        function chart(selection) {\n            renderWatch.reset();\n            renderWatch.models(parallelCoordinates);\n\n            selection.each(function(data) {\n                var container = d3.select(this);\n                nv.utils.initSVG(container);\n\n                var that = this;\n\n                var availableWidth = nv.utils.availableWidth(width, container, margin),\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n\n                chart.update = function() { container.call(chart); };\n                chart.container = this;\n\n                state.setter(stateSetter(dimensionData), chart.update)\n                    .getter(stateGetter(dimensionData))\n                    .update();\n\n                //set state.disabled\n                state.disabled = dimensionData.map(function (d) { return !!d.disabled });\n\n                //Keep dimensions position in memory\n                dimensionData = dimensionData.map(function (d) {d.disabled = !!d.disabled; return d});\n                dimensionData.forEach(function (d, i) {\n                    d.originalPosition = isNaN(d.originalPosition) ? i : d.originalPosition;\n                    d.currentPosition = isNaN(d.currentPosition) ? i : d.currentPosition;\n                });\n\n               if (!defaultState) {\n                    var key;\n                    defaultState = {};\n                    for(key in state) {\n                        if(state[key] instanceof Array)\n                            defaultState[key] = state[key].slice(0);\n                        else\n                            defaultState[key] = state[key];\n                    }\n                }\n\n                // Display No Data message if there's nothing to show.\n                if(!data || !data.length) {\n                    nv.utils.noData(chart, container);\n                    return chart;\n                } else {\n                    container.selectAll('.nv-noData').remove();\n                }\n\n                //------------------------------------------------------------\n                // Setup containers and skeleton of chart\n\n                var wrap = container.selectAll('g.nv-wrap.nv-parallelCoordinatesChart').data([data]);\n                var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-parallelCoordinatesChart').append('g');\n\n                var g = wrap.select('g');\n\n                gEnter.append('g').attr('class', 'nv-parallelCoordinatesWrap');\n                gEnter.append('g').attr('class', 'nv-legendWrap');\n\n                g.select(\"rect\")\n                    .attr(\"width\", availableWidth)\n                    .attr(\"height\", (availableHeight > 0) ? availableHeight : 0);\n\n                // Legend\n                if (!showLegend) {\n                    g.select('.nv-legendWrap').selectAll('*').remove();\n                } else {\n                    legend.width(availableWidth)\n                        .color(function (d) { return \"rgb(188,190,192)\"; });\n\n                    g.select('.nv-legendWrap')\n                        .datum(dimensionData.sort(function (a, b) { return a.originalPosition - b.originalPosition; }))\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n                    wrap.select('.nv-legendWrap')\n                       .attr('transform', 'translate( 0 ,' + (-margin.top) + ')');\n                }\n                wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n                // Main Chart Component(s)\n                parallelCoordinates\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .dimensionData(dimensionData)\n                    .displayBrush(displayBrush);\n\n\t\t        var parallelCoordinatesWrap = g.select('.nv-parallelCoordinatesWrap ')\n                  .datum(data);\n\n\t\t        parallelCoordinatesWrap.transition().call(parallelCoordinates);\n\n\t\t\t\t//============================================================\n                // Event Handling/Dispatching (in chart's scope)\n                //------------------------------------------------------------\n                //Display reset brush button\n\t\t        parallelCoordinates.dispatch.on('brushEnd', function (active, hasActiveBrush) {\n\t\t            if (hasActiveBrush) {\n\t\t                displayBrush = true;\n\t\t                dispatch.brushEnd(active);\n\t\t            } else {\n\n\t\t                displayBrush = false;\n\t\t            }\n\t\t        });\n\n\t\t        legend.dispatch.on('stateChange', function(newState) {\n\t\t            for(var key in newState) {\n\t\t                state[key] = newState[key];\n\t\t            }\n\t\t            dispatch.stateChange(state);\n\t\t            chart.update();\n\t\t        });\n\n                //Update dimensions order and display reset sorting button\n\t\t        parallelCoordinates.dispatch.on('dimensionsOrder', function (e) {\n\t\t            dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; });\n\t\t            var isSorted = false;\n\t\t            dimensionData.forEach(function (d, i) {\n\t\t                d.currentPosition = i;\n\t\t                if (d.currentPosition !== d.originalPosition)\n\t\t                    isSorted = true;\n\t\t            });\n\t\t            dispatch.dimensionsOrder(dimensionData, isSorted);\n\t\t        });\n\n\t\t\t\t// Update chart from a state object passed to event handler\n                dispatch.on('changeState', function (e) {\n\n                    if (typeof e.disabled !== 'undefined') {\n                        dimensionData.forEach(function (series, i) {\n                            series.disabled = e.disabled[i];\n                        });\n                        state.disabled = e.disabled;\n                    }\n                    chart.update();\n                });\n            });\n\n            renderWatch.renderEnd('parraleleCoordinateChart immediate');\n            return chart;\n        }\n\n\t\t//============================================================\n        // Event Handling/Dispatching (out of chart's scope)\n        //------------------------------------------------------------\n\n        parallelCoordinates.dispatch.on('elementMouseover.tooltip', function (evt) {\n            var tp = {\n                key: evt.label,\n                color: evt.color,\n                series: []\n             }\n            if(evt.values){\n                Object.keys(evt.values).forEach(function (d) {\n                    var dim = evt.dimensions.filter(function (dd) {return dd.key === d;})[0];\n                    if(dim){\n                        var v;\n                        if (isNaN(evt.values[d]) || isNaN(parseFloat(evt.values[d]))) {\n                            v = nanValue;\n                        } else {\n                            v = dim.format(evt.values[d]);\n                        }\n                        tp.series.push({ idx: dim.currentPosition, key: d, value: v, color: dim.color });\n                    }\n                });\n                tp.series.sort(function(a,b) {return a.idx - b.idx});\n             }\n            tooltip.data(tp).hidden(false);\n        });\n\n        parallelCoordinates.dispatch.on('elementMouseout.tooltip', function(evt) {\n            tooltip.hidden(true)\n        });\n\n        parallelCoordinates.dispatch.on('elementMousemove.tooltip', function () {\n            tooltip();\n        });\n\t\t //============================================================\n        // Expose Public Variables\n        //------------------------------------------------------------\n\n\t\t// expose chart's sub-components\n        chart.dispatch = dispatch;\n        chart.parallelCoordinates = parallelCoordinates;\n        chart.legend = legend;\n        chart.tooltip = tooltip;\n        chart.options = nv.utils.optionsFunc.bind(chart);\n\n        chart._options = Object.create({}, {\n            // simple options, just get/set the necessary values\n            width: { get: function () { return width; }, set: function (_) { width = _; } },\n            height: { get: function () { return height; }, set: function (_) { height = _; } },\n            showLegend: { get: function () { return showLegend; }, set: function (_) { showLegend = _; } },\n            defaultState: { get: function () { return defaultState; }, set: function (_) { defaultState = _; } },\n            dimensionData: { get: function () { return dimensionData; }, set: function (_) { dimensionData = _; } },\n            displayBrush: { get: function () { return displayBrush; }, set: function (_) { displayBrush = _; } },\n            noData: { get: function () { return noData; }, set: function (_) { noData = _; } },\n            nanValue: { get: function () { return nanValue; }, set: function (_) { nanValue = _; } },\n\n            // options that require extra logic in the setter\n            margin: {\n                get: function () { return margin; },\n                set: function (_) {\n                    if (_.top !== undefined) {\n                        margin.top = _.top;\n                        marginTop = _.top;\n                    }\n                    margin.right = _.right !== undefined ? _.right : margin.right;\n                    margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n                    margin.left = _.left !== undefined ? _.left : margin.left;\n                }\n            },\n            color: {get: function(){return color;}, set: function(_){\n                    color = nv.utils.getColor(_);\n                    legend.color(color);\n                    parallelCoordinates.color(color);\n                }}\n        });\n\n        nv.utils.inheritOptions(chart, parallelCoordinates);\n        nv.utils.initOptions(chart);\n\n        return chart;\n    };\nnv.models.pie = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 500\n        , height = 500\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , color = nv.utils.defaultColor()\n        , valueFormat = d3.format(',.2f')\n        , showLabels = true\n        , labelsOutside = false\n        , labelType = \"key\"\n        , labelThreshold = .02 //if slice percentage is under this, don't show label\n        , hideOverlapLabels = false //Hide labels that don't fit in slice\n        , donut = false\n        , title = false\n        , growOnHover = true\n        , titleOffset = 0\n        , labelSunbeamLayout = false\n        , startAngle = false\n        , padAngle = false\n        , endAngle = false\n        , cornerRadius = 0\n        , donutRatio = 0.5\n        , duration = 250\n        , arcsRadius = []\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    var arcs = [];\n    var arcsOver = [];\n\n    //============================================================\n    // chart function\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right\n                , availableHeight = height - margin.top - margin.bottom\n                , radius = Math.min(availableWidth, availableHeight) / 2\n                , arcsRadiusOuter = []\n                , arcsRadiusInner = []\n                ;\n\n            container = d3.select(this)\n            if (arcsRadius.length === 0) {\n                var outer = radius - radius / 10;\n                var inner = donutRatio * radius;\n                for (var i = 0; i < data[0].length; i++) {\n                    arcsRadiusOuter.push(outer);\n                    arcsRadiusInner.push(inner);\n                }\n            } else {\n                if(growOnHover){\n                    arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer / 10) * radius; });\n                    arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner / 10) * radius; });\n                    donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner / 10); }));\n                } else {\n                    arcsRadiusOuter = arcsRadius.map(function (d) { return d.outer * radius; });\n                    arcsRadiusInner = arcsRadius.map(function (d) { return d.inner * radius; });\n                    donutRatio = d3.min(arcsRadius.map(function (d) { return d.inner; }));\n                }\n            }\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('.nv-wrap.nv-pie').data(data);\n            var wrapEnter = wrap.enter().append('g').attr('class','nvd3 nv-wrap nv-pie nv-chart-' + id);\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n            var g_pie = gEnter.append('g').attr('class', 'nv-pie');\n            gEnter.append('g').attr('class', 'nv-pieLabels');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            g.select('.nv-pie').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');\n            g.select('.nv-pieLabels').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');\n\n            //\n            container.on('click', function(d,i) {\n                dispatch.chartClick({\n                    data: d,\n                    index: i,\n                    pos: d3.event,\n                    id: id\n                });\n            });\n\n            arcs = [];\n            arcsOver = [];\n            for (var i = 0; i < data[0].length; i++) {\n\n                var arc = d3.svg.arc().outerRadius(arcsRadiusOuter[i]);\n                var arcOver = d3.svg.arc().outerRadius(arcsRadiusOuter[i] + 5);\n\n                if (startAngle !== false) {\n                    arc.startAngle(startAngle);\n                    arcOver.startAngle(startAngle);\n                }\n                if (endAngle !== false) {\n                    arc.endAngle(endAngle);\n                    arcOver.endAngle(endAngle);\n                }\n                if (donut) {\n                    arc.innerRadius(arcsRadiusInner[i]);\n                    arcOver.innerRadius(arcsRadiusInner[i]);\n                }\n\n                if (arc.cornerRadius && cornerRadius) {\n                    arc.cornerRadius(cornerRadius);\n                    arcOver.cornerRadius(cornerRadius);\n                }\n\n                arcs.push(arc);\n                arcsOver.push(arcOver);\n            }\n\n            // Setup the Pie chart and choose the data element\n            var pie = d3.layout.pie()\n                .sort(null)\n                .value(function(d) { return d.disabled ? 0 : getY(d) });\n\n            // padAngle added in d3 3.5\n            if (pie.padAngle && padAngle) {\n                pie.padAngle(padAngle);\n            }\n\n            // if title is specified and donut, put it in the middle\n            if (donut && title) {\n                g_pie.append(\"text\").attr('class', 'nv-pie-title');\n\n                wrap.select('.nv-pie-title')\n                    .style(\"text-anchor\", \"middle\")\n                    .text(function (d) {\n                        return title;\n                    })\n                    .style(\"font-size\", (Math.min(availableWidth, availableHeight)) * donutRatio * 2 / (title.length + 2) + \"px\")\n                    .attr(\"dy\", \"0.35em\") // trick to vertically center text\n                    .attr('transform', function(d, i) {\n                        return 'translate(0, '+ titleOffset + ')';\n                    });\n            }\n\n            var slices = wrap.select('.nv-pie').selectAll('.nv-slice').data(pie);\n            var pieLabels = wrap.select('.nv-pieLabels').selectAll('.nv-label').data(pie);\n\n            slices.exit().remove();\n            pieLabels.exit().remove();\n\n            var ae = slices.enter().append('g');\n            ae.attr('class', 'nv-slice');\n            ae.on('mouseover', function(d, i) {\n                d3.select(this).classed('hover', true);\n                if (growOnHover) {\n                    d3.select(this).select(\"path\").transition()\n                        .duration(70)\n                        .attr(\"d\", arcsOver[i]);\n                }\n                dispatch.elementMouseover({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\"),\n                    percent: (d.endAngle - d.startAngle) / (2 * Math.PI)\n                });\n            });\n            ae.on('mouseout', function(d, i) {\n                d3.select(this).classed('hover', false);\n                if (growOnHover) {\n                    d3.select(this).select(\"path\").transition()\n                        .duration(50)\n                        .attr(\"d\", arcs[i]);\n                }\n                dispatch.elementMouseout({data: d.data, index: i});\n            });\n            ae.on('mousemove', function(d, i) {\n                dispatch.elementMousemove({data: d.data, index: i});\n            });\n            ae.on('click', function(d, i) {\n                var element = this;\n                dispatch.elementClick({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\"),\n                    event: d3.event,\n                    element: element\n                });\n            });\n            ae.on('dblclick', function(d, i) {\n                dispatch.elementDblClick({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\")\n                });\n            });\n\n            slices.attr('fill', function(d,i) { return color(d.data, i); });\n            slices.attr('stroke', function(d,i) { return color(d.data, i); });\n\n            var paths = ae.append('path').each(function(d) {\n                this._current = d;\n            });\n\n            slices.select('path')\n                .transition()\n                .duration(duration)\n                .attr('d', function (d, i) { return arcs[i](d); })\n                .attrTween('d', arcTween);\n\n            if (showLabels) {\n                // This does the normal label\n                var labelsArc = [];\n                for (var i = 0; i < data[0].length; i++) {\n                    labelsArc.push(arcs[i]);\n\n                    if (labelsOutside) {\n                        if (donut) {\n                            labelsArc[i] = d3.svg.arc().outerRadius(arcs[i].outerRadius());\n                            if (startAngle !== false) labelsArc[i].startAngle(startAngle);\n                            if (endAngle !== false) labelsArc[i].endAngle(endAngle);\n                        }\n                    } else if (!donut) {\n                            labelsArc[i].innerRadius(0);\n                    }\n                }\n\n                pieLabels.enter().append(\"g\").classed(\"nv-label\",true).each(function(d,i) {\n                    var group = d3.select(this);\n\n                    group.attr('transform', function (d, i) {\n                        if (labelSunbeamLayout) {\n                            d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate\n                            d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate\n                            var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);\n                            if ((d.startAngle + d.endAngle) / 2 < Math.PI) {\n                                rotateAngle -= 90;\n                            } else {\n                                rotateAngle += 90;\n                            }\n                            return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')';\n                        } else {\n                            d.outerRadius = radius + 10; // Set Outer Coordinate\n                            d.innerRadius = radius + 15; // Set Inner Coordinate\n                            return 'translate(' + labelsArc[i].centroid(d) + ')'\n                        }\n                    });\n\n                    group.append('rect')\n                        .style('stroke', '#fff')\n                        .style('fill', '#fff')\n                        .attr(\"rx\", 3)\n                        .attr(\"ry\", 3);\n\n                    group.append('text')\n                        .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned\n                        .style('fill', '#000')\n                });\n\n                var labelLocationHash = {};\n                var avgHeight = 14;\n                var avgWidth = 140;\n                var createHashKey = function(coordinates) {\n                    return Math.floor(coordinates[0]/avgWidth) * avgWidth + ',' + Math.floor(coordinates[1]/avgHeight) * avgHeight;\n                };\n                var getSlicePercentage = function(d) {\n                    return (d.endAngle - d.startAngle) / (2 * Math.PI);\n                };\n\n                pieLabels.watchTransition(renderWatch, 'pie labels').attr('transform', function (d, i) {\n                    if (labelSunbeamLayout) {\n                        d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate\n                        d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate\n                        var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);\n                        if ((d.startAngle + d.endAngle) / 2 < Math.PI) {\n                            rotateAngle -= 90;\n                        } else {\n                            rotateAngle += 90;\n                        }\n                        return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')';\n                    } else {\n                        d.outerRadius = radius + 10; // Set Outer Coordinate\n                        d.innerRadius = radius + 15; // Set Inner Coordinate\n\n                        /*\n                        Overlapping pie labels are not good. What this attempts to do is, prevent overlapping.\n                        Each label location is hashed, and if a hash collision occurs, we assume an overlap.\n                        Adjust the label's y-position to remove the overlap.\n                        */\n                        var center = labelsArc[i].centroid(d);\n                        var percent = getSlicePercentage(d);\n                        if (d.value && percent >= labelThreshold) {\n                            var hashKey = createHashKey(center);\n                            if (labelLocationHash[hashKey]) {\n                                center[1] -= avgHeight;\n                            }\n                            labelLocationHash[createHashKey(center)] = true;\n                        }\n                        return 'translate(' + center + ')'\n                    }\n                });\n\n                pieLabels.select(\".nv-label text\")\n                    .style('text-anchor', function(d,i) {\n                        //center the text on it's origin or begin/end if orthogonal aligned\n                        return labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle';\n                    })\n                    .text(function(d, i) {\n                        var percent = getSlicePercentage(d);\n                        var label = '';\n                        if (!d.value || percent < labelThreshold) return '';\n\n                        if(typeof labelType === 'function') {\n                            label = labelType(d, i, {\n                                'key': getX(d.data),\n                                'value': getY(d.data),\n                                'percent': valueFormat(percent)\n                            });\n                        } else {\n                            switch (labelType) {\n                                case 'key':\n                                    label = getX(d.data);\n                                    break;\n                                case 'value':\n                                    label = valueFormat(getY(d.data));\n                                    break;\n                                case 'percent':\n                                    label = d3.format('%')(percent);\n                                    break;\n                            }\n                        }\n                        return label;\n                    })\n                ;\n\n                if (hideOverlapLabels) {\n                    pieLabels\n                        .each(function (d, i) {\n                            if (!this.getBBox) return;\n                            var bb = this.getBBox(),\n                            center = labelsArc[i].centroid(d);\n                            var topLeft = {\n                              x : center[0] + bb.x,\n                              y : center[1] + bb.y\n                            };\n\n                            var topRight = {\n                              x : topLeft.x + bb.width,\n                              y : topLeft.y\n                            };\n\n                            var bottomLeft = {\n                              x : topLeft.x,\n                              y : topLeft.y + bb.height\n                            };\n\n                            var bottomRight = {\n                              x : topLeft.x + bb.width,\n                              y : topLeft.y + bb.height\n                            };\n\n                            d.visible = nv.utils.pointIsInArc(topLeft, d, arc) &&\n                            nv.utils.pointIsInArc(topRight, d, arc) &&\n                            nv.utils.pointIsInArc(bottomLeft, d, arc) &&\n                            nv.utils.pointIsInArc(bottomRight, d, arc);\n                        })\n                        .style('display', function (d) {\n                            return d.visible ? null : 'none';\n                        })\n                    ;\n                }\n\n            }\n\n\n            // Computes the angle of an arc, converting from radians to degrees.\n            function angle(d) {\n                var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;\n                return a > 90 ? a - 180 : a;\n            }\n\n            function arcTween(a, idx) {\n                a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle;\n                a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle;\n                if (!donut) a.innerRadius = 0;\n                var i = d3.interpolate(this._current, a);\n                this._current = i(0);\n                return function (t) {\n                    return arcs[idx](i(t));\n                };\n            }\n        });\n\n        renderWatch.renderEnd('pie immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        arcsRadius: { get: function () { return arcsRadius; }, set: function (_) { arcsRadius = _; } },\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}},\n        title:      {get: function(){return title;}, set: function(_){title=_;}},\n        titleOffset:    {get: function(){return titleOffset;}, set: function(_){titleOffset=_;}},\n        labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_;}},\n        hideOverlapLabels: {get: function(){return hideOverlapLabels;}, set: function(_){hideOverlapLabels=_;}},\n        valueFormat:    {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        x:          {get: function(){return getX;}, set: function(_){getX=_;}},\n        id:         {get: function(){return id;}, set: function(_){id=_;}},\n        endAngle:   {get: function(){return endAngle;}, set: function(_){endAngle=_;}},\n        startAngle: {get: function(){return startAngle;}, set: function(_){startAngle=_;}},\n        padAngle:   {get: function(){return padAngle;}, set: function(_){padAngle=_;}},\n        cornerRadius: {get: function(){return cornerRadius;}, set: function(_){cornerRadius=_;}},\n        donutRatio:   {get: function(){return donutRatio;}, set: function(_){donutRatio=_;}},\n        labelsOutside: {get: function(){return labelsOutside;}, set: function(_){labelsOutside=_;}},\n        labelSunbeamLayout: {get: function(){return labelSunbeamLayout;}, set: function(_){labelSunbeamLayout=_;}},\n        donut:              {get: function(){return donut;}, set: function(_){donut=_;}},\n        growOnHover:        {get: function(){return growOnHover;}, set: function(_){growOnHover=_;}},\n\n        // depreciated after 1.7.1\n        pieLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){\n            labelsOutside=_;\n            nv.deprecated('pieLabelsOutside', 'use labelsOutside instead');\n        }},\n        // depreciated after 1.7.1\n        donutLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){\n            labelsOutside=_;\n            nv.deprecated('donutLabelsOutside', 'use labelsOutside instead');\n        }},\n        // deprecated after 1.7.1\n        labelFormat: {get: function(){ return valueFormat;}, set: function(_) {\n            valueFormat=_;\n            nv.deprecated('labelFormat','use valueFormat instead');\n        }},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n            margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;\n            margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;\n            margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY=d3.functor(_);\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color=nv.utils.getColor(_);\n        }},\n        labelType:          {get: function(){return labelType;}, set: function(_){\n            labelType= _ || 'key';\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\nnv.models.pieChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var pie = nv.models.pie();\n    var legend = nv.models.legend();\n    var tooltip = nv.models.tooltip();\n\n    var margin = {top: 30, right: 20, bottom: 20, left: 20}\n        , marginTop = null\n        , width = null\n        , height = null\n        , showTooltipPercent = false\n        , showLegend = true\n        , legendPosition = \"top\"\n        , color = nv.utils.defaultColor()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , duration = 250\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return pie.valueFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined) {\n                data.forEach(function (series, i) {\n                    series.disabled = !state.active[i];\n                });\n            }\n        }\n    };\n\n    //============================================================\n    // Chart function\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(pie);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var that = this;\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().call(chart); };\n            chart.container = this;\n\n            state.setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            //set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-pieChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-pieChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-pieWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                if (legendPosition === \"top\") {\n                    legend.width( availableWidth ).key(pie.x());\n\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + (-margin.top) +')');\n                } else if (legendPosition === \"right\") {\n                    var legendWidth = nv.models.legend().width();\n                    if (availableWidth / 2 < legendWidth) {\n                        legendWidth = (availableWidth / 2)\n                    }\n                    legend.height(availableHeight).key(pie.x());\n                    legend.width(legendWidth);\n                    availableWidth -= legend.width();\n\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend)\n                        .attr('transform', 'translate(' + (availableWidth) +',0)');\n                } else if (legendPosition === \"bottom\") {\n                    legend.width( availableWidth ).key(pie.x());\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    margin.bottom = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + availableHeight +')');\n                }\n            }\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            pie.width(availableWidth).height(availableHeight);\n            var pieWrap = g.select('.nv-pieWrap').datum([data]);\n            d3.transition(pieWrap).call(pie);\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState) {\n                    state[key] = newState[key];\n                }\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n        });\n\n        renderWatch.renderEnd('pieChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    pie.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color,\n            percent: evt.percent\n        };\n        if (!showTooltipPercent) {\n            delete evt.percent;\n            delete evt.series.percent;\n        }\n        tooltip.data(evt).hidden(false);\n    });\n\n    pie.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    pie.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.legend = legend;\n    chart.dispatch = dispatch;\n    chart.pie = pie;\n    chart.tooltip = tooltip;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // use Object get/set functionality to map between vars and chart functions\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:              {get: function(){return width;},                set: function(_){width=_;}},\n        height:             {get: function(){return height;},               set: function(_){height=_;}},\n        noData:             {get: function(){return noData;},               set: function(_){noData=_;}},\n        showTooltipPercent: {get: function(){return showTooltipPercent;},   set: function(_){showTooltipPercent=_;}},\n        showLegend:         {get: function(){return showLegend;},           set: function(_){showLegend=_;}},\n        legendPosition:     {get: function(){return legendPosition;},       set: function(_){legendPosition=_;}},\n        defaultState:       {get: function(){return defaultState;},         set: function(_){defaultState=_;}},\n\n        // options that require extra logic in the setter\n        color: {get: function(){return color;}, set: function(_){\n            color = _;\n            legend.color(color);\n            pie.color(color);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            pie.duration(duration);\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }}\n    });\n    nv.utils.inheritOptions(chart, pie);\n    nv.utils.initOptions(chart);\n    return chart;\n};\nnv.models.sankey = function() {\n    'use strict';\n\n    // Sources:\n    // - https://bost.ocks.org/mike/sankey/\n    // - https://github.com/soxofaan/d3-plugin-captain-sankey\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sankey = {},\n        nodeWidth = 24,\n        nodePadding = 8,\n        size = [1, 1],\n        nodes = [],\n        links = [],\n        sinksRight = true;\n\n    var layout = function(iterations) {\n        computeNodeLinks();\n        computeNodeValues();\n        computeNodeBreadths();\n        computeNodeDepths(iterations);\n    };\n\n    var relayout = function() {\n        computeLinkDepths();\n    };\n\n    // SVG path data generator, to be used as 'd' attribute on 'path' element selection.\n    var link = function() {\n        var curvature = .5;\n\n        function link(d) {\n\n            var x0 = d.source.x + d.source.dx,\n                x1 = d.target.x,\n                xi = d3.interpolateNumber(x0, x1),\n                x2 = xi(curvature),\n                x3 = xi(1 - curvature),\n                y0 = d.source.y + d.sy + d.dy / 2,\n                y1 = d.target.y + d.ty + d.dy / 2;\n            var linkPath = 'M' + x0 + ',' + y0\n                + 'C' + x2 + ',' + y0\n                + ' ' + x3 + ',' + y1\n                + ' ' + x1 + ',' + y1;\n            return linkPath;\n        }\n\n        link.curvature = function(_) {\n            if (!arguments.length) return curvature;\n            curvature = +_;\n            return link;\n        };\n\n        return link;\n    };\n\n    // Y-position of the middle of a node.\n    var center = function(node) {\n        return node.y + node.dy / 2;\n    };\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    // Populate the sourceLinks and targetLinks for each node.\n    // Also, if the source and target are not objects, assume they are indices.\n    function computeNodeLinks() {\n        nodes.forEach(function(node) {\n            // Links that have this node as source.\n            node.sourceLinks = [];\n            // Links that have this node as target.\n            node.targetLinks = [];\n        });\n        links.forEach(function(link) {\n            var source = link.source,\n                target = link.target;\n            if (typeof source === 'number') source = link.source = nodes[link.source];\n            if (typeof target === 'number') target = link.target = nodes[link.target];\n            source.sourceLinks.push(link);\n            target.targetLinks.push(link);\n        });\n    }\n\n    // Compute the value (size) of each node by summing the associated links.\n    function computeNodeValues() {\n        nodes.forEach(function(node) {\n            node.value = Math.max(\n                d3.sum(node.sourceLinks, value),\n                d3.sum(node.targetLinks, value)\n            );\n        });\n    }\n\n    // Iteratively assign the breadth (x-position) for each node.\n    // Nodes are assigned the maximum breadth of incoming neighbors plus one;\n    // nodes with no incoming links are assigned breadth zero, while\n    // nodes with no outgoing links are assigned the maximum breadth.\n    function computeNodeBreadths() {\n        //\n        var remainingNodes = nodes,\n            nextNodes,\n            x = 0;\n\n        // Work from left to right.\n        // Keep updating the breath (x-position) of nodes that are target of recently updated nodes.\n        //\n        while (remainingNodes.length && x < nodes.length) {\n            nextNodes = [];\n            remainingNodes.forEach(function(node) {\n                node.x = x;\n                node.dx = nodeWidth;\n                node.sourceLinks.forEach(function(link) {\n                    if (nextNodes.indexOf(link.target) < 0) {\n                        nextNodes.push(link.target);\n                    }\n                });\n            });\n            remainingNodes = nextNodes;\n            ++x;\n            //\n        }\n\n        // Optionally move pure sinks always to the right.\n        if (sinksRight) {\n            moveSinksRight(x);\n        }\n\n        scaleNodeBreadths((size[0] - nodeWidth) / (x - 1));\n    }\n\n    function moveSourcesRight() {\n        nodes.forEach(function(node) {\n            if (!node.targetLinks.length) {\n                node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1;\n            }\n        });\n    }\n\n    function moveSinksRight(x) {\n        nodes.forEach(function(node) {\n            if (!node.sourceLinks.length) {\n                node.x = x - 1;\n            }\n        });\n    }\n\n    function scaleNodeBreadths(kx) {\n        nodes.forEach(function(node) {\n            node.x *= kx;\n        });\n    }\n\n    // Compute the depth (y-position) for each node.\n    function computeNodeDepths(iterations) {\n        // Group nodes by breath.\n        var nodesByBreadth = d3.nest()\n            .key(function(d) { return d.x; })\n            .sortKeys(d3.ascending)\n            .entries(nodes)\n            .map(function(d) { return d.values; });\n\n        //\n        initializeNodeDepth();\n        resolveCollisions();\n        computeLinkDepths();\n        for (var alpha = 1; iterations > 0; --iterations) {\n            relaxRightToLeft(alpha *= .99);\n            resolveCollisions();\n            computeLinkDepths();\n            relaxLeftToRight(alpha);\n            resolveCollisions();\n            computeLinkDepths();\n        }\n\n        function initializeNodeDepth() {\n            // Calculate vertical scaling factor.\n            var ky = d3.min(nodesByBreadth, function(nodes) {\n                return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value);\n            });\n\n            nodesByBreadth.forEach(function(nodes) {\n                nodes.forEach(function(node, i) {\n                    node.y = i;\n                    node.dy = node.value * ky;\n                });\n            });\n\n            links.forEach(function(link) {\n                link.dy = link.value * ky;\n            });\n        }\n\n        function relaxLeftToRight(alpha) {\n            nodesByBreadth.forEach(function(nodes, breadth) {\n                nodes.forEach(function(node) {\n                    if (node.targetLinks.length) {\n                        // Value-weighted average of the y-position of source node centers linked to this node.\n                        var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value);\n                        node.y += (y - center(node)) * alpha;\n                    }\n                });\n            });\n\n            function weightedSource(link) {\n                return (link.source.y + link.sy + link.dy / 2) * link.value;\n            }\n        }\n\n        function relaxRightToLeft(alpha) {\n            nodesByBreadth.slice().reverse().forEach(function(nodes) {\n                nodes.forEach(function(node) {\n                    if (node.sourceLinks.length) {\n                        // Value-weighted average of the y-positions of target nodes linked to this node.\n                        var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value);\n                        node.y += (y - center(node)) * alpha;\n                    }\n                });\n            });\n\n            function weightedTarget(link) {\n                return (link.target.y + link.ty + link.dy / 2) * link.value;\n            }\n        }\n\n        function resolveCollisions() {\n            nodesByBreadth.forEach(function(nodes) {\n                var node,\n                    dy,\n                    y0 = 0,\n                    n = nodes.length,\n                    i;\n\n                // Push any overlapping nodes down.\n                nodes.sort(ascendingDepth);\n                for (i = 0; i < n; ++i) {\n                    node = nodes[i];\n                    dy = y0 - node.y;\n                    if (dy > 0) node.y += dy;\n                    y0 = node.y + node.dy + nodePadding;\n                }\n\n                // If the bottommost node goes outside the bounds, push it back up.\n                dy = y0 - nodePadding - size[1];\n                if (dy > 0) {\n                    y0 = node.y -= dy;\n\n                    // Push any overlapping nodes back up.\n                    for (i = n - 2; i >= 0; --i) {\n                        node = nodes[i];\n                        dy = node.y + node.dy + nodePadding - y0;\n                        if (dy > 0) node.y -= dy;\n                        y0 = node.y;\n                    }\n                }\n            });\n        }\n\n        function ascendingDepth(a, b) {\n            return a.y - b.y;\n        }\n    }\n\n    // Compute y-offset of the source endpoint (sy) and target endpoints (ty) of links,\n    // relative to the source/target node's y-position.\n    function computeLinkDepths() {\n        nodes.forEach(function(node) {\n            node.sourceLinks.sort(ascendingTargetDepth);\n            node.targetLinks.sort(ascendingSourceDepth);\n        });\n        nodes.forEach(function(node) {\n            var sy = 0, ty = 0;\n            node.sourceLinks.forEach(function(link) {\n                link.sy = sy;\n                sy += link.dy;\n            });\n            node.targetLinks.forEach(function(link) {\n                link.ty = ty;\n                ty += link.dy;\n            });\n        });\n\n        function ascendingSourceDepth(a, b) {\n            return a.source.y - b.source.y;\n        }\n\n        function ascendingTargetDepth(a, b) {\n            return a.target.y - b.target.y;\n        }\n    }\n\n    // Value property accessor.\n    function value(x) {\n        return x.value;\n    }\n\n    sankey.options = nv.utils.optionsFunc.bind(sankey);\n    sankey._options = Object.create({}, {\n        nodeWidth:    {get: function(){return nodeWidth;},   set: function(_){nodeWidth=+_;}},\n        nodePadding:  {get: function(){return nodePadding;}, set: function(_){nodePadding=_;}},\n        nodes:        {get: function(){return nodes;},       set: function(_){nodes=_;}},\n        links:        {get: function(){return links ;},      set: function(_){links=_;}},\n        size:         {get: function(){return size;},        set: function(_){size=_;}},\n        sinksRight:   {get: function(){return sinksRight;},  set: function(_){sinksRight=_;}},\n\n        layout:       {get: function(){layout(32);},         set: function(_){layout(_);}},\n        relayout:     {get: function(){relayout();},         set: function(_){}},\n        center:       {get: function(){return center();},    set: function(_){\n            if(typeof _ === 'function'){\n                center=_;\n            }\n        }},\n        link:         {get: function(){return link();},      set: function(_){\n            if(typeof _ === 'function'){\n                link=_;\n            }\n            return link();\n        }}\n    });\n\n    nv.utils.initOptions(sankey);\n\n    return sankey;\n};\nnv.models.sankeyChart = function() {\n    \"use strict\";\n\n    // Sources:\n    // - https://bost.ocks.org/mike/sankey/\n    // - https://github.com/soxofaan/d3-plugin-captain-sankey\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , sankey = nv.models.sankey()\n        , width = 600\n        , height = 400\n        , nodeWidth = 36\n        , nodePadding =  40\n        , units = 'units'\n        , center = undefined\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var formatNumber = d3.format(',.0f');    // zero decimal places\n    var format = function(d) {\n        return formatNumber(d) + ' ' + units;\n    };\n    var color = d3.scale.category20();\n    var linkTitle = function(d){\n        return d.source.name + ' → ' + d.target.name + '\\n' + format(d.value);\n    };\n    var nodeFillColor = function(d){\n        return d.color = color(d.name.replace(/ .*/, ''));\n    };\n    var nodeStrokeColor = function(d){\n        return d3.rgb(d.color).darker(2);\n    };\n    var nodeTitle = function(d){\n        return d.name + '\\n' + format(d.value);\n    };\n\n    var showError = function(element, message) {\n        element.append('text')\n            .attr('x', 0)\n            .attr('y', 0)\n            .attr('class', 'nvd3-sankey-chart-error')\n            .attr('text-anchor', 'middle')\n            .text(message);\n    };\n\n    function chart(selection) {\n        selection.each(function(data) {\n\n            var testData = {\n                nodes:\n                    [\n                        {'node': 1, 'name': 'Test 1'},\n                        {'node': 2, 'name': 'Test 2'},\n                        {'node': 3, 'name': 'Test 3'},\n                        {'node': 4, 'name': 'Test 4'},\n                        {'node': 5, 'name': 'Test 5'},\n                        {'node': 6, 'name': 'Test 6'}\n                    ],\n                links:\n                    [\n                        {'source': 0, 'target': 1, 'value': 2295},\n                        {'source': 0, 'target': 5, 'value': 1199},\n                        {'source': 1, 'target': 2, 'value': 1119},\n                        {'source': 1, 'target': 5, 'value': 1176},\n                        {'source': 2, 'target': 3, 'value': 487},\n                        {'source': 2, 'target': 5, 'value': 632},\n                        {'source': 3, 'target': 4, 'value': 301},\n                        {'source': 3, 'target': 5, 'value': 186}\n                    ]\n            };\n\n            // Error handling\n            var isDataValid = false;\n            var dataAvailable = false;\n\n            // check if data is valid\n            if(\n                (typeof data['nodes'] === 'object' && data['nodes'].length) >= 0 &&\n                (typeof data['links'] === 'object' && data['links'].length) >= 0\n            ){\n                isDataValid = true;\n            }\n\n            // check if data is available\n            if(\n                data['nodes'] && data['nodes'].length > 0 &&\n                data['links'] && data['links'].length > 0\n            ) {\n                dataAvailable = true;\n            }\n\n            // show error\n            if(!isDataValid) {\n                console.error('NVD3 Sankey chart error:', 'invalid data format for', data);\n                console.info('Valid data format is: ', testData, JSON.stringify(testData));\n                showError(selection, 'Error loading chart, data is invalid');\n                return false;\n            }\n\n            // TODO use nv.utils.noData\n            if(!dataAvailable) {\n                showError(selection, 'No data available');\n                return false;\n            }\n\n            // No errors, continue\n\n            // append the svg canvas to the page\n            var svg = selection.append('svg')\n                .attr('width', width)\n                .attr('height', height)\n                .append('g')\n                .attr('class', 'nvd3 nv-wrap nv-sankeyChart');\n\n            // Set the sankey diagram properties\n            sankey\n                .nodeWidth(nodeWidth)\n                .nodePadding(nodePadding)\n                .size([width, height]);\n\n            var path = sankey.link();\n\n            sankey\n                .nodes(data.nodes)\n                .links(data.links)\n                .layout(32)\n                .center(center);\n\n            // add in the links\n            var link = svg.append('g').selectAll('.link')\n                .data(data.links)\n                .enter().append('path')\n                .attr('class', 'link')\n                .attr('d', path)\n                .style('stroke-width', function(d) { return Math.max(1, d.dy); })\n            .sort(function(a,b) { return b.dy - a.dy; });\n\n            // add the link titles\n            link.append('title')\n                .text(linkTitle);\n\n            // add in the nodes\n            var node = svg.append('g').selectAll('.node')\n                .data(data.nodes)\n                .enter().append('g')\n                .attr('class', 'node')\n                .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; })\n                .call(\n                    d3.behavior\n                        .drag()\n                        .origin(function(d) { return d; })\n                        .on('dragstart', function() {\n                            this.parentNode.appendChild(this);\n                        })\n                        .on('drag', dragmove)\n                );\n\n            // add the rectangles for the nodes\n            node.append('rect')\n                .attr('height', function(d) { return d.dy; })\n                .attr('width', sankey.nodeWidth())\n                .style('fill', nodeFillColor)\n                .style('stroke', nodeStrokeColor)\n                .append('title')\n                .text(nodeTitle);\n\n            // add in the title for the nodes\n            node.append('text')\n                .attr('x', -6)\n                .attr('y', function(d) { return d.dy / 2; })\n                .attr('dy', '.35em')\n                .attr('text-anchor', 'end')\n                .attr('transform', null)\n                .text(function(d) { return d.name; })\n                .filter(function(d) { return d.x < width / 2; })\n                .attr('x', 6 + sankey.nodeWidth())\n                .attr('text-anchor', 'start');\n\n            // the function for moving the nodes\n            function dragmove(d) {\n                d3.select(this).attr('transform',\n                'translate(' + d.x + ',' + (\n                    d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))\n                ) + ')');\n                sankey.relayout();\n                link.attr('d', path);\n            }\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        units:           {get: function(){return units;},       set: function(_){units=_;}},\n        width:           {get: function(){return width;},       set: function(_){width=_;}},\n        height:          {get: function(){return height;},      set: function(_){height=_;}},\n        format:          {get: function(){return format;},      set: function(_){format=_;}},\n        linkTitle:       {get: function(){return linkTitle;},   set: function(_){linkTitle=_;}},\n        nodeWidth:       {get: function(){return nodeWidth;},   set: function(_){nodeWidth=_;}},\n        nodePadding:     {get: function(){return nodePadding;}, set: function(_){nodePadding=_;}},\n        center:          {get: function(){return center},       set: function(_){center=_}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        nodeStyle: {get: function(){return {};}, set: function(_){\n            nodeFillColor   = _.fillColor   !== undefined ? _.fillColor   : nodeFillColor;\n            nodeStrokeColor = _.strokeColor !== undefined ? _.strokeColor : nodeStrokeColor;\n            nodeTitle       = _.title       !== undefined ? _.title       : nodeTitle;\n        }}\n\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.scatter = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin       = {top: 0, right: 0, bottom: 0, left: 0}\n        , width        = null\n        , height       = null\n        , color        = nv.utils.defaultColor() // chooses color\n        , pointBorderColor = null\n        , id           = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't select one\n        , container    = null\n        , x            = d3.scale.linear()\n        , y            = d3.scale.linear()\n        , z            = d3.scale.linear() //linear because d3.svg.shape.size is treated as area\n        , getX         = function(d) { return d.x } // accessor to get the x value\n        , getY         = function(d) { return d.y } // accessor to get the y value\n        , getSize      = function(d) { return d.size || 1} // accessor to get the point size\n        , getShape     = function(d) { return d.shape || 'circle' } // accessor to get point shape\n        , forceX       = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)\n        , forceY       = [] // List of numbers to Force into the Y scale\n        , forceSize    = [] // List of numbers to Force into the Size scale\n        , interactive  = true // If true, plots a voronoi overlay for advanced point intersection\n        , pointActive  = function(d) { return !d.notActive } // any points that return false will be filtered out\n        , padData      = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding\n        , clipEdge     = false // if true, masks points within x and y scale\n        , clipVoronoi  = true // if true, masks each point with a circle... can turn off to slightly increase performance\n        , showVoronoi  = false // display the voronoi areas\n        , clipRadius   = function() { return 25 } // function to get the radius for voronoi point clips\n        , xDomain      = null // Override x domain (skips the calculation from data)\n        , yDomain      = null // Override y domain\n        , xRange       = null // Override x range\n        , yRange       = null // Override y range\n        , sizeDomain   = null // Override point size domain\n        , sizeRange    = null\n        , singlePoint  = false\n        , dispatch     = d3.dispatch('elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'renderEnd')\n        , useVoronoi   = true\n        , duration     = 250\n        , interactiveUpdateDelay = 300\n        , showLabels    = false\n        ;\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0, z0 // used to store previous scales\n        , xDom, yDom // used to store previous domains\n        , width0\n        , height0\n        , timeoutID\n        , needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        , _sizeRange_def = [16, 256]\n        , _cache = {}\n        ;\n\n    //============================================================\n    // Diff and Cache Utilities\n    //------------------------------------------------------------\n    // getDiffs is used to filter unchanged points from the update\n    // selection. It implicitly updates it's cache when called and\n    // therefor the diff is based upon the previous invocation NOT\n    // the previous update.\n    //\n    // getDiffs takes a point as its first argument followed by n\n    // key getter pairs (d, [key, get... key, get]) this approach\n    // was chosen for efficiency. (The filter will call it a LOT).\n    //\n    // It is important to call delCache on point exit to prevent a\n    // memory leak. It is also needed to prevent invalid caches if\n    // a new point uses the same series and point id key.\n    //\n    // Argument Performance Concerns:\n    // - Object property lists for key getter pairs would be very\n    // expensive (points * objects for the GC every update).\n    // - ES6 function names for implicit keys would be nice but\n    // they are not guaranteed to be unique.\n    // - function.toString to obtain implicit keys is possible\n    // but long object keys are not free (internal hash).\n    // - Explicit key without objects are the most efficient.\n\n    function getCache(d) {\n        var key, val;\n        key = d[0].series + ':' + d[1];\n        val = _cache[key] = _cache[key] || {};\n        return val;\n    }\n\n    function delCache(d) {\n        var key, val;\n        key = d[0].series + ':' + d[1];\n        delete _cache[key];\n    }\n\n    function getDiffs(d) {\n        var i, key, val,\n            cache = getCache(d),\n            diffs = false;\n        for (i = 1; i < arguments.length; i += 2) {\n            key = arguments[i];\n            val = arguments[i + 1](d[0], d[1]);\n            if (cache[key] !== val || !cache.hasOwnProperty(key)) {\n                cache[key] = val;\n                diffs = true;\n            }\n        }\n        return diffs;\n    }\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            //add series index to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                });\n            });\n\n            // Setup Scales\n            var logScale = (typeof(chart.yScale().base) === \"function\"); // Only log scale has a method \"base()\"\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain && sizeDomain) ? [] : // if we know xDomain and yDomain and sizeDomain, no need to calculate.... if Size is constant remember to set sizeDomain to speed up performance\n                d3.merge(\n                    data.map(function(d) {\n                        return d.values.map(function(d,i) {\n                            return { x: getX(d,i), y: getY(d,i), size: getSize(d,i) }\n                        })\n                    })\n                );\n\n            x   .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x; }).concat(forceX)))\n\n            if (padData && data[0])\n                x.range(xRange || [(availableWidth * padDataOuter +  availableWidth) / (2 *data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 * data[0].values.length)  ]);\n            //x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [0, availableWidth]);\n\n             if (logScale) {\n                    var min = d3.min(seriesData.map(function(d) { if (d.y !== 0) return d.y; }));\n                    y.clamp(true)\n                        .domain(yDomain || d3.extent(seriesData.map(function(d) {\n                            if (d.y !== 0) return d.y;\n                            else return min * 0.1;\n                        }).concat(forceY)))\n                        .range(yRange || [availableHeight, 0]);\n                } else {\n                        y.domain(yDomain || d3.extent(seriesData.map(function (d) { return d.y;}).concat(forceY)))\n                        .range(yRange || [availableHeight, 0]);\n                }\n\n            z   .domain(sizeDomain || d3.extent(seriesData.map(function(d) { return d.size }).concat(forceSize)))\n                .range(sizeRange || _sizeRange_def);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            singlePoint = x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1];\n\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] - y.domain()[0] * 0.01, y.domain()[1] + y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            if ( isNaN(x.domain()[0])) {\n                x.domain([-1,1]);\n            }\n\n            if ( isNaN(y.domain()[0])) {\n                y.domain([-1,1]);\n            }\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n            z0 = z0 || z;\n\n            var scaleDiff = x(1) !== x0(1) || y(1) !== y0(1) || z(1) !== z0(1);\n\n            width0 = width0 || width;\n            height0 = height0 || height;\n\n            var sizeDiff = width0 !== width || height0 !== height;\n\n            // Domain Diffs\n\n            xDom = xDom || [];\n            var domainDiff = xDom[0] !== x.domain()[0] || xDom[1] !== x.domain()[1];\n            xDom = x.domain();\n\n            yDom = yDom || [];\n            domainDiff = domainDiff || yDom[0] !== y.domain()[0] || yDom[1] !== y.domain()[1];\n            yDom = y.domain();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id);\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.classed('nv-single-point', singlePoint);\n            gEnter.append('g').attr('class', 'nv-groups');\n            gEnter.append('g').attr('class', 'nv-point-paths');\n            wrapEnter.append('g').attr('class', 'nv-point-clips');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect')\n                .attr('transform', 'translate( -10, -10)');\n\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth + 20)\n                .attr('height', (availableHeight > 0) ? availableHeight + 20 : 0);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            function updateInteractiveLayer() {\n                // Always clear needs-update flag regardless of whether or not\n                // we will actually do anything (avoids needless invocations).\n                needsUpdate = false;\n\n                if (!interactive) return false;\n                container.selectAll(\".nv-point.hover\").classed(\"hover\", false);\n\n                // nuke all voronoi paths\n                wrap.select('.nv-point-paths').selectAll('path').remove();\n\n                // inject series and point index for reference into voronoi\n                if (useVoronoi === true) {\n                    var vertices = d3.merge(data.map(function(group, groupIndex) {\n                            return group.values\n                                .map(function(point, pointIndex) {\n                                    // *Adding noise to make duplicates very unlikely\n                                    // *Injecting series and point index for reference\n                                    // *Adding a 'jitter' to the points, because there's an issue in d3.geom.voronoi.\n                                    var pX = getX(point,pointIndex);\n                                    var pY = getY(point,pointIndex);\n\n                                    return [nv.utils.NaNtoZero(x(pX)) + Math.random() * 1e-4,\n                                            nv.utils.NaNtoZero(y(pY)) + Math.random() * 1e-4,\n                                        groupIndex,\n                                        pointIndex, point];\n                                })\n                                .filter(function(pointArray, pointIndex) {\n                                    return pointActive(pointArray[4], pointIndex); // Issue #237.. move filter to after map, so pointIndex is correct!\n                                })\n                        })\n                    );\n\n                    if (vertices.length == 0) return false;  // No active points, we're done\n                    if (vertices.length < 3) {\n                        // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work\n                        vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]);\n                        vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]);\n                        vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]);\n                        vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]);\n                    }\n\n                    // keep voronoi sections from going more than 10 outside of graph\n                    // to avoid overlap with other things like legend etc\n                    var bounds = d3.geom.polygon([\n                        [-10,-10],\n                        [-10,height + 10],\n                        [width + 10,height + 10],\n                        [width + 10,-10]\n                    ]);\n\n                    // delete duplicates from vertices - essential assumption for d3.geom.voronoi\n                    var epsilon = 1e-4; // Uses 1e-4 to determine equivalence.\n                    vertices = vertices.sort(function(a,b){return ((a[0] - b[0]) || (a[1] - b[1]))});\n                    for (var i = 0; i < vertices.length - 1; ) {\n                        if ((Math.abs(vertices[i][0] - vertices[i+1][0]) < epsilon) &&\n                        (Math.abs(vertices[i][1] - vertices[i+1][1]) < epsilon)) {\n                            vertices.splice(i+1, 1);\n                        } else {\n                            i++;\n                        }\n                    }\n\n                    var voronoi = d3.geom.voronoi(vertices).map(function(d, i) {\n                        if (d.length === 0) {\n                            return null;\n                        }\n\n                        return {\n                            'data': bounds.clip(d),\n                            'series': vertices[i][2],\n                            'point': vertices[i][3]\n                        }\n                    });\n\n                    var pointPaths = wrap.select('.nv-point-paths').selectAll('path').data(voronoi);\n                    var vPointPaths = pointPaths\n                        .enter().append(\"svg:path\")\n                        .attr(\"d\", function(d) {\n                            if (!d || !d.data || d.data.length === 0)\n                                return 'M 0 0';\n                            else\n                                return \"M\" + d.data.join(\",\") + \"Z\";\n                        })\n                        .attr(\"id\", function(d,i) {\n                            return \"nv-path-\"+i; })\n                        .attr(\"clip-path\", function(d,i) { return \"url(#nv-clip-\"+id+\"-\"+i+\")\"; })\n                        ;\n\n                    // good for debugging point hover issues\n                    if (showVoronoi) {\n                        vPointPaths.style(\"fill\", d3.rgb(230, 230, 230))\n                            .style('fill-opacity', 0.4)\n                            .style('stroke-opacity', 1)\n                            .style(\"stroke\", d3.rgb(200,200,200));\n                    }\n\n                    if (clipVoronoi) {\n                        // voronoi sections are already set to clip,\n                        // just create the circles with the IDs they expect\n                        wrap.select('.nv-point-clips').selectAll('*').remove(); // must do * since it has sub-dom\n                        var pointClips = wrap.select('.nv-point-clips').selectAll('clipPath').data(vertices);\n                        var vPointClips = pointClips\n                            .enter().append(\"svg:clipPath\")\n                            .attr(\"id\", function(d, i) { return \"nv-clip-\"+id+\"-\"+i;})\n                            .append(\"svg:circle\")\n                            .attr('cx', function(d) { return d[0]; })\n                            .attr('cy', function(d) { return d[1]; })\n                            .attr('r', clipRadius);\n                    }\n\n                    var mouseEventCallback = function(el, d, mDispatch) {\n                        if (needsUpdate) return 0;\n                        var series = data[d.series];\n                        if (series === undefined) return;\n                        var point  = series.values[d.point];\n                        point['color'] = color(series, d.series);\n\n                        // standardize attributes for tooltip.\n                        point['x'] = getX(point);\n                        point['y'] = getY(point);\n\n                        // can't just get box of event node since it's actually a voronoi polygon\n                        var box = container.node().getBoundingClientRect();\n                        var scrollTop  = window.pageYOffset || document.documentElement.scrollTop;\n                        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n                        var pos = {\n                            left: x(getX(point, d.point)) + box.left + scrollLeft + margin.left + 10,\n                            top: y(getY(point, d.point)) + box.top + scrollTop + margin.top + 10\n                        };\n\n                        mDispatch({\n                            point: point,\n                            series: series,\n                            pos: pos,\n                            relativePos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top],\n                            seriesIndex: d.series,\n                            pointIndex: d.point,\n                            event: d3.event,\n                            element: el\n                        });\n                    };\n\n                    pointPaths\n                        .on('click', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementClick);\n                        })\n                        .on('dblclick', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementDblClick);\n                        })\n                        .on('mouseover', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementMouseover);\n                        })\n                        .on('mouseout', function(d, i) {\n                            mouseEventCallback(this, d, dispatch.elementMouseout);\n                        });\n\n                } else {\n                    // add event handlers to points instead voronoi paths\n                    wrap.select('.nv-groups').selectAll('.nv-group')\n                        .selectAll('.nv-point')\n                        //.data(dataWithPoints)\n                        //.style('pointer-events', 'auto') // recativate events, disabled by css\n                        .on('click', function(d,i) {\n                            //nv.log('test', d, i);\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n                            var element = this;\n                            dispatch.elementClick({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], //TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                event: d3.event,\n                                element: element\n                            });\n                        })\n                        .on('dblclick', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementDblClick({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i\n                            });\n                        })\n                        .on('mouseover', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementMouseover({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                color: color(d[0], i)\n                            });\n                        })\n                        .on('mouseout', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementMouseout({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                color: color(d[0], i)\n                            });\n                        });\n                }\n            }\n\n            needsUpdate = true;\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit()\n                .remove();\n            groups\n                .attr('class', function(d,i) {\n                    return (d.classed || '') + ' nv-group nv-series-' + i;\n                })\n                .classed('nv-noninteractive', !interactive)\n                .classed('hover', function(d) { return d.hover });\n            groups.watchTransition(renderWatch, 'scatter: groups')\n                .style('fill', function(d,i) { return color(d, i) })\n                .style('stroke', function(d,i) { return d.pointBorderColor || pointBorderColor || color(d, i) })\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', .5);\n\n            // create the points, maintaining their IDs from the original data set\n            var points = groups.selectAll('path.nv-point')\n                .data(function(d) {\n                    return d.values.map(\n                        function (point, pointIndex) {\n                            return [point, pointIndex]\n                        }).filter(\n                            function(pointArray, pointIndex) {\n                                return pointActive(pointArray[0], pointIndex)\n                            })\n                    });\n            points.enter().append('path')\n                .attr('class', function (d) {\n                    return 'nv-point nv-point-' + d[1];\n                })\n                .style('fill', function (d) { return d.color })\n                .style('stroke', function (d) { return d.color })\n                .attr('transform', function(d) {\n                    return 'translate(' + nv.utils.NaNtoZero(x0(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y0(getY(d[0],d[1]))) + ')'\n                })\n                .attr('d',\n                    nv.utils.symbol()\n                    .type(function(d) { return getShape(d[0]); })\n                    .size(function(d) { return z(getSize(d[0],d[1])) })\n            );\n            points.exit().each(delCache).remove();\n            groups.exit().selectAll('path.nv-point')\n                .watchTransition(renderWatch, 'scatter exit')\n                .attr('transform', function(d) {\n                    return 'translate(' + nv.utils.NaNtoZero(x(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'\n                })\n                .remove();\n\n            //============================================================\n            // Point Update Optimisation Notes\n            //------------------------------------------------------------\n            // The following update selections are filtered with getDiffs\n            // (defined at the top of this file) this brings a performance\n            // benefit for charts with large data sets that accumulate a\n            // subset of changes or additions over time.\n            //\n            // Uneccesary and expensive DOM calls are avoided by culling\n            // unchanged points from the selection in exchange for the\n            // cheaper overhead of caching and diffing each point first.\n            //\n            // Due to the way D3 and NVD3 work, other global changes need\n            // to be considered in addition to local point properties.\n            // This is a potential source of bugs (if any of the global\n            // changes that possibly affect points are missed).\n\n            // Update Point Positions [x, y]\n            points.filter(function (d) {\n                // getDiffs must always be called to update cache\n                return getDiffs(d, 'x', getX, 'y', getY) ||\n                    scaleDiff || sizeDiff || domainDiff;\n            })\n            .watchTransition(renderWatch, 'scatter points')\n            .attr('transform', function (d) {\n                return 'translate(' +\n                    nv.utils.NaNtoZero(x(getX(d[0], d[1]))) + ',' +\n                    nv.utils.NaNtoZero(y(getY(d[0], d[1]))) + ')'\n            });\n\n            // Update Point Appearance [shape, size]\n            points.filter(function (d) {\n                // getDiffs must always be called to update cache\n                return getDiffs(d, 'shape', getShape, 'size', getSize) ||\n                    scaleDiff || sizeDiff || domainDiff;\n            })\n            .watchTransition(renderWatch, 'scatter points')\n            .attr('d', nv.utils.symbol()\n                .type(function (d) { return getShape(d[0]) })\n                .size(function (d) { return z(getSize(d[0], d[1])) })\n            );\n\n            // add label a label to scatter chart\n            if(showLabels)\n            {\n                var titles =  groups.selectAll('.nv-label')\n                    .data(function(d) {\n                        return d.values.map(\n                            function (point, pointIndex) {\n                                return [point, pointIndex]\n                            }).filter(\n                                function(pointArray, pointIndex) {\n                                    return pointActive(pointArray[0], pointIndex)\n                                })\n                        });\n\n                titles.enter().append('text')\n                    .style('fill', function (d,i) {\n                        return d.color })\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 1)\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x0(getX(d[0],d[1]))) + Math.sqrt(z(getSize(d[0],d[1]))/Math.PI) + 2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y0(getY(d[0],d[1]))) + ')';\n                    })\n                    .text(function(d,i){\n                        return d[0].label;});\n\n                titles.exit().remove();\n                groups.exit().selectAll('path.nv-label')\n                    .watchTransition(renderWatch, 'scatter exit')\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')';\n                    })\n                    .remove();\n               titles.each(function(d) {\n                  d3.select(this)\n                    .classed('nv-label', true)\n                    .classed('nv-label-' + d[1], false)\n                    .classed('hover',false);\n                });\n                titles.watchTransition(renderWatch, 'scatter labels')\n                    .text(function(d,i){ \n                        return d[0].label;})\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'\n                    });\n            }\n\n            // Delay updating the invisible interactive layer for smoother animation\n            if( interactiveUpdateDelay )\n            {\n                clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer\n                timeoutID = setTimeout(updateInteractiveLayer, interactiveUpdateDelay );\n            }\n            else\n            {\n                updateInteractiveLayer();\n            }\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n            z0 = z.copy();\n\n            width0 = width;\n            height0 = height;\n\n        });\n        renderWatch.renderEnd('scatter immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // utility function calls provided by this chart\n    chart._calls = new function() {\n        this.clearHighlights = function () {\n            nv.dom.write(function() {\n                container.selectAll(\".nv-point.hover\").classed(\"hover\", false);\n            });\n            return null;\n        };\n        this.highlightPoint = function (seriesIndex, pointIndex, isHoverOver) {\n            nv.dom.write(function() {\n                container.select('.nv-groups')\n                  .selectAll(\".nv-series-\" + seriesIndex)\n                  .selectAll(\".nv-point-\" + pointIndex)\n                  .classed(\"hover\", isHoverOver);\n            });\n        };\n    };\n\n    // trigger calls from events too\n    dispatch.on('elementMouseover.point', function(d) {\n        if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,true);\n    });\n\n    dispatch.on('elementMouseout.point', function(d) {\n        if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,false);\n    });\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:        {get: function(){return width;}, set: function(_){width=_;}},\n        height:       {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:       {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:       {get: function(){return y;}, set: function(_){y=_;}},\n        pointScale:   {get: function(){return z;}, set: function(_){z=_;}},\n        xDomain:      {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:      {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        pointDomain:  {get: function(){return sizeDomain;}, set: function(_){sizeDomain=_;}},\n        xRange:       {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:       {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        pointRange:   {get: function(){return sizeRange;}, set: function(_){sizeRange=_;}},\n        forceX:       {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:       {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        forcePoint:   {get: function(){return forceSize;}, set: function(_){forceSize=_;}},\n        interactive:  {get: function(){return interactive;}, set: function(_){interactive=_;}},\n        pointActive:  {get: function(){return pointActive;}, set: function(_){pointActive=_;}},\n        padDataOuter: {get: function(){return padDataOuter;}, set: function(_){padDataOuter=_;}},\n        padData:      {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge:     {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        clipVoronoi:  {get: function(){return clipVoronoi;}, set: function(_){clipVoronoi=_;}},\n        clipRadius:   {get: function(){return clipRadius;}, set: function(_){clipRadius=_;}},\n        showVoronoi:   {get: function(){return showVoronoi;}, set: function(_){showVoronoi=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n        interactiveUpdateDelay: {get:function(){return interactiveUpdateDelay;}, set: function(_){interactiveUpdateDelay=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){ showLabels = _;}},\n        pointBorderColor: {get: function(){return pointBorderColor;}, set: function(_){pointBorderColor=_;}},\n\n        // simple functor options\n        x:     {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}},\n        y:     {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}},\n        pointSize: {get: function(){return getSize;}, set: function(_){getSize = d3.functor(_);}},\n        pointShape: {get: function(){return getShape;}, set: function(_){getShape = d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        useVoronoi: {get: function(){return useVoronoi;}, set: function(_){\n            useVoronoi = _;\n            if (useVoronoi === false) {\n                clipVoronoi = false;\n            }\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\nnv.models.scatterChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var scatter      = nv.models.scatter()\n        , xAxis        = nv.models.axis()\n        , yAxis        = nv.models.axis()\n        , legend       = nv.models.legend()\n        , distX        = nv.models.distribution()\n        , distY        = nv.models.distribution()\n        , tooltip      = nv.models.tooltip()\n        ;\n\n    var margin       = {top: 30, right: 20, bottom: 50, left: 75}\n        , marginTop = null\n        , width        = null\n        , height       = null\n        , container    = null\n        , color        = nv.utils.defaultColor()\n        , x            = scatter.xScale()\n        , y            = scatter.yScale()\n        , showDistX    = false\n        , showDistY    = false\n        , showLegend   = true\n        , showXAxis    = true\n        , showYAxis    = true\n        , rightAlignYAxis = false\n        , state = nv.utils.state()\n        , defaultState = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , noData       = null\n        , duration = 250\n        , showLabels    = false\n        ;\n\n    scatter.xScale(x).yScale(y);\n    xAxis.orient('bottom').tickPadding(10);\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickPadding(10)\n    ;\n    distX.axis('x');\n    distY.axis('y');\n    tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0\n        , renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n        if (showDistX) renderWatch.models(distX);\n        if (showDistY) renderWatch.models(distY);\n\n        selection.each(function(data) {\n            var that = this;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                renderWatch.renderEnd('scatter immediate');\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatterChart nv-chart-' + scatter.id());\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            // background for pointer events\n            gEnter.append('rect').attr('class', 'nvd3 nv-background').style(\"pointer-events\",\"none\");\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n            gEnter.append('g').attr('class', 'nv-regressionLinesWrap');\n            gEnter.append('g').attr('class', 'nv-distWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = availableWidth;\n                legend.width(legendWidth);\n\n                wrap.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0' + ',' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            scatter\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    d.color = d.color || color(d, i);\n                    return d.color;\n                }).filter(function(d,i) { return !data[i].disabled }))\n                .showLabels(showLabels);\n\n            wrap.select('.nv-scatterWrap')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(scatter);\n\n\n            wrap.select('.nv-regressionLinesWrap')\n                .attr('clip-path', 'url(#nv-edge-clip-' + scatter.id() + ')');\n\n            var regWrap = wrap.select('.nv-regressionLinesWrap').selectAll('.nv-regLines')\n                .data(function (d) {\n                    return d;\n                });\n\n            regWrap.enter().append('g').attr('class', 'nv-regLines');\n\n            var regLine = regWrap.selectAll('.nv-regLine')\n                .data(function (d) {\n                    return [d]\n                });\n\n            regLine.enter()\n                .append('line').attr('class', 'nv-regLine')\n                .style('stroke-opacity', 0);\n\n            // don't add lines unless we have slope and intercept to use\n            regLine.filter(function(d) {\n                return d.intercept && d.slope;\n            })\n                .watchTransition(renderWatch, 'scatterPlusLineChart: regline')\n                .attr('x1', x.range()[0])\n                .attr('x2', x.range()[1])\n                .attr('y1', function (d, i) {\n                    return y(x.domain()[0] * d.slope + d.intercept)\n                })\n                .attr('y2', function (d, i) {\n                    return y(x.domain()[1] * d.slope + d.intercept)\n                })\n                .style('stroke', function (d, i, j) {\n                    return color(d, j)\n                })\n                .style('stroke-opacity', function (d, i) {\n                    return (d.disabled || typeof d.slope === 'undefined' || typeof d.intercept === 'undefined') ? 0 : 1\n                });\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight , 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')')\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            // Setup Distribution\n            distX\n                .getData(scatter.x())\n                .scale(x)\n                .width(availableWidth)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n            gEnter.select('.nv-distWrap').append('g')\n                .attr('class', 'nv-distributionX');\n            g.select('.nv-distributionX')\n                .attr('transform', 'translate(0,' + y.range()[0] + ')')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(distX)\n                .style('opacity', function() { return showDistX ? '1' : '1e-6'; })\n                .watchTransition(renderWatch, 'scatterPlusLineChart')\n                .style('opacity', function() { return showDistX ? '1' : '1e-6'; })\n\n\n            distY\n                .getData(scatter.y())\n                .scale(y)\n                .width(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n            gEnter.select('.nv-distWrap').append('g')\n                .attr('class', 'nv-distributionY');\n            g.select('.nv-distributionY')\n                .attr('transform', 'translate(' + (rightAlignYAxis ? availableWidth : -distY.size() ) + ',0)')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(distY)\n                .style('opacity', function() { return showDistY ? '1' : '1e-6'; })\n                .watchTransition(renderWatch, 'scatterPlusLineChart')\n                .style('opacity', function() { return showDistY ? '1' : '1e-6'; })\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            // mouseover needs availableHeight so we just keep scatter mouse events inside the chart block\n            scatter.dispatch.on('elementMouseout.tooltip', function(evt) {\n                tooltip.hidden(true);\n                container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                    .attr('y1', 0);\n                container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                    .attr('x2', distY.size());\n            });\n\n            scatter.dispatch.on('elementMouseover.tooltip', function(evt) {\n                container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                    .attr('y1', evt.relativePos[1] - availableHeight);\n                container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                    .attr('x2', evt.relativePos[0] + distX.size());\n                tooltip.data(evt).hidden(false);\n            });\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('scatter with line immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.distX = distX;\n    chart.distY = distY;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        container:  {get: function(){return container;}, set: function(_){container=_;}},\n        showDistX:  {get: function(){return showDistX;}, set: function(_){showDistX=_;}},\n        showDistY:  {get: function(){return showDistY;}, set: function(_){showDistY=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        showXAxis:  {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:  {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:     {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:     {get: function(){return noData;}, set: function(_){noData=_;}},\n        duration:   {get: function(){return duration;}, set: function(_){duration=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            distX.color(color);\n            distY.color(color);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\nnv.models.sparkline = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 2, right: 0, bottom: 2, left: 0}\n        , width = 400\n        , height = 32\n        , container = null\n        , animate = true\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , color = nv.utils.getColor(['#000'])\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , showMinMaxPoints = true\n        , showCurrentPoint = true\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    \n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x   .domain(xDomain || d3.extent(data, getX ))\n                .range(xRange || [0, availableWidth]);\n\n            y   .domain(yDomain || d3.extent(data, getY ))\n                .range(yRange || [availableHeight, 0]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-sparkline').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparkline');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')\n\n            var paths = wrap.selectAll('path')\n                .data(function(d) { return [d] });\n            paths.enter().append('path');\n            paths.exit().remove();\n            paths\n                .style('stroke', function(d,i) { return d.color || color(d, i) })\n                .attr('d', d3.svg.line()\n                    .x(function(d,i) { return x(getX(d,i)) })\n                    .y(function(d,i) { return y(getY(d,i)) })\n            );\n\n            // TODO: Add CURRENT data point (Need Min, Mac, Current / Most recent)\n            var points = wrap.selectAll('circle.nv-point')\n                .data(function(data) {\n                    var yValues = data.map(function(d, i) { return getY(d,i); });\n                    function pointIndex(index) {\n                        if (index != -1) {\n                            var result = data[index];\n                            result.pointIndex = index;\n                            return result;\n                        } else {\n                            return null;\n                        }\n                    }\n                    var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])),\n                        minPoint = pointIndex(yValues.indexOf(y.domain()[0])),\n                        currentPoint = pointIndex(yValues.length - 1);\n                    return [(showMinMaxPoints ? minPoint : null), (showMinMaxPoints ? maxPoint : null), (showCurrentPoint ? currentPoint : null)].filter(function (d) {return d != null;});\n                });\n            points.enter().append('circle');\n            points.exit().remove();\n            points\n                .attr('cx', function(d,i) { return x(getX(d,d.pointIndex)) })\n                .attr('cy', function(d,i) { return y(getY(d,d.pointIndex)) })\n                .attr('r', 2)\n                .attr('class', function(d,i) {\n                    return getX(d, d.pointIndex) == x.domain()[1] ? 'nv-point nv-currentValue' :\n                            getY(d, d.pointIndex) == y.domain()[0] ? 'nv-point nv-minValue' : 'nv-point nv-maxValue'\n                });\n        });\n        \n        renderWatch.renderEnd('sparkline immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:            {get: function(){return width;}, set: function(_){width=_;}},\n        height:           {get: function(){return height;}, set: function(_){height=_;}},\n        xDomain:          {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:          {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:           {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:           {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        xScale:           {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:           {get: function(){return y;}, set: function(_){y=_;}},\n        animate:          {get: function(){return animate;}, set: function(_){animate=_;}},\n        showMinMaxPoints: {get: function(){return showMinMaxPoints;}, set: function(_){showMinMaxPoints=_;}},\n        showCurrentPoint: {get: function(){return showCurrentPoint;}, set: function(_){showCurrentPoint=_;}},\n\n        //functor options\n        x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},\n        y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    chart.dispatch = dispatch;\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\nnv.models.sparklinePlus = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sparkline = nv.models.sparkline();\n\n    var margin = {top: 15, right: 100, bottom: 10, left: 50}\n        , width = null\n        , height = null\n        , x\n        , y\n        , index = []\n        , paused = false\n        , xTickFormat = d3.format(',r')\n        , yTickFormat = d3.format(',.2f')\n        , showLastValue = true\n        , alignValue = true\n        , rightAlignValue = false\n        , noData = null\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n        \n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(sparkline);\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.call(chart); };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var currentValue = sparkline.y()(data[data.length-1], data.length-1);\n\n            // Setup Scales\n            x = sparkline.xScale();\n            y = sparkline.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-sparklineplus').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparklineplus');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-sparklineWrap');\n            gEnter.append('g').attr('class', 'nv-valueWrap');\n            gEnter.append('g').attr('class', 'nv-hoverArea');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            var sparklineWrap = g.select('.nv-sparklineWrap');\n\n            sparkline.width(availableWidth).height(availableHeight);\n            sparklineWrap.call(sparkline);\n\n            if (showLastValue) {\n                var valueWrap = g.select('.nv-valueWrap');\n                var value = valueWrap.selectAll('.nv-currentValue')\n                    .data([currentValue]);\n\n                value.enter().append('text').attr('class', 'nv-currentValue')\n                    .attr('dx', rightAlignValue ? -8 : 8)\n                    .attr('dy', '.9em')\n                    .style('text-anchor', rightAlignValue ? 'end' : 'start');\n\n                value\n                    .attr('x', availableWidth + (rightAlignValue ? margin.right : 0))\n                    .attr('y', alignValue ? function (d) {\n                        return y(d)\n                    } : 0)\n                    .style('fill', sparkline.color()(data[data.length - 1], data.length - 1))\n                    .text(yTickFormat(currentValue));\n            }\n\n            gEnter.select('.nv-hoverArea').append('rect')\n                .on('mousemove', sparklineHover)\n                .on('click', function() { paused = !paused })\n                .on('mouseout', function() { index = []; updateValueLine(); });\n\n            g.select('.nv-hoverArea rect')\n                .attr('transform', function(d) { return 'translate(' + -margin.left + ',' + -margin.top + ')' })\n                .attr('width', availableWidth + margin.left + margin.right)\n                .attr('height', availableHeight + margin.top);\n\n            //index is currently global (within the chart), may or may not keep it that way\n            function updateValueLine() {\n                if (paused) return;\n\n                var hoverValue = g.selectAll('.nv-hoverValue').data(index);\n\n                var hoverEnter = hoverValue.enter()\n                    .append('g').attr('class', 'nv-hoverValue')\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 0);\n\n                hoverValue.exit()\n                    .transition().duration(250)\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 0)\n                    .remove();\n\n                hoverValue\n                    .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' })\n                    .transition().duration(250)\n                    .style('stroke-opacity', 1)\n                    .style('fill-opacity', 1);\n\n                if (!index.length) return;\n\n                hoverEnter.append('line')\n                    .attr('x1', 0)\n                    .attr('y1', -margin.top)\n                    .attr('x2', 0)\n                    .attr('y2', availableHeight);\n\n                hoverEnter.append('text').attr('class', 'nv-xValue')\n                    .attr('x', -6)\n                    .attr('y', -margin.top)\n                    .attr('text-anchor', 'end')\n                    .attr('dy', '.9em');\n\n                g.select('.nv-hoverValue .nv-xValue')\n                    .text(xTickFormat(sparkline.x()(data[index[0]], index[0])));\n\n                hoverEnter.append('text').attr('class', 'nv-yValue')\n                    .attr('x', 6)\n                    .attr('y', -margin.top)\n                    .attr('text-anchor', 'start')\n                    .attr('dy', '.9em');\n\n                g.select('.nv-hoverValue .nv-yValue')\n                    .text(yTickFormat(sparkline.y()(data[index[0]], index[0])));\n            }\n\n            function sparklineHover() {\n                if (paused) return;\n\n                var pos = d3.mouse(this)[0] - margin.left;\n\n                function getClosestIndex(data, x) {\n                    var distance = Math.abs(sparkline.x()(data[0], 0) - x);\n                    var closestIndex = 0;\n                    for (var i = 0; i < data.length; i++){\n                        if (Math.abs(sparkline.x()(data[i], i) - x) < distance) {\n                            distance = Math.abs(sparkline.x()(data[i], i) - x);\n                            closestIndex = i;\n                        }\n                    }\n                    return closestIndex;\n                }\n\n                index = [getClosestIndex(data, Math.round(x.invert(pos)))];\n                updateValueLine();\n            }\n\n        });\n        renderWatch.renderEnd('sparklinePlus immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.sparkline = sparkline;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:           {get: function(){return width;}, set: function(_){width=_;}},\n        height:          {get: function(){return height;}, set: function(_){height=_;}},\n        xTickFormat:     {get: function(){return xTickFormat;}, set: function(_){xTickFormat=_;}},\n        yTickFormat:     {get: function(){return yTickFormat;}, set: function(_){yTickFormat=_;}},\n        showLastValue:   {get: function(){return showLastValue;}, set: function(_){showLastValue=_;}},\n        alignValue:      {get: function(){return alignValue;}, set: function(_){alignValue=_;}},\n        rightAlignValue: {get: function(){return rightAlignValue;}, set: function(_){rightAlignValue=_;}},\n        noData:          {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, sparkline);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.stackedArea = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , color = nv.utils.defaultColor() // a function that computes the color\n        , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't selet one\n        , container = null\n        , getX = function(d) { return d.x } // accessor to get the x value from a data point\n        , getY = function(d) { return d.y } // accessor to get the y value from a data point\n        , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined\n        , style = 'stack'\n        , offset = 'zero'\n        , order = 'default'\n        , interpolate = 'linear'  // controls the line interpolation\n        , clipEdge = false // if true, masks lines within x and y scale\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , scatter = nv.models.scatter()\n        , duration = 250\n        , dispatch =  d3.dispatch('areaClick', 'areaMouseover', 'areaMouseout','renderEnd', 'elementClick', 'elementMouseover', 'elementMouseout')\n        ;\n\n    scatter\n        .pointSize(2.2) // default size\n        .pointDomain([2.2, 2.2]) // all the same size by default\n    ;\n\n    /************************************\n     * offset:\n     *   'wiggle' (stream)\n     *   'zero' (stacked)\n     *   'expand' (normalize to 100%)\n     *   'silhouette' (simple centered)\n     *\n     * order:\n     *   'inside-out' (stream)\n     *   'default' (input order)\n     ************************************/\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            var dataRaw = data;\n            // Injecting point index into each point because d3.layout.stack().out does not give index\n            data.forEach(function(aseries, i) {\n                aseries.seriesIndex = i;\n                aseries.values = aseries.values.map(function(d, j) {\n                    d.index = j;\n                    d.seriesIndex = i;\n                    return d;\n                });\n            });\n\n            var dataFiltered = data.filter(function(series) {\n                return !series.disabled;\n            });\n\n            data = d3.layout.stack()\n                .order(order)\n                .offset(offset)\n                .values(function(d) { return d.values })  //TODO: make values customizeable in EVERY model in this fashion\n                .x(getX)\n                .y(getY)\n                .out(function(d, y0, y) {\n                    d.display = {\n                        y: y,\n                        y0: y0\n                    };\n                })\n            (dataFiltered);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-stackedarea').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedarea');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-areaWrap');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            \n            // If the user has not specified forceY, make sure 0 is included in the domain\n            // Otherwise, use user-specified values for forceY\n            if (scatter.forceY().length == 0) {\n                scatter.forceY().push(0);\n            }\n            \n            scatter\n                .width(availableWidth)\n                .height(availableHeight)\n                .x(getX)\n                .y(function(d) {\n                    if (d.display !== undefined) { return d.display.y + d.display.y0; }\n                })\n                .color(data.map(function(d,i) {\n                    d.color = d.color || color(d, d.seriesIndex);\n                    return d.color;\n                }));\n\n            var scatterWrap = g.select('.nv-scatterWrap')\n                .datum(data);\n\n            scatterWrap.call(scatter);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect');\n\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            var area = d3.svg.area()\n                .defined(defined)\n                .x(function(d,i)  { return x(getX(d,i)) })\n                .y0(function(d) {\n                    return y(d.display.y0)\n                })\n                .y1(function(d) {\n                    return y(d.display.y + d.display.y0)\n                })\n                .interpolate(interpolate);\n\n            var zeroArea = d3.svg.area()\n                .defined(defined)\n                .x(function(d,i)  { return x(getX(d,i)) })\n                .y0(function(d) { return y(d.display.y0) })\n                .y1(function(d) { return y(d.display.y0) });\n\n            var path = g.select('.nv-areaWrap').selectAll('path.nv-area')\n                .data(function(d) { return d });\n\n            path.enter().append('path').attr('class', function(d,i) { return 'nv-area nv-area-' + i })\n                .attr('d', function(d,i){\n                    return zeroArea(d.values, d.seriesIndex);\n                })\n                .on('mouseover', function(d,i) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.areaMouseover({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.areaMouseout({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                })\n                .on('click', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.areaClick({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                });\n\n            path.exit().remove();\n            path.style('fill', function(d,i){\n                    return d.color || color(d, d.seriesIndex)\n                })\n                .style('stroke', function(d,i){ return d.color || color(d, d.seriesIndex) });\n            path.watchTransition(renderWatch,'stackedArea path')\n                .attr('d', function(d,i) {\n                    return area(d.values,i)\n                });\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            scatter.dispatch.on('elementMouseover.area', function(e) {\n                g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', true);\n            });\n            scatter.dispatch.on('elementMouseout.area', function(e) {\n                g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', false);\n            });\n\n            //Special offset functions\n            chart.d3_stackedOffset_stackPercent = function(stackData) {\n                var n = stackData.length,    //How many series\n                    m = stackData[0].length,     //how many points per series\n                    i,\n                    j,\n                    o,\n                    y0 = [];\n\n                for (j = 0; j < m; ++j) { //Looping through all points\n                    for (i = 0, o = 0; i < dataRaw.length; i++) { //looping through all series\n                        o += getY(dataRaw[i].values[j]); //total y value of all series at a certian point in time.\n                    }\n\n                    if (o) for (i = 0; i < n; i++) { //(total y value of all series at point in time i) != 0\n                        stackData[i][j][1] /= o;\n                    } else { //(total y value of all series at point in time i) == 0\n                        for (i = 0; i < n; i++) {\n                            stackData[i][j][1] = 0;\n                        }\n                    }\n                }\n                for (j = 0; j < m; ++j) y0[j] = 0;\n                return y0;\n            };\n\n        });\n\n        renderWatch.renderEnd('stackedArea immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Global getters and setters\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n\n    scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); });\n\n    chart.interpolate = function(_) {\n        if (!arguments.length) return interpolate;\n        interpolate = _;\n        return chart;\n    };\n\n    chart.duration = function(_) {\n        if (!arguments.length) return duration;\n        duration = _;\n        renderWatch.reset(duration);\n        scatter.duration(duration);\n        return chart;\n    };\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        defined: {get: function(){return defined;}, set: function(_){defined=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        offset:      {get: function(){return offset;}, set: function(_){offset=_;}},\n        order:    {get: function(){return order;}, set: function(_){order=_;}},\n        interpolate:    {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n\n        // simple functor options\n        x:     {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}},\n        y:     {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        style: {get: function(){return style;}, set: function(_){\n            style = _;\n            switch (style) {\n                case 'stack':\n                    chart.offset('zero');\n                    chart.order('default');\n                    break;\n                case 'stream':\n                    chart.offset('wiggle');\n                    chart.order('inside-out');\n                    break;\n                case 'stream-center':\n                    chart.offset('silhouette');\n                    chart.order('inside-out');\n                    break;\n                case 'expand':\n                    chart.offset('expand');\n                    chart.order('default');\n                    break;\n                case 'stack_percent':\n                    chart.offset(chart.d3_stackedOffset_stackPercent);\n                    chart.order('default');\n                    break;\n            }\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            scatter.duration(duration);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.stackedAreaChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var stacked = nv.models.stackedArea()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        , focus = nv.models.focus(nv.models.stackedArea())\n        ;\n\n    var margin = {top: 10, right: 25, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , focusEnable = false\n        , useInteractiveGuideline = false\n        , showTotalInTooltip = true\n        , totalLabel = 'TOTAL'\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        , controlWidth = 250\n        , controlOptions = ['Stacked','Stream','Expanded']\n        , controlLabels = {}\n        , duration = 250\n        ;\n\n    state.style = stacked.style();\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient((rightAlignYAxis) ? 'right' : 'left');\n\n    tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        });\n\n    var oldYTickFormat = null,\n        oldValueFormatter = null;\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    var style = stacked.style();\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                style: stacked.style()\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.style !== undefined)\n                style = state.style;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var percentFormatter = d3.format('%');\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(stacked);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n\n            chart.update = function() { container.transition().duration(duration).call(chart); };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n            // Setup Scales\n            x = stacked.xScale();\n            y = stacked.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedAreaChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-background').append('rect');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y nv-axis');\n            focusEnter.append('g').attr('class', 'nv-stackedWrap');\n            focusEnter.append('g').attr('class', 'nv-interactive');\n\n            // g.select(\"rect\").attr(\"width\",availableWidth).attr(\"height\",availableHeight);\n\n            var contextEnter = gEnter.append('g').attr('class', 'nv-focusWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = (showControls && legendPosition === 'top') ? availableWidth - controlWidth : availableWidth;\n\n                legend.width(legendWidth);\n                g.select('.nv-legendWrap').datum(data).call(legend);\n\n                if (legendPosition === 'bottom') {\n                \tvar xAxisHeight = xAxis.height();\n                   \tmargin.bottom = Math.max(legend.height() + xAxisHeight, margin.bottom);\n                   \tavailableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                \tvar legendTop = availableHeight + xAxisHeight;\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + legendTop +')');\n                } else if (legendPosition === 'top') {\n                    if (!marginTop && margin.top != legend.height()) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                    }\n\n                    g.select('.nv-legendWrap')\n                    \t.attr('transform', 'translate(' + (availableWidth-legendWidth) + ',' + (-margin.top) +')');\n                }\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    {\n                        key: controlLabels.stacked || 'Stacked',\n                        metaKey: 'Stacked',\n                        disabled: stacked.style() != 'stack',\n                        style: 'stack'\n                    },\n                    {\n                        key: controlLabels.stream || 'Stream',\n                        metaKey: 'Stream',\n                        disabled: stacked.style() != 'stream',\n                        style: 'stream'\n                    },\n                    {\n                        key: controlLabels.stream_center || 'Stream Center',\n                        metaKey: 'Stream_Center',\n                        disabled: stacked.style() != 'stream_center',\n                        style: 'stream-center'\n                    },\n                    {\n                        key: controlLabels.expanded || 'Expanded',\n                        metaKey: 'Expanded',\n                        disabled: stacked.style() != 'expand',\n                        style: 'expand'\n                    },\n                    {\n                        key: controlLabels.stack_percent || 'Stack %',\n                        metaKey: 'Stack_Percent',\n                        disabled: stacked.style() != 'stack_percent',\n                        style: 'stack_percent'\n                    }\n                ];\n\n                controlWidth = (controlOptions.length/3) * 260;\n                controlsData = controlsData.filter(function(d) {\n                    return controlOptions.indexOf(d.metaKey) !== -1;\n                });\n\n                controls\n                    .width( controlWidth )\n                    .color(['#444', '#444', '#444']);\n\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .call(controls);\n\n                var requiredTop = Math.max(controls.height(), showLegend && (legendPosition === 'top') ? legend.height() : 0);\n\n                if ( margin.top != requiredTop ) {\n                    margin.top = requiredTop;\n                    availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                }\n\n                g.select('.nv-controlsWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left: margin.left, top: margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            g.select('.nv-focus .nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            stacked\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var stackedWrap = g.select('.nv-focus .nv-stackedWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis.scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight, 0);\n            }\n\n            if (showYAxis) {\n                var ticks;\n                if (stacked.offset() === 'wiggle') {\n                    ticks = 0;\n                }\n                else {\n                    ticks = nv.utils.calcTicksY(availableHeight/36, data);\n                }\n                yAxis.scale(y)\n                    ._ticks(ticks)\n                    .tickSize(-availableWidth, 0);\n            }\n\n            //============================================================\n            // Update Axes\n            //============================================================\n            function updateXAxis() {\n                if(showXAxis) {\n                    g.select('.nv-focus .nv-x.nv-axis')\n                        .attr('transform', 'translate(0,' + availableHeight + ')')\n                        .transition()\n                        .duration(duration)\n                        .call(xAxis)\n                        ;\n                }\n            }\n\n            function updateYAxis() {\n                if(showYAxis) {\n                    if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') {\n                        var currentFormat = yAxis.tickFormat();\n\n                        if ( !oldYTickFormat || currentFormat !== percentFormatter )\n                            oldYTickFormat = currentFormat;\n\n                        //Forces the yAxis to use percentage in 'expand' mode.\n                        yAxis.tickFormat(percentFormatter);\n                    }\n                    else {\n                        if (oldYTickFormat) {\n                            yAxis.tickFormat(oldYTickFormat);\n                            oldYTickFormat = null;\n                        }\n                    }\n\n                    g.select('.nv-focus .nv-y.nv-axis')\n                    .transition().duration(0)\n                    .call(yAxis);\n                }\n            }\n\n            //============================================================\n            // Update Focus\n            //============================================================\n            if(!focusEnable) {\n                stackedWrap.transition().call(stacked);\n                updateXAxis();\n                updateYAxis();\n            } else {\n                focus.width(availableWidth);\n                g.select('.nv-focusWrap')\n                    .attr('transform', 'translate(0,' + ( availableHeight + margin.bottom + focus.margin().top) + ')')\n                    .datum(data.filter(function(d) { return !d.disabled; }))\n                    .call(focus);\n                var extent = focus.brush.empty() ? focus.xDomain() : focus.brush.extent();\n                if(extent !== null){\n                    onBrush(extent);\n                }\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            stacked.dispatch.on('areaClick.toggle', function(e) {\n                if (data.filter(function(d) { return !d.disabled }).length === 1)\n                    data.forEach(function(d) {\n                        d.disabled = false;\n                    });\n                else\n                    data.forEach(function(d,i) {\n                        d.disabled = (i != e.seriesIndex);\n                    });\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n\n                chart.update();\n            });\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                stacked.style(d.style);\n\n\n                state.style = stacked.style();\n                dispatch.stateChange(state);\n\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                stacked.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [], valueSum = 0, allNullValues = true, atleastOnePoint = false;\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        var point = series.values[pointIndex];\n                        var pointYValue = chart.y()(point, pointIndex);\n                        if (pointYValue != null && pointYValue > 0) {\n                            stacked.highlightPoint(i, pointIndex, true);\n                            atleastOnePoint = true;\n                        }\n\n                        // Draw at least one point if all values are zero.\n                        if (i === (data.length - 1) && !atleastOnePoint) {\n                            stacked.highlightPoint(i, pointIndex, true);\n                        }\n                        if (typeof point === 'undefined') return;\n                        if (typeof singlePoint === 'undefined') singlePoint = point;\n                        if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n\n                        //If we are in 'expand' mode, use the stacked percent value instead of raw value.\n                        var tooltipValue = (stacked.style() == 'expand') ? point.display.y : chart.y()(point,pointIndex);\n                        allData.push({\n                            key: series.key,\n                            value: tooltipValue,\n                            color: color(series,series.seriesIndex),\n                            point: point\n                        });\n\n                        if (showTotalInTooltip && stacked.style() != 'expand' && tooltipValue != null) {\n                          valueSum += tooltipValue;\n                          allNullValues = false;\n                        };\n                    });\n\n                allData.reverse();\n\n                //Highlight the tooltip entry based on which stack the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var yDistMax = Infinity, indexToHighlight = null;\n                    allData.forEach(function(series,i) {\n\n                        //To handle situation where the stacked area chart is negative, we need to use absolute values\n                        //when checking if the mouse Y value is within the stack area.\n                        yValue = Math.abs(yValue);\n                        var stackedY0 = Math.abs(series.point.display.y0);\n                        var stackedY = Math.abs(series.point.display.y);\n                        if ( yValue >= stackedY0 && yValue <= (stackedY + stackedY0))\n                        {\n                            indexToHighlight = i;\n                            return;\n                        }\n                    });\n                    if (indexToHighlight != null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                //If we are not in 'expand' mode, add a 'Total' row to the tooltip.\n                if (showTotalInTooltip && stacked.style() != 'expand' && allData.length >= 2 && !allNullValues) {\n                    allData.push({\n                        key: totalLabel,\n                        value: valueSum,\n                        total: true\n                    });\n                }\n\n                var xValue = chart.x()(singlePoint,pointIndex);\n\n                var valueFormatter = interactiveLayer.tooltip.valueFormatter();\n                // Keeps track of the tooltip valueFormatter if the chart changes to expanded view\n                if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') {\n                    if ( !oldValueFormatter ) {\n                        oldValueFormatter = valueFormatter;\n                    }\n                    //Forces the tooltip to use percentage in 'expand' mode.\n                    valueFormatter = d3.format(\".1%\");\n                }\n                else {\n                    if (oldValueFormatter) {\n                        valueFormatter = oldValueFormatter;\n                        oldValueFormatter = null;\n                    }\n                }\n\n                interactiveLayer.tooltip\n                    .valueFormatter(valueFormatter)\n                    .data(\n                    {\n                        value: xValue,\n                        series: allData\n                    }\n                )();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                stacked.clearHighlights();\n            });\n\n            /* Update `main' graph on brush update. */\n            focus.dispatch.on(\"onBrush\", function(extent) {\n                onBrush(extent);\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n\n                if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.style !== 'undefined') {\n                    stacked.style(e.style);\n                    style = e.style;\n                }\n\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            function onBrush(extent) {\n                // Update Main (Focus)\n                var stackedWrap = g.select('.nv-focus .nv-stackedWrap')\n                    .datum(\n                    data.filter(function(d) { return !d.disabled; })\n                        .map(function(d,i) {\n                            return {\n                                key: d.key,\n                                area: d.area,\n                                classed: d.classed,\n                                values: d.values.filter(function(d,i) {\n                                    return stacked.x()(d,i) >= extent[0] && stacked.x()(d,i) <= extent[1];\n                                }),\n                                disableTooltip: d.disableTooltip\n                            };\n                        })\n                );\n                stackedWrap.transition().duration(duration).call(stacked);\n\n                // Update Main (Focus) Axes\n                updateXAxis();\n                updateYAxis();\n            }\n\n        });\n\n        renderWatch.renderEnd('stacked Area chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    stacked.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.point['x'] = stacked.x()(evt.point);\n        evt.point['y'] = stacked.y()(evt.point);\n        tooltip.data(evt).hidden(false);\n    });\n\n    stacked.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.stacked = stacked;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.x2Axis = focus.xAxis;\n    chart.yAxis = yAxis;\n    chart.y2Axis = focus.yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n    chart.focus = focus;\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        showControls:    {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels:    {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        controlOptions:    {get: function(){return controlOptions;}, set: function(_){controlOptions=_;}},\n        showTotalInTooltip:      {get: function(){return showTotalInTooltip;}, set: function(_){showTotalInTooltip=_;}},\n        totalLabel:      {get: function(){return totalLabel;}, set: function(_){totalLabel=_;}},\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:     {get: function(){return focus.height();}, set: function(_){focus.height(_);}},\n        brushExtent: {get: function(){return focus.brushExtent();}, set: function(_){focus.brushExtent(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        focusMargin: {get: function(){return focus.margin}, set: function(_){\n            focus.margin.top    = _.top    !== undefined ? _.top    : focus.margin.top;\n            focus.margin.right  = _.right  !== undefined ? _.right  : focus.margin.right;\n            focus.margin.bottom = _.bottom !== undefined ? _.bottom : focus.margin.bottom;\n            focus.margin.left   = _.left   !== undefined ? _.left   : focus.margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            stacked.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            stacked.color(color);\n            focus.color(color);\n        }},\n        x: {get: function(){return stacked.x();}, set: function(_){\n            stacked.x(_);\n            focus.x(_);\n        }},\n        y: {get: function(){return stacked.y();}, set: function(_){\n            stacked.y(_);\n            focus.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = !!_;\n            chart.interactive(!_);\n            chart.useVoronoi(!_);\n            stacked.scatter.interactive(!_);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, stacked);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.stackedAreaWithFocusChart = function() {\n  return nv.models.stackedAreaChart()\n    .margin({ bottom: 30 })\n    .focusEnable( true );\n};\n// based on http://bl.ocks.org/kerryrodden/477c1bfb081b783f80ad\nnv.models.sunburst = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 600\n        , height = 600\n        , mode = \"count\"\n        , modes = {count: function(d) { return 1; }, value: function(d) { return d.value || d.size }, size: function(d) { return d.value || d.size }}\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , color = nv.utils.defaultColor()\n        , showLabels = false\n        , labelFormat = function(d){if(mode === 'count'){return d.name + ' #' + d.value}else{return d.name + ' ' + (d.value || d.size)}}\n        , labelThreshold = 0.02\n        , sort = function(d1, d2){return d1.name > d2.name;}\n        , key = function(d,i){\n            if (d.parent !== undefined) {\n                return d.name + '-' + d.parent.name + '-' + i;\n            } else {\n                return d.name;\n            }\n        }\n        , groupColorByParent = true\n        , duration = 500\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd');\n\n    //============================================================\n    // aux functions and setup\n    //------------------------------------------------------------\n\n    var x = d3.scale.linear().range([0, 2 * Math.PI]);\n    var y = d3.scale.sqrt();\n\n    var partition = d3.layout.partition().sort(sort);\n\n    var node, availableWidth, availableHeight, radius;\n    var prevPositions = {};\n\n    var arc = d3.svg.arc()\n        .startAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x))) })\n        .endAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))) })\n        .innerRadius(function(d) {return Math.max(0, y(d.y)) })\n        .outerRadius(function(d) {return Math.max(0, y(d.y + d.dy)) });\n\n    function rotationToAvoidUpsideDown(d) {\n        var centerAngle = computeCenterAngle(d);\n        if(centerAngle > 90){\n            return 180;\n        }\n        else {\n            return 0;\n        }\n    }\n\n    function computeCenterAngle(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n        var centerAngle = (((startAngle + endAngle) / 2) * (180 / Math.PI)) - 90;\n        return centerAngle;\n    }\n\n    function computeNodePercentage(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n        return (endAngle - startAngle) / (2 * Math.PI);\n    }\n\n    function labelThresholdMatched(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n\n        var size = endAngle - startAngle;\n        return size > labelThreshold;\n    }\n\n    // When zooming: interpolate the scales.\n    function arcTweenZoom(e,i) {\n        var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]),\n        yd = d3.interpolate(y.domain(), [node.y, 1]),\n        yr = d3.interpolate(y.range(), [node.y ? 20 : 0, radius]);\n\n        if (i === 0) {\n            return function() {return arc(e);}\n        }\n        else {\n            return function (t) {\n                x.domain(xd(t));\n                y.domain(yd(t)).range(yr(t));\n                return arc(e);\n            }\n        };\n    }\n\n    function arcTweenUpdate(d) {\n        var ipo = d3.interpolate({x: d.x0, dx: d.dx0, y: d.y0, dy: d.dy0}, d);\n\n        return function (t) {\n            var b = ipo(t);\n\n            d.x0 = b.x;\n            d.dx0 = b.dx;\n            d.y0 = b.y;\n            d.dy0 = b.dy;\n\n            return arc(b);\n        };\n    }\n\n    function updatePrevPosition(node) {\n        var k = key(node);\n        if(! prevPositions[k]) prevPositions[k] = {};\n        var pP = prevPositions[k];\n        pP.dx = node.dx;\n        pP.x = node.x;\n        pP.dy = node.dy;\n        pP.y = node.y;\n    }\n\n    function storeRetrievePrevPositions(nodes) {\n        nodes.forEach(function(n){\n            var k = key(n);\n            var pP = prevPositions[k];\n            //console.log(k,n,pP);\n            if( pP ){\n                n.dx0 = pP.dx;\n                n.x0 = pP.x;\n                n.dy0 = pP.dy;\n                n.y0 = pP.y;\n            }\n            else {\n                n.dx0 = n.dx;\n                n.x0 = n.x;\n                n.dy0 = n.dy;\n                n.y0 = n.y;\n            }\n            updatePrevPosition(n);\n        });\n    }\n\n    function zoomClick(d) {\n        var labels = container.selectAll('text')\n        var path = container.selectAll('path')\n\n        // fade out all text elements\n        labels.transition().attr(\"opacity\",0);\n\n        // to allow reference to the new center node\n        node = d;\n\n        path.transition()\n            .duration(duration)\n            .attrTween(\"d\", arcTweenZoom)\n            .each('end', function(e) {\n                // partially taken from here: http://bl.ocks.org/metmajer/5480307\n                // check if the animated element's data e lies within the visible angle span given in d\n                if(e.x >= d.x && e.x < (d.x + d.dx) ){\n                    if(e.depth >= d.depth){\n                        // get a selection of the associated text element\n                        var parentNode = d3.select(this.parentNode);\n                        var arcText = parentNode.select('text');\n\n                        // fade in the text element and recalculate positions\n                        arcText.transition().duration(duration)\n                        .text( function(e){return labelFormat(e) })\n                        .attr(\"opacity\", function(d){\n                            if(labelThresholdMatched(d)) {\n                                return 1;\n                            }\n                            else {\n                                return 0;\n                            }\n                        })\n                        .attr(\"transform\", function() {\n                            var width = this.getBBox().width;\n                            if(e.depth === 0)\n                            return \"translate(\" + (width / 2 * - 1) + \",0)\";\n                            else if(e.depth === d.depth){\n                                return \"translate(\" + (y(e.y) + 5) + \",0)\";\n                            }\n                            else {\n                                var centerAngle = computeCenterAngle(e);\n                                var rotation = rotationToAvoidUpsideDown(e);\n                                if (rotation === 0) {\n                                    return 'rotate('+ centerAngle +')translate(' + (y(e.y) + 5) + ',0)';\n                                }\n                                else {\n                                    return 'rotate('+ centerAngle +')translate(' + (y(e.y) + width + 5) + ',0)rotate(' + rotation + ')';\n                                }\n                            }\n                        });\n                    }\n                }\n            })\n    }\n\n    //============================================================\n    // chart function\n    //------------------------------------------------------------\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n\n        selection.each(function(data) {\n            container = d3.select(this);\n            availableWidth = nv.utils.availableWidth(width, container, margin);\n            availableHeight = nv.utils.availableHeight(height, container, margin);\n            radius = Math.min(availableWidth, availableHeight) / 2;\n\n            y.range([0, radius]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.select('g.nvd3.nv-wrap.nv-sunburst');\n            if( !wrap[0][0] ) {\n                wrap = container.append('g')\n                    .attr('class', 'nvd3 nv-wrap nv-sunburst nv-chart-' + id)\n                    .attr('transform', 'translate(' + ((availableWidth / 2) + margin.left + margin.right) + ',' + ((availableHeight / 2) + margin.top + margin.bottom) + ')');\n            } else {\n                wrap.attr('transform', 'translate(' + ((availableWidth / 2) + margin.left + margin.right) + ',' + ((availableHeight / 2) + margin.top + margin.bottom) + ')');\n            }\n\n            container.on('click', function (d, i) {\n                dispatch.chartClick({\n                    data: d,\n                    index: i,\n                    pos: d3.event,\n                    id: id\n                });\n            });\n\n            partition.value(modes[mode] || modes[\"count\"]);\n\n            //reverse the drawing order so that the labels of inner\n            //arcs are drawn on top of the outer arcs.\n            var nodes = partition.nodes(data[0]).reverse()\n\n            storeRetrievePrevPositions(nodes);\n            var cG = wrap.selectAll('.arc-container').data(nodes, key)\n\n            //handle new datapoints\n            var cGE = cG.enter()\n                .append(\"g\")\n                .attr(\"class\",'arc-container')\n\n            cGE.append(\"path\")\n                .attr(\"d\", arc)\n                .style(\"fill\", function (d) {\n                    if (d.color) {\n                        return d.color;\n                    }\n                    else if (groupColorByParent) {\n                        return color((d.children ? d : d.parent).name);\n                    }\n                    else {\n                        return color(d.name);\n                    }\n                })\n                .style(\"stroke\", \"#FFF\")\n                .on(\"click\", function(d,i){\n                    zoomClick(d);\n                    dispatch.elementClick({\n                        data: d,\n                        index: i\n                    })\n                })\n                .on('mouseover', function(d,i){\n                    d3.select(this).classed('hover', true).style('opacity', 0.8);\n                    dispatch.elementMouseover({\n                        data: d,\n                        color: d3.select(this).style(\"fill\"),\n                        percent: computeNodePercentage(d)\n                    });\n                })\n                .on('mouseout', function(d,i){\n                    d3.select(this).classed('hover', false).style('opacity', 1);\n                    dispatch.elementMouseout({\n                        data: d\n                    });\n                })\n                .on('mousemove', function(d,i){\n                    dispatch.elementMousemove({\n                        data: d\n                    });\n                });\n\n            ///Iterating via each and selecting based on the this\n            ///makes it work ... a cG.selectAll('path') doesn't.\n            ///Without iteration the data (in the element) didn't update.\n            cG.each(function(d){\n                d3.select(this).select('path')\n                    .transition()\n                    .duration(duration)\n                    .attrTween('d', arcTweenUpdate);\n            });\n\n            if(showLabels){\n                //remove labels first and add them back\n                cG.selectAll('text').remove();\n\n                //this way labels are on top of newly added arcs\n                cG.append('text')\n                    .text( function(e){ return labelFormat(e)})\n                    .transition()\n                    .duration(duration)\n                    .attr(\"opacity\", function(d){\n                        if(labelThresholdMatched(d)) {\n                            return 1;\n                        }\n                        else {\n                            return 0;\n                        }\n                    })\n                    .attr(\"transform\", function(d) {\n                        var width = this.getBBox().width;\n                        if(d.depth === 0){\n                            return \"rotate(0)translate(\" + (width / 2 * -1) + \",0)\";\n                        }\n                        else {\n                            var centerAngle = computeCenterAngle(d);\n                            var rotation = rotationToAvoidUpsideDown(d);\n                            if (rotation === 0) {\n                                return 'rotate('+ centerAngle +')translate(' + (y(d.y) + 5) + ',0)';\n                            }\n                            else {\n                                return 'rotate('+ centerAngle +')translate(' + (y(d.y) + width + 5) + ',0)rotate(' + rotation + ')';\n                            }\n                        }\n                    });\n            }\n\n            //zoom out to the center when the data is updated.\n            zoomClick(nodes[nodes.length - 1])\n\n\n            //remove unmatched elements ...\n            cG.exit()\n                .transition()\n                .duration(duration)\n                .attr('opacity',0)\n                .each('end',function(d){\n                    var k = key(d);\n                    prevPositions[k] = undefined;\n                })\n                .remove();\n        });\n\n\n        renderWatch.renderEnd('sunburst immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        mode:       {get: function(){return mode;}, set: function(_){mode=_;}},\n        id:         {get: function(){return id;}, set: function(_){id=_;}},\n        duration:   {get: function(){return duration;}, set: function(_){duration=_;}},\n        groupColorByParent: {get: function(){return groupColorByParent;}, set: function(_){groupColorByParent=!!_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=!!_}},\n        labelFormat: {get: function(){return labelFormat;}, set: function(_){labelFormat=_}},\n        labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_}},\n        sort: {get: function(){return sort;}, set: function(_){sort=_}},\n        key: {get: function(){return key;}, set: function(_){key=_}},\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color=nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\nnv.models.sunburstChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sunburst = nv.models.sunburst();\n    var tooltip = nv.models.tooltip();\n\n    var margin = {top: 30, right: 20, bottom: 20, left: 20}\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showTooltipPercent = false\n        , id = Math.round(Math.random() * 100000)\n        , defaultState = null\n        , noData = null\n        , duration = 250\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd');\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d){return d;});\n\n    //============================================================\n    // Chart function\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(sunburst);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin);\n            var availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0) {\n                    container.call(chart);\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = container;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            sunburst.width(availableWidth).height(availableHeight).margin(margin);\n            container.call(sunburst);\n        });\n\n        renderWatch.renderEnd('sunburstChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    sunburst.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.series = {\n            key: evt.data.name,\n            value: (evt.data.value || evt.data.size),\n            color: evt.color,\n            percent: evt.percent\n        };\n        if (!showTooltipPercent) {\n            delete evt.percent;\n            delete evt.series.percent;\n        }\n        tooltip.data(evt).hidden(false);\n    });\n\n    sunburst.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    sunburst.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.sunburst = sunburst;\n    chart.tooltip = tooltip;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // use Object get/set functionality to map between vars and chart functions\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        noData:             {get: function(){return noData;},               set: function(_){noData=_;}},\n        defaultState:       {get: function(){return defaultState;},         set: function(_){defaultState=_;}},\n        showTooltipPercent: {get: function(){return showTooltipPercent;},   set: function(_){showTooltipPercent=_;}},\n\n        // options that require extra logic in the setter\n        color: {get: function(){return color;}, set: function(_){\n            color = _;\n            sunburst.color(color);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            sunburst.duration(duration);\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n            sunburst.margin(margin);\n        }}\n    });\n    nv.utils.inheritOptions(chart, sunburst);\n    nv.utils.initOptions(chart);\n    return chart;\n\n};\n\nnv.version = \"1.8.6-dev\";\n})();\n//# sourceMappingURL=nv.d3.js.map"
  },
  {
    "path": "composer.json",
    "content": "{\n  \"name\": \"novus/nvd3\",\n  \"description\": \"A reusable charting library written in d3.js\",\n  \"keywords\": [\n    \"nvd3\",\n    \"d3\",\n    \"chart\",\n    \"graph\"\n  ],\n  \"homepage\": \"https://github.com/novus/nvd3\",\n  \"license\": \"Apache-2.0\",\n  \"authors\": [\n    {\n      \"name\": \"Bob Monteverde\"\n    },\n    {\n      \"name\": \"Tyler Wolf\"\n    },\n    {\n      \"name\": \"Robin Hu\"\n    },\n    {\n      \"name\": \"Frank Shao\"\n    },\n    {\n      \"name\": \"liquidpele\"\n    }\n  ],\n  \"require\": {\n    \"mbostock/d3\": \"@stable\"\n  }\n}"
  },
  {
    "path": "examples/TimeSeries.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        .spaced {\n            float: left;\n            margin: 10px 0 10px 10px;\n        }\n        .svg-container {\n            display: block;\n            position: absolute;\n            top: 30px;\n            left: 0;\n            right: 0;\n            bottom: 0;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n        .nvd3 line.nv-guideline { /* Hide the guideline */\n            display: none;\n            stroke-width: 0.0;\n        }\n\n        .nvd3 .nv-bars rect { /* fix the hover guideline to be snappy */\n            transition: fill-opacity 0ms linear;\n            -moz-transition: fill-opacity 0ms linear;\n            -webkit-transition: fill-opacity 0ms linear;\n        }\n\n        .nvd3 .nv-x .nv-axis .x-axis-tick-mark {\n            stroke: #000; /* black tick marks */\n        }\n\n        .nvd3 .nv-y .nv-axis .tick.zero line {\n            stroke: #000; /* black line for the x axis */\n        }\n\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<button class=\"spaced\" onClick=\"switchChartStyle('instant')\">Bars represents points in time</button>\n<button class=\"spaced\" onClick=\"switchChartStyle('timespan')\">Bars represent spans of time</button>\n<div class=\"spaced\" style=\"float: left;\">(affects the x axis ticks and the bar spacing)</div>\n\n<div style=\"clear: both;\"></div>\n\n<div class=\"svg-container\" id=\"sc-one\">\n    <svg id=\"test1\"></svg>\n</div>\n<div class=\"svg-container\" id=\"sc-two\">\n    <svg id=\"test2\"></svg>\n</div>\n\n<script>\n\n    var data = [{\n        values : []\n    }];\n\n    var i, x;\n    var gap = false;\n    var prevVal = 3000;\n    var tickCount = 100;\n    var probEnterGap = 0.1;\n    var probExitGap = 0.2;\n    var barTimespan = 30 * 60; // thirty minutes in seconds\n    var startOfTime = 1425096000;\n    for (i = 0; i < tickCount; i++) {\n        x = startOfTime + i * barTimespan;\n        if (!gap) {\n            if (Math.random() > probEnterGap) {\n                prevVal += (Math.random() - 0.5) * 500;\n                if (prevVal <= 0) {\n                    prevVal = Math.random() * 100;\n                }\n                data[0].values.push({x: x * 1000, y: prevVal});\n            }\n            else {\n                gap = true;\n            }\n        }\n        else {\n            if (Math.random() < probExitGap) {\n                gap = false;\n            }\n        }\n    }\n\n    var chart;\n\n    var halfBarXMin = data[0].values[0].x - barTimespan / 2 * 1000;\n    var halfBarXMax = data[0].values[data[0].values.length-1].x + barTimespan / 2 * 1000;\n\n    function renderChart(location, meaning) {\n        nv.addGraph(function() {\n            chart = nv.models.historicalBarChart();\n            chart\n                .xScale(d3.time.scale()) // use a time scale instead of plain numbers in order to get nice round default values in the axis\n                .color(['#68c'])\n                .forceX([halfBarXMin, halfBarXMax]) // fix half-bar problem on the first and last bars\n                .useInteractiveGuideline(true) // check out the css that turns the guideline into this nice thing\n                .margin({\"left\": 80, \"right\": 50, \"top\": 20, \"bottom\": 30})\n                .duration(0)\n            ;\n\n            var tickMultiFormat = d3.time.format.multi([\n                [\"%-I:%M%p\", function(d) { return d.getMinutes(); }], // not the beginning of the hour\n                [\"%-I%p\", function(d) { return d.getHours(); }], // not midnight\n                [\"%b %-d\", function(d) { return d.getDate() != 1; }], // not the first of the month\n                [\"%b %-d\", function(d) { return d.getMonth(); }], // not Jan 1st\n                [\"%Y\", function() { return true; }]\n            ]);\n            chart.xAxis\n                    .showMaxMin(false)\n                    .tickPadding(10)\n                    .tickFormat(function (d) { return tickMultiFormat(new Date(d)); })\n            ;\n\n            chart.yAxis\n                    .showMaxMin(false)\n                    .tickFormat(d3.format(\",.0f\"))\n            ;\n\n            var svgElem = d3.select(location);\n            svgElem\n                    .datum(data)\n                    .transition()\n                    .call(chart);\n\n            // make our own x-axis tick marks because NVD3 doesn't provide any\n            var tickY2 = chart.yAxis.scale().range()[1];\n            var lineElems = svgElem\n                            .select('.nv-x.nv-axis.nvd3-svg')\n                            .select('.nvd3.nv-wrap.nv-axis')\n                            .select('g')\n                            .selectAll('.tick')\n                            .data(chart.xScale().ticks())\n                            .append('line')\n                            .attr('class', 'x-axis-tick-mark')\n                            .attr('x2', 0)\n                            .attr('y1', tickY2 + 4)\n                            .attr('y2', tickY2)\n                            .attr('stroke-width', 1)\n                    ;\n\n            // set up the tooltip to display full dates\n            var tsFormat = d3.time.format('%b %-d, %Y %I:%M%p');\n            var contentGenerator = chart.interactiveLayer.tooltip.contentGenerator();\n            var tooltip = chart.interactiveLayer.tooltip;\n            tooltip.contentGenerator(function (d) { d.value = d.series[0].data.x; return contentGenerator(d); });\n            tooltip.headerFormatter(function (d) { return tsFormat(new Date(d)); });\n\n            // common stuff for the sections below\n            var xScale = chart.xScale();\n            var xPixelFirstBar = xScale(data[0].values[0].x);\n            var xPixelSecondBar = xScale(data[0].values[0].x + barTimespan * 1000);\n            var barWidth = xPixelSecondBar - xPixelFirstBar; // number of pixels representing time delta per bar\n\n            // fix the bar widths so they don't overlap when there are gaps\n            function fixBarWidths(barSpacingFraction) {\n                svgElem\n                    .selectAll('.nv-bars')\n                    .selectAll('rect')\n                    .attr('width', (1 - barSpacingFraction) * barWidth)\n                    .attr('transform', function(d, i) {\n                        var deltaX = xScale(data[0].values[i].x) - xPixelFirstBar;\n                        deltaX += barSpacingFraction / 2 * barWidth;\n                        return 'translate(' + deltaX + ', 0)';\n                    })\n                    ;\n            }\n\n            /*\n            If you're representing sample measurements spaced a certain time apart, the tick marks should\n            be in the middle of the bars and some spacing between bars is recommended to aid with interpretation.\n            On the other hand, if you want to represent a quantity measured over a span of time (one bar), you're\n            better off placing the ticks on the edge of the bar and leaving no gap in between bars.\n            */\n            function shiftXAxis() {\n                var xAxisElem = svgElem.select('.nv-axis.nv-x');\n                var transform = xAxisElem.attr('transform');\n                var xShift = -barWidth/2;\n                transform = transform.replace('0,', xShift + ',');\n                xAxisElem.attr('transform', transform);\n            }\n\n            if (meaning === 'instant') {\n                fixBarWidths(0.2);\n            }\n            else if (meaning === 'timespan') {\n                fixBarWidths(0.0);\n                shiftXAxis();\n            }\n\n            return chart;\n        });\n    }\n\n    renderChart('#test1', 'instant');\n    renderChart('#test2', 'timespan');\n\n    window.setTimeout(function() {\n        window.setTimeout(function() {\n            document.getElementById('sc-one').style.display = 'block';\n            document.getElementById('sc-two').style.display = 'none';\n        }, 0);\n    }, 0);\n\n    function switchChartStyle(style) {\n        if (style === 'instant') {\n            document.getElementById('sc-one').style.display = 'block';\n            document.getElementById('sc-two').style.display = 'none';\n        }\n        else if (style === 'timespan') {\n            document.getElementById('sc-one').style.display = 'none';\n            document.getElementById('sc-two').style.display = 'block';\n        }\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/actual.json",
    "content": "[{\"key\":{\"measurement_point\":\"elec_energy_consumed\",\"units\":\"kWh\",\"interval_length\":30,\"timezone\":\"Asia/Tokyo\"},\"values\":[{\"recorded_at\":\"2017-07-01T00:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T01:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T01:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T02:00:00+0900\",\"value\":40.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T02:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T03:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T03:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T04:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T04:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T05:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T05:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T06:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T06:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T07:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T07:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T08:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T08:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T09:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T09:30:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T10:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T10:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T11:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T11:30:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T12:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T12:30:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T13:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T13:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T14:00:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T14:30:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T15:00:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T15:30:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T16:00:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T16:30:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T17:00:00+0900\",\"value\":93.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T17:30:00+0900\",\"value\":93.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T18:00:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T18:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T19:00:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T19:30:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T20:00:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T20:30:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T21:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T21:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T22:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T22:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T23:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-01T23:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T00:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T00:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T01:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T01:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T02:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T02:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T03:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T03:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T04:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T04:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T05:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T05:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T06:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T06:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T07:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T07:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T08:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T08:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T09:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T09:30:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T10:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T10:30:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T11:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T11:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T12:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T12:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T13:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T13:30:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T14:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T14:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T15:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T15:30:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T16:00:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T16:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T17:00:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T17:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T18:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T18:30:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T19:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T19:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T20:00:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T20:30:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T21:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T21:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T22:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T22:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T23:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-02T23:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T00:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T00:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T01:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T01:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T02:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T02:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T03:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T03:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T04:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T04:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T05:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T06:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T06:30:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T07:00:00+0900\",\"value\":124.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T07:30:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T08:00:00+0900\",\"value\":136.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T08:30:00+0900\",\"value\":166.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T09:00:00+0900\",\"value\":196.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T09:30:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T10:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T10:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T11:00:00+0900\",\"value\":235.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T11:30:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T12:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T12:30:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T13:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T13:30:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T14:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T14:30:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T15:00:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T15:30:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T16:00:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T16:30:00+0900\",\"value\":228.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T17:00:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T17:30:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T18:00:00+0900\",\"value\":198.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T18:30:00+0900\",\"value\":169.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T19:00:00+0900\",\"value\":155.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T19:30:00+0900\",\"value\":138.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T20:00:00+0900\",\"value\":141.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T20:30:00+0900\",\"value\":131.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T21:00:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T21:30:00+0900\",\"value\":105.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T22:00:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T22:30:00+0900\",\"value\":87.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T23:00:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-03T23:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T00:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T00:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T01:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T01:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T02:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T02:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T03:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T03:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T04:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T04:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T05:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T05:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T06:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T06:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T07:00:00+0900\",\"value\":100.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T07:30:00+0900\",\"value\":96.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T08:00:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T08:30:00+0900\",\"value\":162.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T09:00:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T09:30:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T10:00:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T10:30:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T11:00:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T11:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T12:00:00+0900\",\"value\":210.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T12:30:00+0900\",\"value\":197.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T13:00:00+0900\",\"value\":188.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T13:30:00+0900\",\"value\":200.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T14:00:00+0900\",\"value\":193.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T14:30:00+0900\",\"value\":191.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T15:00:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T15:30:00+0900\",\"value\":202.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T16:00:00+0900\",\"value\":193.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T16:30:00+0900\",\"value\":187.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T17:00:00+0900\",\"value\":187.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T17:30:00+0900\",\"value\":183.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T18:00:00+0900\",\"value\":180.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T18:30:00+0900\",\"value\":155.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T19:00:00+0900\",\"value\":134.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T19:30:00+0900\",\"value\":117.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T20:00:00+0900\",\"value\":115.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T20:30:00+0900\",\"value\":114.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T21:00:00+0900\",\"value\":108.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T21:30:00+0900\",\"value\":100.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T22:00:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T22:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T23:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-04T23:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T00:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T00:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T01:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T01:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T02:00:00+0900\",\"value\":40.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T02:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T03:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T03:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T04:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T04:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T05:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T05:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T06:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T06:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T07:00:00+0900\",\"value\":94.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T07:30:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T08:00:00+0900\",\"value\":104.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T08:30:00+0900\",\"value\":138.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T09:00:00+0900\",\"value\":173.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T09:30:00+0900\",\"value\":195.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T10:00:00+0900\",\"value\":192.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T10:30:00+0900\",\"value\":202.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T11:00:00+0900\",\"value\":193.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T11:30:00+0900\",\"value\":196.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T12:00:00+0900\",\"value\":194.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T12:30:00+0900\",\"value\":188.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T13:00:00+0900\",\"value\":177.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T13:30:00+0900\",\"value\":191.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T14:00:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T14:30:00+0900\",\"value\":189.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T15:00:00+0900\",\"value\":191.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T15:30:00+0900\",\"value\":194.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T16:00:00+0900\",\"value\":193.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T16:30:00+0900\",\"value\":192.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T17:00:00+0900\",\"value\":186.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T17:30:00+0900\",\"value\":185.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T18:00:00+0900\",\"value\":183.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T18:30:00+0900\",\"value\":155.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T19:00:00+0900\",\"value\":140.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T19:30:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T20:00:00+0900\",\"value\":112.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T20:30:00+0900\",\"value\":106.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T21:00:00+0900\",\"value\":101.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T21:30:00+0900\",\"value\":96.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T22:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T22:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T23:00:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-05T23:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T00:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T00:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T01:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T01:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T02:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T02:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T03:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T03:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T04:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T04:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T05:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T05:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T06:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T06:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T07:00:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T07:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T08:00:00+0900\",\"value\":111.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T08:30:00+0900\",\"value\":145.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T09:00:00+0900\",\"value\":173.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T09:30:00+0900\",\"value\":185.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T10:00:00+0900\",\"value\":187.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T10:30:00+0900\",\"value\":196.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T11:00:00+0900\",\"value\":200.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T11:30:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T12:00:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T12:30:00+0900\",\"value\":198.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T13:00:00+0900\",\"value\":191.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T13:30:00+0900\",\"value\":197.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T14:00:00+0900\",\"value\":195.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T14:30:00+0900\",\"value\":200.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T15:00:00+0900\",\"value\":204.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T15:30:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T16:00:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T16:30:00+0900\",\"value\":206.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T17:00:00+0900\",\"value\":204.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T17:30:00+0900\",\"value\":213.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T18:00:00+0900\",\"value\":197.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T18:30:00+0900\",\"value\":163.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T19:00:00+0900\",\"value\":149.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T19:30:00+0900\",\"value\":125.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T20:00:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T20:30:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T21:00:00+0900\",\"value\":113.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T21:30:00+0900\",\"value\":100.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T22:00:00+0900\",\"value\":93.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T22:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T23:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-06T23:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T00:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T00:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T01:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T01:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T02:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T02:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T03:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T03:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T04:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T04:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T05:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T05:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T06:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T06:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T07:00:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T07:30:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T08:00:00+0900\",\"value\":106.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T08:30:00+0900\",\"value\":140.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T09:00:00+0900\",\"value\":176.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T09:30:00+0900\",\"value\":185.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T10:00:00+0900\",\"value\":192.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T10:30:00+0900\",\"value\":201.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T11:00:00+0900\",\"value\":202.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T11:30:00+0900\",\"value\":194.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T12:00:00+0900\",\"value\":196.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T12:30:00+0900\",\"value\":195.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T13:00:00+0900\",\"value\":183.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T13:30:00+0900\",\"value\":203.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T14:00:00+0900\",\"value\":202.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T14:30:00+0900\",\"value\":194.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T15:00:00+0900\",\"value\":206.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T15:30:00+0900\",\"value\":206.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T16:00:00+0900\",\"value\":199.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T16:30:00+0900\",\"value\":194.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T17:00:00+0900\",\"value\":198.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T17:30:00+0900\",\"value\":208.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T18:00:00+0900\",\"value\":195.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T18:30:00+0900\",\"value\":162.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T19:00:00+0900\",\"value\":139.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T19:30:00+0900\",\"value\":124.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T20:00:00+0900\",\"value\":117.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T20:30:00+0900\",\"value\":107.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T21:00:00+0900\",\"value\":103.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T21:30:00+0900\",\"value\":100.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T22:00:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T22:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T23:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-07T23:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T00:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T00:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T01:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T01:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T02:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T02:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T03:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T03:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T04:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T04:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T05:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T05:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T06:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T06:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T07:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T07:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T08:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T08:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T09:00:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T09:30:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T10:00:00+0900\",\"value\":87.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T10:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T11:00:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T11:30:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T12:00:00+0900\",\"value\":85.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T12:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T13:00:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T13:30:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T14:00:00+0900\",\"value\":94.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T14:30:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T15:00:00+0900\",\"value\":93.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T15:30:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T16:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T16:30:00+0900\",\"value\":87.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T17:00:00+0900\",\"value\":85.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T17:30:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T18:00:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T18:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T19:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T19:30:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T20:00:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T20:30:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T21:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T21:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T22:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T22:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T23:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-08T23:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T00:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T00:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T01:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T01:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T02:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T02:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T03:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T03:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T04:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T04:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T05:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T05:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T06:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T06:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T07:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T07:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T08:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T08:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T09:00:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T09:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T10:00:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T10:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T11:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T11:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T12:00:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T12:30:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T13:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T13:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T14:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T14:30:00+0900\",\"value\":87.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T15:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T15:30:00+0900\",\"value\":85.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T16:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T16:30:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T17:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T17:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T18:00:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T18:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T19:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T19:30:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T20:00:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T20:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T21:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T21:30:00+0900\",\"value\":55.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T22:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T22:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T23:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-09T23:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T00:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T00:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T01:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T01:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T02:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T02:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T03:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T03:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T04:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T04:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T05:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T06:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T06:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T07:00:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T07:30:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T08:00:00+0900\",\"value\":116.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T08:30:00+0900\",\"value\":150.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T09:00:00+0900\",\"value\":201.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T09:30:00+0900\",\"value\":213.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T10:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T10:30:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T11:00:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T11:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T12:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T12:30:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T13:00:00+0900\",\"value\":207.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T13:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T14:00:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T14:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T15:00:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T15:30:00+0900\",\"value\":234.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T16:00:00+0900\",\"value\":240.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T16:30:00+0900\",\"value\":243.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T17:00:00+0900\",\"value\":233.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T17:30:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T18:00:00+0900\",\"value\":214.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T18:30:00+0900\",\"value\":176.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T19:00:00+0900\",\"value\":163.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T19:30:00+0900\",\"value\":141.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T20:00:00+0900\",\"value\":137.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T20:30:00+0900\",\"value\":134.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T21:00:00+0900\",\"value\":130.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T21:30:00+0900\",\"value\":116.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T22:00:00+0900\",\"value\":109.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T22:30:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T23:00:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-10T23:30:00+0900\",\"value\":63.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T00:00:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T00:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T01:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T01:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T02:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T02:30:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T03:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T03:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T04:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T04:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T05:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T05:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T06:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T06:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T07:00:00+0900\",\"value\":102.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T07:30:00+0900\",\"value\":96.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T08:00:00+0900\",\"value\":125.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T08:30:00+0900\",\"value\":159.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T09:00:00+0900\",\"value\":201.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T09:30:00+0900\",\"value\":212.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T10:00:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T10:30:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T11:00:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T11:30:00+0900\",\"value\":233.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T12:00:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T12:30:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T13:00:00+0900\",\"value\":207.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T13:30:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T14:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T14:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T15:00:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T15:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T16:00:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T16:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T17:00:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T17:30:00+0900\",\"value\":243.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T18:00:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T18:30:00+0900\",\"value\":191.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T19:00:00+0900\",\"value\":175.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T19:30:00+0900\",\"value\":145.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T20:00:00+0900\",\"value\":141.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T20:30:00+0900\",\"value\":132.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T21:00:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T21:30:00+0900\",\"value\":108.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T22:00:00+0900\",\"value\":94.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T22:30:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T23:00:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-11T23:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T00:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T00:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T01:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T01:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T02:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T02:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T03:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T03:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T04:00:00+0900\",\"value\":41.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T04:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T05:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T05:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T06:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T06:30:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T07:00:00+0900\",\"value\":116.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T07:30:00+0900\",\"value\":106.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T08:00:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T08:30:00+0900\",\"value\":163.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T09:00:00+0900\",\"value\":204.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T09:30:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T10:00:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T10:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T11:00:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T11:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T12:00:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T12:30:00+0900\",\"value\":204.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T13:00:00+0900\",\"value\":208.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T13:30:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T14:00:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T14:30:00+0900\",\"value\":228.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T15:00:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T15:30:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T16:00:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T16:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T17:00:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T17:30:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T18:00:00+0900\",\"value\":206.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T18:30:00+0900\",\"value\":176.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T19:00:00+0900\",\"value\":158.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T19:30:00+0900\",\"value\":133.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T20:00:00+0900\",\"value\":128.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T20:30:00+0900\",\"value\":120.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T21:00:00+0900\",\"value\":110.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T21:30:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T22:00:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T22:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T23:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-12T23:30:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T00:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T00:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T01:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T01:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T02:00:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T02:30:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T03:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T03:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T04:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T04:30:00+0900\",\"value\":42.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T05:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T05:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T06:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T06:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T07:00:00+0900\",\"value\":108.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T07:30:00+0900\",\"value\":108.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T08:00:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T08:30:00+0900\",\"value\":155.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T09:00:00+0900\",\"value\":200.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T09:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T10:00:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T10:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T11:00:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T11:30:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T12:00:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T12:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T13:00:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T13:30:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T14:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T14:30:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T15:00:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T15:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T16:00:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T16:30:00+0900\",\"value\":240.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T17:00:00+0900\",\"value\":228.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T17:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T18:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T18:30:00+0900\",\"value\":206.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T19:00:00+0900\",\"value\":183.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T19:30:00+0900\",\"value\":152.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T20:00:00+0900\",\"value\":156.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T20:30:00+0900\",\"value\":150.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T21:00:00+0900\",\"value\":132.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T21:30:00+0900\",\"value\":109.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T22:00:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T22:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T23:00:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-13T23:30:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T00:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T00:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T01:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T01:30:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T02:00:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T02:30:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T03:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T03:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T04:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T04:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T05:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T05:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T06:00:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T06:30:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T07:00:00+0900\",\"value\":117.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T07:30:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T08:00:00+0900\",\"value\":135.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T08:30:00+0900\",\"value\":159.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T09:00:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T09:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T10:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T10:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T11:00:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T11:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T12:00:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T12:30:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T13:00:00+0900\",\"value\":209.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T13:30:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T14:00:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T14:30:00+0900\",\"value\":214.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T15:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T15:30:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T16:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T16:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T17:00:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T17:30:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T18:00:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T18:30:00+0900\",\"value\":179.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T19:00:00+0900\",\"value\":149.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T19:30:00+0900\",\"value\":127.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T20:00:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T20:30:00+0900\",\"value\":105.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T21:00:00+0900\",\"value\":97.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T21:30:00+0900\",\"value\":85.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T22:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T22:30:00+0900\",\"value\":62.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T23:00:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-14T23:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T00:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T00:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T01:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T01:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T02:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T02:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T03:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T03:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T04:00:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T04:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T05:00:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T05:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T06:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T06:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T07:00:00+0900\",\"value\":55.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T07:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T08:00:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T08:30:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T09:00:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T09:30:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T10:00:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T10:30:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T11:00:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T11:30:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T12:00:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T12:30:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T13:00:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T13:30:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T14:00:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T14:30:00+0900\",\"value\":91.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T15:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T15:30:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T16:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T16:30:00+0900\",\"value\":87.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T17:00:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T17:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T18:00:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T18:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T19:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T19:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T20:00:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T20:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T21:00:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T21:30:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T22:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T22:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T23:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-15T23:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T00:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T00:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T01:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T01:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T02:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T02:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T03:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T03:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T04:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T04:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T05:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T05:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T06:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T06:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T07:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T07:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T08:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T08:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T09:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T09:30:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T10:00:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T10:30:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T11:00:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T11:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T12:00:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T12:30:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T13:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T13:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T14:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T14:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T15:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T15:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T16:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T16:30:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T17:00:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T17:30:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T18:00:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T18:30:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T19:00:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T19:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T20:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T20:30:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T21:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T21:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T22:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T22:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T23:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-16T23:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T00:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T00:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T01:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T01:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T02:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T02:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T03:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T03:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T04:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T04:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T05:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T05:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T06:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T06:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T07:00:00+0900\",\"value\":99.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T07:30:00+0900\",\"value\":62.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T08:00:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T08:30:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T09:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T09:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T10:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T10:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T11:00:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T11:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T12:00:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T12:30:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T13:00:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T13:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T14:00:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T14:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T15:00:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T15:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T16:00:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T16:30:00+0900\",\"value\":76.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T17:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T17:30:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T18:00:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T18:30:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T19:00:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T19:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T20:00:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T20:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T21:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T21:30:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T22:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T22:30:00+0900\",\"value\":55.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T23:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-17T23:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T00:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T00:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T01:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T01:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T02:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T02:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T03:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T03:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T04:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T04:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T05:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T05:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T06:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T06:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T07:00:00+0900\",\"value\":121.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T07:30:00+0900\",\"value\":130.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T08:00:00+0900\",\"value\":156.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T08:30:00+0900\",\"value\":195.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T09:00:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T09:30:00+0900\",\"value\":262.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T10:00:00+0900\",\"value\":262.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T10:30:00+0900\",\"value\":246.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T11:00:00+0900\",\"value\":236.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T11:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T12:00:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T12:30:00+0900\",\"value\":209.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T13:00:00+0900\",\"value\":205.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T13:30:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T14:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T14:30:00+0900\",\"value\":213.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T15:00:00+0900\",\"value\":212.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T15:30:00+0900\",\"value\":208.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T16:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T16:30:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T17:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T17:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T18:00:00+0900\",\"value\":207.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T18:30:00+0900\",\"value\":183.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T19:00:00+0900\",\"value\":160.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T19:30:00+0900\",\"value\":145.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T20:00:00+0900\",\"value\":140.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T20:30:00+0900\",\"value\":135.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T21:00:00+0900\",\"value\":131.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T21:30:00+0900\",\"value\":122.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T22:00:00+0900\",\"value\":115.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T22:30:00+0900\",\"value\":101.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T23:00:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-18T23:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T00:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T00:30:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T01:00:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T01:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T02:00:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T02:30:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T03:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T03:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T04:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T04:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T05:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T06:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T06:30:00+0900\",\"value\":72.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T07:00:00+0900\",\"value\":112.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T07:30:00+0900\",\"value\":109.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T08:00:00+0900\",\"value\":123.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T08:30:00+0900\",\"value\":161.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T09:00:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T09:30:00+0900\",\"value\":234.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T10:00:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T10:30:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T11:00:00+0900\",\"value\":233.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T11:30:00+0900\",\"value\":235.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T12:00:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T12:30:00+0900\",\"value\":216.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T13:00:00+0900\",\"value\":209.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T13:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T14:00:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T14:30:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T15:00:00+0900\",\"value\":227.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T15:30:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T16:00:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T16:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T17:00:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T17:30:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T18:00:00+0900\",\"value\":213.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T18:30:00+0900\",\"value\":181.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T19:00:00+0900\",\"value\":162.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T19:30:00+0900\",\"value\":137.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T20:00:00+0900\",\"value\":126.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T20:30:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T21:00:00+0900\",\"value\":107.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T21:30:00+0900\",\"value\":97.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T22:00:00+0900\",\"value\":94.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T22:30:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T23:00:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-19T23:30:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T00:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T00:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T01:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T01:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T02:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T02:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T03:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T03:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T04:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T04:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T05:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T05:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T06:00:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T06:30:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T07:00:00+0900\",\"value\":110.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T07:30:00+0900\",\"value\":103.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T08:00:00+0900\",\"value\":132.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T08:30:00+0900\",\"value\":167.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T09:00:00+0900\",\"value\":212.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T09:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T10:00:00+0900\",\"value\":239.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T10:30:00+0900\",\"value\":251.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T11:00:00+0900\",\"value\":251.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T11:30:00+0900\",\"value\":242.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T12:00:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T12:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T13:00:00+0900\",\"value\":211.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T13:30:00+0900\",\"value\":231.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T14:00:00+0900\",\"value\":244.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T14:30:00+0900\",\"value\":237.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T15:00:00+0900\",\"value\":248.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T15:30:00+0900\",\"value\":248.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T16:00:00+0900\",\"value\":262.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T16:30:00+0900\",\"value\":241.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T17:00:00+0900\",\"value\":243.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T17:30:00+0900\",\"value\":239.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T18:00:00+0900\",\"value\":237.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T18:30:00+0900\",\"value\":200.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T19:00:00+0900\",\"value\":179.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T19:30:00+0900\",\"value\":153.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T20:00:00+0900\",\"value\":149.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T20:30:00+0900\",\"value\":140.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T21:00:00+0900\",\"value\":136.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T21:30:00+0900\",\"value\":118.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T22:00:00+0900\",\"value\":108.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T22:30:00+0900\",\"value\":99.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T23:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-20T23:30:00+0900\",\"value\":77.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T00:00:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T00:30:00+0900\",\"value\":58.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T01:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T01:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T02:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T02:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T03:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T03:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T04:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T04:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T05:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T06:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T06:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T07:00:00+0900\",\"value\":113.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T07:30:00+0900\",\"value\":128.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T08:00:00+0900\",\"value\":140.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T08:30:00+0900\",\"value\":162.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T09:00:00+0900\",\"value\":220.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T09:30:00+0900\",\"value\":236.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T10:00:00+0900\",\"value\":241.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T10:30:00+0900\",\"value\":257.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T11:00:00+0900\",\"value\":254.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T11:30:00+0900\",\"value\":245.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T12:00:00+0900\",\"value\":244.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T12:30:00+0900\",\"value\":233.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T13:00:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T13:30:00+0900\",\"value\":242.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T14:00:00+0900\",\"value\":240.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T14:30:00+0900\",\"value\":239.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T15:00:00+0900\",\"value\":236.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T15:30:00+0900\",\"value\":248.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T16:00:00+0900\",\"value\":243.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T16:30:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T17:00:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T17:30:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T18:00:00+0900\",\"value\":205.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T18:30:00+0900\",\"value\":178.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T19:00:00+0900\",\"value\":160.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T19:30:00+0900\",\"value\":130.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T20:00:00+0900\",\"value\":128.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T20:30:00+0900\",\"value\":126.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T21:00:00+0900\",\"value\":118.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T21:30:00+0900\",\"value\":120.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T22:00:00+0900\",\"value\":105.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T22:30:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T23:00:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-21T23:30:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T00:00:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T00:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T01:00:00+0900\",\"value\":57.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T01:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T02:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T02:30:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T03:00:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T03:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T04:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T04:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T05:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T06:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T06:30:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T07:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T07:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T08:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T08:30:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T09:00:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T09:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T10:00:00+0900\",\"value\":86.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T10:30:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T11:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T11:30:00+0900\",\"value\":91.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T12:00:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T12:30:00+0900\",\"value\":85.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T13:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T13:30:00+0900\",\"value\":89.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T14:00:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T14:30:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T15:00:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T15:30:00+0900\",\"value\":92.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T16:00:00+0900\",\"value\":90.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T16:30:00+0900\",\"value\":91.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T17:00:00+0900\",\"value\":88.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T17:30:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T18:00:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T18:30:00+0900\",\"value\":73.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T19:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T19:30:00+0900\",\"value\":66.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T20:00:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T20:30:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T21:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T21:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T22:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T22:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T23:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-22T23:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T00:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T00:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T01:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T01:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T02:00:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T02:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T03:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T03:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T04:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T04:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T05:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T05:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T06:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T06:30:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T07:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T07:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T08:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T08:30:00+0900\",\"value\":56.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T09:00:00+0900\",\"value\":60.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T09:30:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T10:00:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T10:30:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T11:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T11:30:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T12:00:00+0900\",\"value\":69.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T12:30:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T13:00:00+0900\",\"value\":71.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T13:30:00+0900\",\"value\":80.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T14:00:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T14:30:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T15:00:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T15:30:00+0900\",\"value\":86.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T16:00:00+0900\",\"value\":84.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T16:30:00+0900\",\"value\":82.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T17:00:00+0900\",\"value\":81.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T17:30:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T18:00:00+0900\",\"value\":75.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T18:30:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T19:00:00+0900\",\"value\":67.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T19:30:00+0900\",\"value\":64.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T20:00:00+0900\",\"value\":63.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T20:30:00+0900\",\"value\":63.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T21:00:00+0900\",\"value\":62.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T21:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T22:00:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T22:30:00+0900\",\"value\":62.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T23:00:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-23T23:30:00+0900\",\"value\":61.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T00:00:00+0900\",\"value\":59.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T00:30:00+0900\",\"value\":55.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T01:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T01:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T02:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T02:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T03:00:00+0900\",\"value\":49.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T03:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T04:00:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T04:30:00+0900\",\"value\":47.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T05:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T05:30:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T06:00:00+0900\",\"value\":54.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T06:30:00+0900\",\"value\":74.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T07:00:00+0900\",\"value\":143.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T07:30:00+0900\",\"value\":113.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T08:00:00+0900\",\"value\":132.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T08:30:00+0900\",\"value\":179.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T09:00:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T09:30:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T10:00:00+0900\",\"value\":241.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T10:30:00+0900\",\"value\":238.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T11:00:00+0900\",\"value\":229.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T11:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T12:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T12:30:00+0900\",\"value\":215.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T13:00:00+0900\",\"value\":209.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T13:30:00+0900\",\"value\":214.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T14:00:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T14:30:00+0900\",\"value\":222.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T15:00:00+0900\",\"value\":230.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T15:30:00+0900\",\"value\":224.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T16:00:00+0900\",\"value\":233.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T16:30:00+0900\",\"value\":232.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T17:00:00+0900\",\"value\":237.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T17:30:00+0900\",\"value\":235.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T18:00:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T18:30:00+0900\",\"value\":184.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T19:00:00+0900\",\"value\":174.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T19:30:00+0900\",\"value\":152.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T20:00:00+0900\",\"value\":145.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T20:30:00+0900\",\"value\":134.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T21:00:00+0900\",\"value\":136.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T21:30:00+0900\",\"value\":126.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T22:00:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T22:30:00+0900\",\"value\":107.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T23:00:00+0900\",\"value\":99.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-24T23:30:00+0900\",\"value\":83.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T00:00:00+0900\",\"value\":65.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T00:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T01:00:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T01:30:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T02:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T02:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T03:00:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T03:30:00+0900\",\"value\":50.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T04:00:00+0900\",\"value\":48.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T04:30:00+0900\",\"value\":44.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T05:00:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T05:30:00+0900\",\"value\":46.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T06:00:00+0900\",\"value\":51.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T06:30:00+0900\",\"value\":68.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T07:00:00+0900\",\"value\":115.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T07:30:00+0900\",\"value\":111.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T08:00:00+0900\",\"value\":129.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T08:30:00+0900\",\"value\":170.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T09:00:00+0900\",\"value\":203.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T09:30:00+0900\",\"value\":214.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T10:00:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T10:30:00+0900\",\"value\":218.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T11:00:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T11:30:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T12:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T12:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T13:00:00+0900\",\"value\":207.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T13:30:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T14:00:00+0900\",\"value\":223.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T14:30:00+0900\",\"value\":226.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T15:00:00+0900\",\"value\":225.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T15:30:00+0900\",\"value\":217.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T16:00:00+0900\",\"value\":219.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T16:30:00+0900\",\"value\":221.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T17:00:00+0900\",\"value\":212.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T17:30:00+0900\",\"value\":213.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T18:00:00+0900\",\"value\":201.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T18:30:00+0900\",\"value\":172.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T19:00:00+0900\",\"value\":164.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T19:30:00+0900\",\"value\":144.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T20:00:00+0900\",\"value\":146.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T20:30:00+0900\",\"value\":138.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T21:00:00+0900\",\"value\":128.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T21:30:00+0900\",\"value\":119.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T22:00:00+0900\",\"value\":111.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T22:30:00+0900\",\"value\":95.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T23:00:00+0900\",\"value\":79.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-25T23:30:00+0900\",\"value\":78.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T00:00:00+0900\",\"value\":70.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T00:30:00+0900\",\"value\":55.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T01:00:00+0900\",\"value\":52.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T01:30:00+0900\",\"value\":53.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T02:00:00+0900\",\"value\":43.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T02:30:00+0900\",\"value\":45.0,\"flags\":\"historical\"},{\"recorded_at\":\"2017-07-26T03:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T03:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T04:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T05:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T05:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T06:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T06:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T07:00:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T07:30:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T08:00:00+0900\",\"value\":120.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T08:30:00+0900\",\"value\":164.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T09:00:00+0900\",\"value\":204.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T09:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T10:00:00+0900\",\"value\":207.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T10:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T11:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T11:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T12:00:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T12:30:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T13:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T13:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T14:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T14:30:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T15:00:00+0900\",\"value\":211.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T15:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T16:00:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T16:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T17:00:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T17:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T18:00:00+0900\",\"value\":207.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T18:30:00+0900\",\"value\":171.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T19:00:00+0900\",\"value\":154.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T19:30:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T20:00:00+0900\",\"value\":114.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T20:30:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T21:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T21:30:00+0900\",\"value\":97.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T22:00:00+0900\",\"value\":90.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T22:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T23:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-26T23:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T00:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T00:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T01:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T01:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T02:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T05:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T06:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T06:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T07:00:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T07:30:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T08:00:00+0900\",\"value\":112.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T08:30:00+0900\",\"value\":148.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T09:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T09:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T10:00:00+0900\",\"value\":234.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T10:30:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T11:00:00+0900\",\"value\":244.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T11:30:00+0900\",\"value\":248.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T12:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T12:30:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T13:00:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T13:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T14:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T14:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T15:00:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T15:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T16:00:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T16:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T17:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T17:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T18:00:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T18:30:00+0900\",\"value\":183.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T19:00:00+0900\",\"value\":164.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T19:30:00+0900\",\"value\":142.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T20:00:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T20:30:00+0900\",\"value\":139.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T21:00:00+0900\",\"value\":130.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T21:30:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T22:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T22:30:00+0900\",\"value\":97.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T23:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-27T23:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T00:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T00:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T01:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T01:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T02:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T02:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T03:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T03:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T04:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T04:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T05:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T05:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T06:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T06:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T07:00:00+0900\",\"value\":109.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T07:30:00+0900\",\"value\":100.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T08:00:00+0900\",\"value\":109.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T08:30:00+0900\",\"value\":147.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T09:00:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T09:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T10:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T10:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T11:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T11:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T12:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T12:30:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T13:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T13:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T14:00:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T14:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T15:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T15:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T16:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T16:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T17:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T17:30:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T18:00:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T18:30:00+0900\",\"value\":180.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T19:00:00+0900\",\"value\":158.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T19:30:00+0900\",\"value\":138.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T20:00:00+0900\",\"value\":136.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T20:30:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T21:00:00+0900\",\"value\":111.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T21:30:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T22:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T22:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T23:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-28T23:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T00:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T01:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T02:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T03:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T04:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T05:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T06:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T06:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T07:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T07:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T08:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T08:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T09:00:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T09:30:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T10:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T10:30:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T11:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T11:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T12:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T12:30:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T13:00:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T13:30:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T14:00:00+0900\",\"value\":89.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T14:30:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T15:00:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T15:30:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T16:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T16:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T17:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T17:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T18:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T18:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T19:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T19:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T20:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T20:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T21:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T21:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T22:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T22:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T23:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-29T23:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T00:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T00:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T01:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T01:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T02:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T02:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T03:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T03:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T04:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T04:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T05:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T05:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T06:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T06:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T07:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T07:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T08:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T08:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T09:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T09:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T10:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T10:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T11:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T11:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T12:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T12:30:00+0900\",\"value\":86.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T13:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T13:30:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T14:00:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T14:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T15:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T15:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T16:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T16:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T17:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T17:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T18:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T18:30:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T19:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T19:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T20:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T20:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T21:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T21:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T22:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T22:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T23:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-30T23:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T00:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T00:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T01:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T01:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T02:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T02:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T03:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T04:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T05:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T05:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T06:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T06:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T07:00:00+0900\",\"value\":152.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T07:30:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T08:00:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T08:30:00+0900\",\"value\":185.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T09:00:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T09:30:00+0900\",\"value\":264.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T10:00:00+0900\",\"value\":262.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T10:30:00+0900\",\"value\":267.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T11:00:00+0900\",\"value\":266.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T11:30:00+0900\",\"value\":270.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T12:00:00+0900\",\"value\":256.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T12:30:00+0900\",\"value\":249.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T13:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T13:30:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T14:00:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T14:30:00+0900\",\"value\":251.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T15:00:00+0900\",\"value\":243.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T15:30:00+0900\",\"value\":260.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T16:00:00+0900\",\"value\":263.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T16:30:00+0900\",\"value\":245.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T17:00:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T17:30:00+0900\",\"value\":260.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T18:00:00+0900\",\"value\":244.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T18:30:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T19:00:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T19:30:00+0900\",\"value\":162.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T20:00:00+0900\",\"value\":142.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T20:30:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T21:00:00+0900\",\"value\":128.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T21:30:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T22:00:00+0900\",\"value\":99.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T22:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T23:00:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-07-31T23:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T00:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T00:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T01:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T01:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T02:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T02:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T03:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T03:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T04:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T04:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T05:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T05:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T06:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T06:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T07:00:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T07:30:00+0900\",\"value\":123.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T08:00:00+0900\",\"value\":136.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T08:30:00+0900\",\"value\":181.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T09:00:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T09:30:00+0900\",\"value\":249.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T10:00:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T10:30:00+0900\",\"value\":249.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T11:00:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T11:30:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T12:00:00+0900\",\"value\":236.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T12:30:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T13:00:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T13:30:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T14:00:00+0900\",\"value\":244.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T14:30:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T15:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T15:30:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T16:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T16:30:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T17:00:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T17:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T18:00:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T18:30:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T19:00:00+0900\",\"value\":179.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T19:30:00+0900\",\"value\":154.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T20:00:00+0900\",\"value\":145.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T20:30:00+0900\",\"value\":139.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T21:00:00+0900\",\"value\":126.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T21:30:00+0900\",\"value\":117.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T22:00:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T22:30:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T23:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-01T23:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T00:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T00:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T01:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T01:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T02:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T02:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T03:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T03:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T04:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T04:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T05:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T05:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T06:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T06:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T07:00:00+0900\",\"value\":105.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T07:30:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T08:00:00+0900\",\"value\":117.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T08:30:00+0900\",\"value\":160.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T09:00:00+0900\",\"value\":209.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T09:30:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T10:00:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T10:30:00+0900\",\"value\":247.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T11:00:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T11:30:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T12:00:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T12:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T13:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T13:30:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T14:00:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T14:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T15:00:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T15:30:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T16:00:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T16:30:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T17:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T17:30:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T18:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T18:30:00+0900\",\"value\":173.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T19:00:00+0900\",\"value\":148.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T19:30:00+0900\",\"value\":113.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T20:00:00+0900\",\"value\":108.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T20:30:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T21:00:00+0900\",\"value\":100.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T21:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T22:00:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T22:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T23:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-02T23:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T00:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T01:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T01:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T02:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T02:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T03:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T03:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T04:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T04:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T05:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T05:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T06:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T06:30:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T07:00:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T07:30:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T08:00:00+0900\",\"value\":120.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T08:30:00+0900\",\"value\":163.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T09:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T09:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T10:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T10:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T11:00:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T11:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T12:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T12:30:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T13:00:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T13:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T14:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T14:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T15:00:00+0900\",\"value\":234.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T15:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T16:00:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T16:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T17:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T17:30:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T18:00:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T18:30:00+0900\",\"value\":189.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T19:00:00+0900\",\"value\":175.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T19:30:00+0900\",\"value\":146.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T20:00:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T20:30:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T21:00:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T21:30:00+0900\",\"value\":110.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T22:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T22:30:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T23:00:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-03T23:30:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T00:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T00:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T02:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T03:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T05:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T06:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T06:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T07:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T07:30:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T08:00:00+0900\",\"value\":120.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T08:30:00+0900\",\"value\":164.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T09:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T09:30:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T10:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T10:30:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T11:00:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T11:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T12:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T12:30:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T13:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T13:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T14:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T14:30:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T15:00:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T15:30:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T16:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T16:30:00+0900\",\"value\":227.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T17:00:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T17:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T18:00:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T18:30:00+0900\",\"value\":180.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T19:00:00+0900\",\"value\":160.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T19:30:00+0900\",\"value\":137.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T20:00:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T20:30:00+0900\",\"value\":129.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T21:00:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T21:30:00+0900\",\"value\":113.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T22:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T22:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T23:00:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-04T23:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T00:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T01:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T01:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T02:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T02:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T03:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T03:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T04:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T04:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T05:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T05:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T06:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T06:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T07:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T07:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T08:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T08:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T09:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T09:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T10:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T10:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T11:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T11:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T12:00:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T12:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T13:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T13:30:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T14:00:00+0900\",\"value\":88.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T14:30:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T15:00:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T15:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T16:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T16:30:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T17:00:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T17:30:00+0900\",\"value\":88.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T18:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T18:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T19:00:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T19:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T20:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T20:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T21:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T21:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T22:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T22:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T23:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-05T23:30:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T00:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T00:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T01:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T02:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T02:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T03:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T04:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T05:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T05:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T06:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T06:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T07:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T07:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T08:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T08:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T09:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T09:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T10:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T10:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T11:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T11:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T12:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T12:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T13:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T13:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T14:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T14:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T15:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T15:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T16:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T16:30:00+0900\",\"value\":86.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T17:00:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T17:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T18:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T18:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T19:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T19:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T20:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T20:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T21:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T21:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T22:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T22:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T23:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-06T23:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T00:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T01:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T01:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T02:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T02:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T03:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T03:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T04:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T04:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T05:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T05:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T06:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T06:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T07:00:00+0900\",\"value\":157.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T07:30:00+0900\",\"value\":135.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T08:00:00+0900\",\"value\":152.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T08:30:00+0900\",\"value\":191.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T09:00:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T09:30:00+0900\",\"value\":254.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T10:00:00+0900\",\"value\":263.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T10:30:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T11:00:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T11:30:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T12:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T12:30:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T13:00:00+0900\",\"value\":207.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T13:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T14:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T14:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T15:00:00+0900\",\"value\":204.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T15:30:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T16:00:00+0900\",\"value\":211.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T16:30:00+0900\",\"value\":207.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T17:00:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T17:30:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T18:00:00+0900\",\"value\":180.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T18:30:00+0900\",\"value\":150.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T19:00:00+0900\",\"value\":143.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T19:30:00+0900\",\"value\":129.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T20:00:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T20:30:00+0900\",\"value\":117.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T21:00:00+0900\",\"value\":107.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T21:30:00+0900\",\"value\":90.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T22:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T22:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T23:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-07T23:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T00:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T00:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T01:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T03:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T04:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T04:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T05:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T06:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T06:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T07:00:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T07:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T08:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T08:30:00+0900\",\"value\":146.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T09:00:00+0900\",\"value\":192.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T09:30:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T10:00:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T10:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T11:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T11:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T12:00:00+0900\",\"value\":227.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T12:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T13:00:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T13:30:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T14:00:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T14:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T15:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T15:30:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T16:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T16:30:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T17:00:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T17:30:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T18:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T18:30:00+0900\",\"value\":182.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T19:00:00+0900\",\"value\":162.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T19:30:00+0900\",\"value\":144.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T20:00:00+0900\",\"value\":137.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T20:30:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T21:00:00+0900\",\"value\":126.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T21:30:00+0900\",\"value\":108.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T22:00:00+0900\",\"value\":101.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T22:30:00+0900\",\"value\":94.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T23:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-08T23:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T00:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T00:30:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T01:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T01:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T02:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T05:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T06:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T06:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T07:00:00+0900\",\"value\":100.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T07:30:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T08:00:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T08:30:00+0900\",\"value\":158.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T09:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T09:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T10:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T10:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T11:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T11:30:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T12:00:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T12:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T13:00:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T13:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T14:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T14:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T15:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T15:30:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T16:00:00+0900\",\"value\":227.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T16:30:00+0900\",\"value\":234.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T17:00:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T17:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T18:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T18:30:00+0900\",\"value\":172.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T19:00:00+0900\",\"value\":158.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T19:30:00+0900\",\"value\":128.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T20:00:00+0900\",\"value\":115.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T20:30:00+0900\",\"value\":108.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T21:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T21:30:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T22:00:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T22:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T23:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-09T23:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T00:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T01:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T01:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T02:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T02:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T03:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T03:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T04:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T04:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T05:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T05:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T06:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T06:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T07:00:00+0900\",\"value\":123.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T07:30:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T08:00:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T08:30:00+0900\",\"value\":157.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T09:00:00+0900\",\"value\":211.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T09:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T10:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T10:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T11:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T11:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T12:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T12:30:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T13:00:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T13:30:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T14:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T14:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T15:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T15:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T16:00:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T16:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T17:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T17:30:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T18:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T18:30:00+0900\",\"value\":195.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T19:00:00+0900\",\"value\":171.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T19:30:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T20:00:00+0900\",\"value\":138.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T20:30:00+0900\",\"value\":129.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T21:00:00+0900\",\"value\":111.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T21:30:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T22:00:00+0900\",\"value\":90.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T22:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T23:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-10T23:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T00:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T00:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T01:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T01:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T02:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T03:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T05:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T06:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T06:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T07:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T07:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T08:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T08:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T09:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T09:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T10:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T10:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T11:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T11:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T12:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T12:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T13:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T13:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T14:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T14:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T15:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T15:30:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T16:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T16:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T17:00:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T17:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T18:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T18:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T19:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T19:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T20:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T20:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T21:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T21:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T22:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T22:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T23:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-11T23:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T00:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T00:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T01:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T01:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T05:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T06:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T06:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T07:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T07:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T08:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T08:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T09:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T09:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T10:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T10:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T11:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T11:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T12:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T12:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T13:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T13:30:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T14:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T14:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T15:00:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T15:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T16:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T16:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T17:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T17:30:00+0900\",\"value\":83.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T18:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T18:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T19:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T19:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T20:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T20:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T21:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T21:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T22:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T22:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T23:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-12T23:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T00:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T00:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T01:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T01:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T02:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T02:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T03:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T03:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T04:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T04:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T05:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T05:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T06:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T06:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T07:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T07:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T08:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T08:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T09:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T09:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T10:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T10:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T11:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T11:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T12:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T12:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T13:00:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T13:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T14:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T14:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T15:00:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T15:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T16:00:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T16:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T17:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T17:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T18:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T18:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T19:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T19:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T20:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T20:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T21:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T21:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T22:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T22:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T23:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-13T23:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T00:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T00:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T03:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T03:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T04:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T05:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T05:30:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T06:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T07:00:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T07:30:00+0900\",\"value\":109.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T08:00:00+0900\",\"value\":124.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T08:30:00+0900\",\"value\":154.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T09:00:00+0900\",\"value\":187.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T09:30:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T10:00:00+0900\",\"value\":198.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T10:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T11:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T11:30:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T12:00:00+0900\",\"value\":194.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T12:30:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T13:00:00+0900\",\"value\":184.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T13:30:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T14:00:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T14:30:00+0900\",\"value\":182.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T15:00:00+0900\",\"value\":179.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T15:30:00+0900\",\"value\":192.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T16:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T16:30:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T17:00:00+0900\",\"value\":190.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T17:30:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T18:00:00+0900\",\"value\":177.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T18:30:00+0900\",\"value\":155.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T19:00:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T19:30:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T20:00:00+0900\",\"value\":96.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T20:30:00+0900\",\"value\":90.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T21:00:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T21:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T22:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T22:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T23:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-14T23:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T00:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T00:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T01:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T02:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T03:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T04:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T05:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T06:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T07:00:00+0900\",\"value\":105.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T07:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T08:00:00+0900\",\"value\":101.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T08:30:00+0900\",\"value\":129.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T09:00:00+0900\",\"value\":170.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T09:30:00+0900\",\"value\":176.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T10:00:00+0900\",\"value\":165.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T10:30:00+0900\",\"value\":172.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T11:00:00+0900\",\"value\":170.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T11:30:00+0900\",\"value\":178.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T12:00:00+0900\",\"value\":169.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T12:30:00+0900\",\"value\":163.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T13:00:00+0900\",\"value\":149.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T13:30:00+0900\",\"value\":171.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T14:00:00+0900\",\"value\":175.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T14:30:00+0900\",\"value\":159.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T15:00:00+0900\",\"value\":164.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T15:30:00+0900\",\"value\":169.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T16:00:00+0900\",\"value\":173.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T16:30:00+0900\",\"value\":168.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T17:00:00+0900\",\"value\":170.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T17:30:00+0900\",\"value\":164.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T18:00:00+0900\",\"value\":155.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T18:30:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T19:00:00+0900\",\"value\":122.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T19:30:00+0900\",\"value\":100.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T20:00:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T20:30:00+0900\",\"value\":92.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T21:00:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T21:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T22:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T22:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T23:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-15T23:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T00:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T00:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T01:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T01:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T02:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T02:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T03:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T03:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T04:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T04:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T05:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T05:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T06:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T07:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T07:30:00+0900\",\"value\":95.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T08:00:00+0900\",\"value\":110.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T08:30:00+0900\",\"value\":139.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T09:00:00+0900\",\"value\":178.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T09:30:00+0900\",\"value\":194.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T10:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T10:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T11:00:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T11:30:00+0900\",\"value\":194.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T12:00:00+0900\",\"value\":198.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T12:30:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T13:00:00+0900\",\"value\":195.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T13:30:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T14:00:00+0900\",\"value\":204.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T14:30:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T15:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T15:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T16:00:00+0900\",\"value\":206.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T16:30:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T17:00:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T17:30:00+0900\",\"value\":211.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T18:00:00+0900\",\"value\":189.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T18:30:00+0900\",\"value\":161.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T19:00:00+0900\",\"value\":140.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T19:30:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T20:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T20:30:00+0900\",\"value\":96.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T21:00:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T21:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T22:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T22:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T23:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-16T23:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T00:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T00:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T01:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T01:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T03:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T04:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T04:30:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T05:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T05:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T06:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T06:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T07:00:00+0900\",\"value\":101.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T07:30:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T08:00:00+0900\",\"value\":117.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T08:30:00+0900\",\"value\":160.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T09:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T09:30:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T10:00:00+0900\",\"value\":204.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T10:30:00+0900\",\"value\":204.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T11:00:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T11:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T12:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T12:30:00+0900\",\"value\":206.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T13:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T13:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T14:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T14:30:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T15:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T15:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T16:00:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T16:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T17:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T17:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T18:00:00+0900\",\"value\":205.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T18:30:00+0900\",\"value\":189.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T19:00:00+0900\",\"value\":168.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T19:30:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T20:00:00+0900\",\"value\":138.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T20:30:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T21:00:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T21:30:00+0900\",\"value\":108.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T22:00:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T22:30:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T23:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-17T23:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T00:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T00:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T01:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T05:30:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T06:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T06:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T07:00:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T07:30:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T08:00:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T08:30:00+0900\",\"value\":154.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T09:00:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T09:30:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T10:00:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T10:30:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T11:00:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T11:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T12:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T12:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T13:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T13:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T14:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T14:30:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T15:00:00+0900\",\"value\":209.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T15:30:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T16:00:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T16:30:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T17:00:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T17:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T18:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T18:30:00+0900\",\"value\":184.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T19:00:00+0900\",\"value\":165.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T19:30:00+0900\",\"value\":134.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T20:00:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T20:30:00+0900\",\"value\":114.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T21:00:00+0900\",\"value\":98.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T21:30:00+0900\",\"value\":88.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T22:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T22:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T23:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-18T23:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T00:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T00:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T01:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T01:30:00+0900\",\"value\":42.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T02:00:00+0900\",\"value\":42.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T03:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T04:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T05:00:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T05:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T06:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T06:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T07:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T07:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T08:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T08:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T09:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T09:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T10:00:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T10:30:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T11:00:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T11:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T12:00:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T12:30:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T13:00:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T13:30:00+0900\",\"value\":87.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T14:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T14:30:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T15:00:00+0900\",\"value\":80.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T15:30:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T16:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T16:30:00+0900\",\"value\":84.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T17:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T17:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T18:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T18:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T19:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T19:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T20:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T20:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T21:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T21:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T22:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T22:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T23:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-19T23:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T00:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T00:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T01:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T01:30:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T02:00:00+0900\",\"value\":42.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T03:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T04:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T05:30:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T06:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T06:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T07:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T07:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T08:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T08:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T09:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T09:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T10:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T10:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T11:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T11:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T12:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T12:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T13:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T13:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T14:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T14:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T15:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T15:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T16:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T16:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T17:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T17:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T18:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T18:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T19:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T19:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T20:00:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T20:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T21:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T21:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T22:00:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T22:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T23:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-20T23:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T00:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T00:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T01:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T01:30:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T02:00:00+0900\",\"value\":60.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T02:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T03:00:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T03:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T04:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T04:30:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T05:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T05:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T06:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T06:30:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T07:00:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T07:30:00+0900\",\"value\":132.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T08:00:00+0900\",\"value\":158.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T08:30:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T09:00:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T09:30:00+0900\",\"value\":263.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T10:00:00+0900\",\"value\":276.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T10:30:00+0900\",\"value\":276.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T11:00:00+0900\",\"value\":261.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T11:30:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T12:00:00+0900\",\"value\":251.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T12:30:00+0900\",\"value\":248.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T13:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T13:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T14:00:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T14:30:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T15:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T15:30:00+0900\",\"value\":248.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T16:00:00+0900\",\"value\":247.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T16:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T17:00:00+0900\",\"value\":236.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T17:30:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T18:00:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T18:30:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T19:00:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T19:30:00+0900\",\"value\":159.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T20:00:00+0900\",\"value\":145.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T20:30:00+0900\",\"value\":132.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T21:00:00+0900\",\"value\":111.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T21:30:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T22:00:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T22:30:00+0900\",\"value\":86.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T23:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-21T23:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T00:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T00:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T01:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T01:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T05:30:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T06:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T07:00:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T07:30:00+0900\",\"value\":136.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T08:00:00+0900\",\"value\":156.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T08:30:00+0900\",\"value\":187.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T09:00:00+0900\",\"value\":236.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T09:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T10:00:00+0900\",\"value\":249.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T10:30:00+0900\",\"value\":253.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T11:00:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T11:30:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T12:00:00+0900\",\"value\":245.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T12:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T13:00:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T13:30:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T14:00:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T14:30:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T15:00:00+0900\",\"value\":251.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T15:30:00+0900\",\"value\":246.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T16:00:00+0900\",\"value\":253.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T16:30:00+0900\",\"value\":244.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T17:00:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T17:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T18:00:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T18:30:00+0900\",\"value\":211.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T19:00:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T19:30:00+0900\",\"value\":161.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T20:00:00+0900\",\"value\":157.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T20:30:00+0900\",\"value\":139.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T21:00:00+0900\",\"value\":128.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T21:30:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T22:00:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T22:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T23:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-22T23:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T00:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T00:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T01:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T01:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T02:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T02:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T03:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T04:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T05:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T05:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T06:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T06:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T07:00:00+0900\",\"value\":114.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T07:30:00+0900\",\"value\":118.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T08:00:00+0900\",\"value\":152.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T08:30:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T09:00:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T09:30:00+0900\",\"value\":256.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T10:00:00+0900\",\"value\":256.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T10:30:00+0900\",\"value\":263.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T11:00:00+0900\",\"value\":259.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T11:30:00+0900\",\"value\":258.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T12:00:00+0900\",\"value\":252.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T12:30:00+0900\",\"value\":249.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T13:00:00+0900\",\"value\":236.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T13:30:00+0900\",\"value\":254.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T14:00:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T14:30:00+0900\",\"value\":245.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T15:00:00+0900\",\"value\":257.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T15:30:00+0900\",\"value\":258.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T16:00:00+0900\",\"value\":253.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T16:30:00+0900\",\"value\":258.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T17:00:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T17:30:00+0900\",\"value\":247.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T18:00:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T18:30:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T19:00:00+0900\",\"value\":171.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T19:30:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T20:00:00+0900\",\"value\":124.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T20:30:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T21:00:00+0900\",\"value\":110.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T21:30:00+0900\",\"value\":105.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T22:00:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T22:30:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T23:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-23T23:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T00:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T00:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T01:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T03:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T05:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T06:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T06:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T07:00:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T07:30:00+0900\",\"value\":132.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T08:00:00+0900\",\"value\":143.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T08:30:00+0900\",\"value\":188.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T09:00:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T09:30:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T10:00:00+0900\",\"value\":258.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T10:30:00+0900\",\"value\":268.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T11:00:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T11:30:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T12:00:00+0900\",\"value\":246.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T12:30:00+0900\",\"value\":247.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T13:00:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T13:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T14:00:00+0900\",\"value\":246.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T14:30:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T15:00:00+0900\",\"value\":250.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T15:30:00+0900\",\"value\":264.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T16:00:00+0900\",\"value\":262.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T16:30:00+0900\",\"value\":254.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T17:00:00+0900\",\"value\":251.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T17:30:00+0900\",\"value\":267.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T18:00:00+0900\",\"value\":243.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T18:30:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T19:00:00+0900\",\"value\":197.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T19:30:00+0900\",\"value\":163.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T20:00:00+0900\",\"value\":155.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T20:30:00+0900\",\"value\":137.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T21:00:00+0900\",\"value\":123.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T21:30:00+0900\",\"value\":113.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T22:00:00+0900\",\"value\":102.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T22:30:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T23:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-24T23:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T00:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T00:30:00+0900\",\"value\":43.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T04:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T05:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T05:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T06:00:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T06:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T07:00:00+0900\",\"value\":118.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T07:30:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T08:00:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T08:30:00+0900\",\"value\":158.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T09:00:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T09:30:00+0900\",\"value\":241.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T10:00:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T10:30:00+0900\",\"value\":255.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T11:00:00+0900\",\"value\":253.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T11:30:00+0900\",\"value\":243.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T12:00:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T12:30:00+0900\",\"value\":232.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T13:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T13:30:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T14:00:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T14:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T15:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T15:30:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T16:00:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T16:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T17:00:00+0900\",\"value\":240.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T17:30:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T18:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T18:30:00+0900\",\"value\":189.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T19:00:00+0900\",\"value\":170.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T19:30:00+0900\",\"value\":130.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T20:00:00+0900\",\"value\":117.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T20:30:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T21:00:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T21:30:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T22:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T22:30:00+0900\",\"value\":81.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T23:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-25T23:30:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T00:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T00:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T01:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T01:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T02:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T02:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T03:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T03:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T04:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T04:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T05:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T05:30:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T06:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T07:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T07:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T08:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T08:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T09:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T09:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T10:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T10:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T11:00:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T11:30:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T12:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T12:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T13:00:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T13:30:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T14:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T14:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T15:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T15:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T16:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T16:30:00+0900\",\"value\":79.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T17:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T17:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T18:00:00+0900\",\"value\":73.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T18:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T19:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T19:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T20:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T20:30:00+0900\",\"value\":64.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T21:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T21:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T22:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T22:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T23:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-26T23:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T00:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T00:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T01:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T01:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T02:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T03:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T04:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T05:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T05:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T06:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T06:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T07:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T07:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T08:00:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T08:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T09:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T09:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T10:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T10:30:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T11:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T11:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T12:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T12:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T13:00:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T13:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T14:00:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T14:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T15:00:00+0900\",\"value\":71.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T15:30:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T16:00:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T16:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T17:00:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T17:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T18:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T18:30:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T19:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T19:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T20:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T20:30:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T21:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T21:30:00+0900\",\"value\":53.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T22:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T22:30:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T23:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-27T23:30:00+0900\",\"value\":52.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T00:00:00+0900\",\"value\":50.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T00:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T01:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T01:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T02:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T02:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T03:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T04:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T04:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T05:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T05:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T06:00:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T06:30:00+0900\",\"value\":70.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T07:00:00+0900\",\"value\":133.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T07:30:00+0900\",\"value\":122.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T08:00:00+0900\",\"value\":143.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T08:30:00+0900\",\"value\":171.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T09:00:00+0900\",\"value\":222.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T09:30:00+0900\",\"value\":238.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T10:00:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T10:30:00+0900\",\"value\":236.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T11:00:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T11:30:00+0900\",\"value\":237.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T12:00:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T12:30:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T13:00:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T13:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T14:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T14:30:00+0900\",\"value\":206.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T15:00:00+0900\",\"value\":213.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T15:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T16:00:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T16:30:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T17:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T17:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T18:00:00+0900\",\"value\":209.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T18:30:00+0900\",\"value\":179.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T19:00:00+0900\",\"value\":168.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T19:30:00+0900\",\"value\":132.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T20:00:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T20:30:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T21:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T21:30:00+0900\",\"value\":97.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T22:00:00+0900\",\"value\":96.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T22:30:00+0900\",\"value\":88.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T23:00:00+0900\",\"value\":75.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-28T23:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T00:00:00+0900\",\"value\":61.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T00:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T01:00:00+0900\",\"value\":54.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T01:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T02:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T02:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T03:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T03:30:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T04:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T04:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T05:30:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T06:00:00+0900\",\"value\":55.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T06:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T07:00:00+0900\",\"value\":114.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T07:30:00+0900\",\"value\":114.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T08:00:00+0900\",\"value\":142.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T08:30:00+0900\",\"value\":173.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T09:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T09:30:00+0900\",\"value\":235.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T10:00:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T10:30:00+0900\",\"value\":229.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T11:00:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T11:30:00+0900\",\"value\":231.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T12:00:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T12:30:00+0900\",\"value\":224.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T13:00:00+0900\",\"value\":227.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T13:30:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T14:00:00+0900\",\"value\":227.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T14:30:00+0900\",\"value\":228.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T15:00:00+0900\",\"value\":239.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T15:30:00+0900\",\"value\":233.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T16:00:00+0900\",\"value\":230.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T16:30:00+0900\",\"value\":226.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T17:00:00+0900\",\"value\":221.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T17:30:00+0900\",\"value\":225.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T18:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T18:30:00+0900\",\"value\":194.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T19:00:00+0900\",\"value\":174.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T19:30:00+0900\",\"value\":150.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T20:00:00+0900\",\"value\":149.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T20:30:00+0900\",\"value\":147.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T21:00:00+0900\",\"value\":137.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T21:30:00+0900\",\"value\":127.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T22:00:00+0900\",\"value\":116.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T22:30:00+0900\",\"value\":101.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T23:00:00+0900\",\"value\":82.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-29T23:30:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T00:00:00+0900\",\"value\":59.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T00:30:00+0900\",\"value\":58.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T01:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T01:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T02:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T03:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T03:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T04:00:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T04:30:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T05:00:00+0900\",\"value\":47.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T05:30:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T06:00:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T06:30:00+0900\",\"value\":69.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T07:00:00+0900\",\"value\":113.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T07:30:00+0900\",\"value\":107.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T08:00:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T08:30:00+0900\",\"value\":160.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T09:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T09:30:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T10:00:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T10:30:00+0900\",\"value\":223.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T11:00:00+0900\",\"value\":214.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T11:30:00+0900\",\"value\":219.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T12:00:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T12:30:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T13:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T13:30:00+0900\",\"value\":216.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T14:00:00+0900\",\"value\":212.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T14:30:00+0900\",\"value\":215.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T15:00:00+0900\",\"value\":217.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T15:30:00+0900\",\"value\":220.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T16:00:00+0900\",\"value\":218.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T16:30:00+0900\",\"value\":208.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T17:00:00+0900\",\"value\":198.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T17:30:00+0900\",\"value\":209.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T18:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T18:30:00+0900\",\"value\":165.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T19:00:00+0900\",\"value\":142.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T19:30:00+0900\",\"value\":119.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T20:00:00+0900\",\"value\":113.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T20:30:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T21:00:00+0900\",\"value\":100.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T21:30:00+0900\",\"value\":91.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T22:00:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T22:30:00+0900\",\"value\":74.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T23:00:00+0900\",\"value\":65.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-30T23:30:00+0900\",\"value\":57.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T00:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T00:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T01:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T02:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T02:30:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T03:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T04:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T05:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T05:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T06:00:00+0900\",\"value\":51.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T06:30:00+0900\",\"value\":66.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T07:00:00+0900\",\"value\":96.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T07:30:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T08:00:00+0900\",\"value\":115.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T08:30:00+0900\",\"value\":148.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T09:00:00+0900\",\"value\":187.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T09:30:00+0900\",\"value\":191.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T10:00:00+0900\",\"value\":190.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T10:30:00+0900\",\"value\":205.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T11:00:00+0900\",\"value\":210.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T11:30:00+0900\",\"value\":201.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T12:00:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T12:30:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T13:00:00+0900\",\"value\":185.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T13:30:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T14:00:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T14:30:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T15:00:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T15:30:00+0900\",\"value\":202.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T16:00:00+0900\",\"value\":203.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T16:30:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T17:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T17:30:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T18:00:00+0900\",\"value\":191.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T18:30:00+0900\",\"value\":162.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T19:00:00+0900\",\"value\":146.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T19:30:00+0900\",\"value\":129.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T20:00:00+0900\",\"value\":123.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T20:30:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T21:00:00+0900\",\"value\":110.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T21:30:00+0900\",\"value\":103.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T22:00:00+0900\",\"value\":89.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T22:30:00+0900\",\"value\":76.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T23:00:00+0900\",\"value\":68.0,\"flags\":\"\"},{\"recorded_at\":\"2017-08-31T23:30:00+0900\",\"value\":62.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T00:00:00+0900\",\"value\":49.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T00:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T01:00:00+0900\",\"value\":44.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T01:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T02:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T02:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T03:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T03:30:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T04:00:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T04:30:00+0900\",\"value\":45.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T05:00:00+0900\",\"value\":46.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T05:30:00+0900\",\"value\":48.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T06:00:00+0900\",\"value\":56.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T06:30:00+0900\",\"value\":67.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T07:00:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T07:30:00+0900\",\"value\":86.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T08:00:00+0900\",\"value\":106.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T08:30:00+0900\",\"value\":138.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T09:00:00+0900\",\"value\":179.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T09:30:00+0900\",\"value\":186.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T10:00:00+0900\",\"value\":190.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T10:30:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T11:00:00+0900\",\"value\":199.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T11:30:00+0900\",\"value\":197.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T12:00:00+0900\",\"value\":191.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T12:30:00+0900\",\"value\":195.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T13:00:00+0900\",\"value\":182.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T13:30:00+0900\",\"value\":200.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T14:00:00+0900\",\"value\":196.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T14:30:00+0900\",\"value\":192.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T15:00:00+0900\",\"value\":192.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T15:30:00+0900\",\"value\":198.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T16:00:00+0900\",\"value\":195.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T16:30:00+0900\",\"value\":193.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T17:00:00+0900\",\"value\":189.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T17:30:00+0900\",\"value\":191.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T18:00:00+0900\",\"value\":176.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T18:30:00+0900\",\"value\":150.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T19:00:00+0900\",\"value\":141.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T19:30:00+0900\",\"value\":121.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T20:00:00+0900\",\"value\":112.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T20:30:00+0900\",\"value\":104.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T21:00:00+0900\",\"value\":93.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T21:30:00+0900\",\"value\":85.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T22:00:00+0900\",\"value\":78.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T22:30:00+0900\",\"value\":77.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T23:00:00+0900\",\"value\":72.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-01T23:30:00+0900\",\"value\":63.0,\"flags\":\"\"},{\"recorded_at\":\"2017-09-02T00:00:00+0900\",\"value\":61.0,\"flags\":\"\"}]}]\n"
  },
  {
    "path": "examples/boxPlot.html",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n\n<body>\n\n<div class=\"gallery\" id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n    nv.addGraph(function() {\n      var chart = nv.models.boxPlotChart()\n          .x(function(d) { return d.label })\n          .staggerLabels(true)\n          .maxBoxWidth(75) // prevent boxes from being incredibly wide\n          .yDomain([0, 500])\n          ;\n\n      d3.select('#chart1 svg')\n          .datum(exampleData())\n          .call(chart);\n\n      nv.utils.windowResize(chart.update);\n\n      return chart;\n    });\n\n    function exampleData() {\n     return  [\n        {\n          label: \"Sample A\",\n          values: {\n            Q1: 120,\n            Q2: 150,\n            Q3: 200,\n            whisker_low: 115,\n            whisker_high: 210,\n            outliers: [50, 100, 225]\n          },\n        },\n        {\n          label: \"Sample B\",\n          values: {\n            Q1: 300,\n            Q2: 350,\n            Q3: 400,\n            whisker_low: 225,\n            whisker_high: 425,\n            outliers: [175]\n          },\n        },\n        {\n          label: \"Sample C\",\n          values: {\n            Q1: 50,\n            Q2: 100,\n            Q3: 125,\n            whisker_low: 25,\n            whisker_high: 175,\n            outliers: [0]\n          },\n        }\n      ];\n    }\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/boxPlotCustomModel.html",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n\n<body>\n\n<div class=\"gallery\" id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n    nv.addGraph(function() {\n        var chart = nv.models.boxPlotChart()\n            .x(function(d) { return d.title })\n            .staggerLabels(true)\n            .maxBoxWidth(75) // prevent boxes from being incredibly wide\n            .itemColor(function (d) { return d.seriesColor })\n            .outliers(function (d) { return d.outlData })\n            .outlierValue(function (d) { return d.data })\n            .outlierLabel(function (d) {\n                if (d.text) { return d.data + ' ' + d.text }\n                return d.data;\n            })\n            .outlierColor(function (d) { return d.color })\n            .q1(function (d) { return d.q1 })\n            .q2(function (d) { return d.median })\n            .q3(function (d) { return d.q3 })\n            .wl(function (d) { return d.minRegularValue })\n            .wh(function (d) { return d.maxRegularValue });\n\n        d3.select('#chart1 svg')\n            .datum(exampleData())\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n    function exampleData() {\n        return  [\n            {\n                title: 'Custom Attributes 1',\n                q1: 1.05, q3: 2.7, maxOutlier: 6, maxRegularValue: 4.4,\n                mean: 3.365, median: 1.3, minOutlier: 0.4, minRegularValue: 0.4,\n                outlData: [\n                    {data: 6, text: 'Source 1'},\n                    {data: 14.5, text: 'Source 2'},\n                    {data: 12, text: 'Reference Value', color: '#000'},\n                    {data: 4.5, text: 'Source 3'}\n                ],\n                seriesColor: '#247E42'\n            },\n            {\n                title: 'Custom Attributes 2',\n                q1: 1.05, q3: 2.849999996, maxOutlier: 4.9, maxRegularValue: 4.9,\n                mean: 3.4949999, median: 1.5, minOutlier: 0.3, minRegularValue: 0.3,\n                outlData: [\n                    {data: 15.2, text: 'Source 1'},\n                    {data: 10, text: 'Reference Value', color: '#F00'},\n                    {data: 7.5, color: '#00F'}\n                ],\n                seriesColor: '#334693'\n            }\n        ];\n    }\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/bullet.html",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n</head>\n<body>\n\n<div class=\"gallery\" id=\"chart\"></div>\n\n<script>\n\n    var width = 960,\n        height = 55,\n        margin = {top: 5, right: 40, bottom: 20, left: 120};\n\n    var chart = nv.models.bullet()\n        .width(width - margin.right - margin.left)\n        .height(height - margin.top - margin.bottom);\n\n    data = [\n        {\"title\":\"Revenue\",\"subtitle\":\"US$, in thousands\",\"ranges\":[-150,-225,-300],\"measures\":[-220],\"markers\":[-250], \"markerLines\":[-230]}\n    ];\n\n    //TODO: to be consistent with other models, should be appending a g to an already made svg, not creating the svg element\n    var vis = d3.select(\"#chart\").selectAll(\"svg\")\n        .data(data)\n        .enter().append(\"svg\")\n        .attr(\"class\", \"bullet nvd3\")\n        .attr(\"width\", width)\n        .attr(\"height\", height);\n\n    vis.call(chart);\n\n    window.transition = function() {\n        vis.datum(randomize).call(chart);\n    };\n\n    function randomize(d) {\n        if (!d.randomizer) d.randomizer = randomizer(d);\n        d.ranges = d.ranges.map(d.randomizer);\n        d.markers = d.markers.map(d.randomizer);\n\t\td.markerLines = d.markerLines.map(d.randomizer);\n        d.measures = d.measures.map(d.randomizer);\n        return d;\n    }\n\n    function randomizer(d) {\n        var k = d3.max(d.ranges) * .2;\n        return function(d) {\n            return Math.max(0, d + k * (Math.random() - .5));\n        };\n    }\n\n    d3.select('body').on('click', window.transition);\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/bulletChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\nNormal Bullet Chart\n<div class=\"gallery with-transitions\" id=\"chart\"></div>\n\nBullet Chart with Custom Labels\n<div class='gallery with-transitions' id='chart2'></div>\n\n<script>\n\n    var width = 960,\n        height = 80,\n        margin = {top: 5, right: 40, bottom: 20, left: 120};\n\n    var chart = nv.models.bulletChart()\n            .width(width - margin.right - margin.left)\n            .height(height - margin.top - margin.bottom);\n\n    var chart2 = nv.models.bulletChart()\n            .width(width - margin.right - margin.left)\n            .height(height - margin.top - margin.bottom);\n\n    data = [\n        {\"title\":\"Revenue\",\"subtitle\":\"US$, in thousands\",\"ranges\":[150,225,300],\"measures\":[220],\"markers\":[250],\"markerLines\":[270]},\n        {\"title\":\"Order Size\",\"subtitle\":\"US$, average\",\"ranges\":[350,500,600],\"measures\":[100],\"markers\":[550], \"markerLines\":[530]},\n        {\"title\":\"Satisfaction\",\"subtitle\":\"out of 5\",\"ranges\":[3.5,4.25,5],\"measures\":[3.2,4.7],\"markers\":[4.4], \"markerLines\":[3.8]}\n    ];\n\n    dataWithLabels = [{\n        \"title\":\"Revenue\",\n        \"subtitle\":\"US$, in thousands\",\n        \"ranges\":[150,225,300],\n        \"measures\":[220],\n        \"markers\":[250, 100],\n        \"markerLines\":[240, 120],\n        \"markerLabels\":['Target Inventory', 'Low Inventory'],\n        \"markerLineLabels\":['Break even Inventory', 'Threshold Inventory'],\n        \"rangeLabels\":['Maximum Inventory','Average Inventory','Minimum Inventory'],\n        \"measureLabels\":['Current Inventory']\n    }];\n\n    //TODO: to be consistent with other models, should be appending a g to an already made svg, not creating the svg element\n    var vis = d3.select(\"#chart\").selectAll(\"svg\")\n        .data(data)\n        .enter().append(\"svg\")\n        .attr(\"class\", \"bullet nvd3\")\n        .attr(\"width\", width)\n        .attr(\"height\", height);\n\n    vis.call(chart);\n\n    var vis2 = d3.select(\"#chart2\").selectAll(\"svg\")\n        .data(dataWithLabels)\n        .enter().append('svg')\n        .attr('class',\"bullet nvd3\")\n        .attr(\"width\",width)\n        .attr(\"height\",height);\n\n    vis2.call(chart2);\n\n    window.transition = function() {\n        vis.datum(randomize).call(chart);\n        vis2.datum(randomize).call(chart2);\n    };\n\n    function randomize(d) {\n        if (!d.randomizer) d.randomizer = randomizer(d);\n        d.ranges = d.ranges.map(d.randomizer);\n        d.markers = d.markers.map(d.randomizer);\n        d.markerLines = d.markerLines.map(d.randomizer);\n        d.measures = d.measures.map(d.randomizer);\n        return d;\n    }\n\n    function randomizer(d) {\n        var k = d3.max(d.ranges) * .2;\n        return function(d) {\n            return Math.max(0, d + k * (Math.random() - .5));\n        };\n    }\n\n    d3.select('body').on('click', window.transition);\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/candlestick.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    var data = [{values: [\n        {\"date\": 15854, \"open\": 165.42, \"high\": 165.8, \"low\": 164.34, \"close\": 165.22, \"volume\": 160363400, \"adjusted\": 164.35},\n        {\"date\": 15855, \"open\": 165.35, \"high\": 166.59, \"low\": 165.22, \"close\": 165.83, \"volume\": 107793800, \"adjusted\": 164.96},\n        {\"date\": 15856, \"open\": 165.37, \"high\": 166.31, \"low\": 163.13, \"close\": 163.45, \"volume\": 176850100, \"adjusted\": 162.59},\n        {\"date\": 15859, \"open\": 163.83, \"high\": 164.46, \"low\": 162.66, \"close\": 164.35, \"volume\": 168390700, \"adjusted\": 163.48},\n        {\"date\": 15860, \"open\": 164.44, \"high\": 165.1, \"low\": 162.73, \"close\": 163.56, \"volume\": 157631500, \"adjusted\": 162.7},\n        {\"date\": 15861, \"open\": 163.09, \"high\": 163.42, \"low\": 161.13, \"close\": 161.27, \"volume\": 211737800, \"adjusted\": 160.42},\n        {\"date\": 15862, \"open\": 161.2, \"high\": 162.74, \"low\": 160.25, \"close\": 162.73, \"volume\": 200225500, \"adjusted\": 161.87},\n        {\"date\": 15863, \"open\": 163.85, \"high\": 164.95, \"low\": 163.14, \"close\": 164.8, \"volume\": 188337800, \"adjusted\": 163.93},\n        {\"date\": 15866, \"open\": 165.31, \"high\": 165.4, \"low\": 164.37, \"close\": 164.8, \"volume\": 105667100, \"adjusted\": 163.93},\n        {\"date\": 15867, \"open\": 163.3, \"high\": 164.54, \"low\": 162.74, \"close\": 163.1, \"volume\": 159505400, \"adjusted\": 162.24},\n        {\"date\": 15868, \"open\": 164.22, \"high\": 164.39, \"low\": 161.6, \"close\": 161.75, \"volume\": 177361500, \"adjusted\": 160.9},\n        {\"date\": 15869, \"open\": 161.66, \"high\": 164.5, \"low\": 161.3, \"close\": 164.21, \"volume\": 163587800, \"adjusted\": 163.35},\n        {\"date\": 15870, \"open\": 164.03, \"high\": 164.67, \"low\": 162.91, \"close\": 163.18, \"volume\": 141197500, \"adjusted\": 162.32},\n        {\"date\": 15873, \"open\": 164.29, \"high\": 165.22, \"low\": 163.22, \"close\": 164.44, \"volume\": 136295600, \"adjusted\": 163.57},\n        {\"date\": 15874, \"open\": 164.53, \"high\": 165.99, \"low\": 164.52, \"close\": 165.74, \"volume\": 114695600, \"adjusted\": 164.87},\n        {\"date\": 15875, \"open\": 165.6, \"high\": 165.89, \"low\": 163.38, \"close\": 163.45, \"volume\": 206149500, \"adjusted\": 162.59},\n        {\"date\": 15876, \"open\": 161.86, \"high\": 163.47, \"low\": 158.98, \"close\": 159.4, \"volume\": 321255900, \"adjusted\": 158.56},\n        {\"date\": 15877, \"open\": 159.64, \"high\": 159.76, \"low\": 157.47, \"close\": 159.07, \"volume\": 271956800, \"adjusted\": 159.07},\n        {\"date\": 15880, \"open\": 157.41, \"high\": 158.43, \"low\": 155.73, \"close\": 157.06, \"volume\": 222329000, \"adjusted\": 157.06},\n        {\"date\": 15881, \"open\": 158.48, \"high\": 160.1, \"low\": 157.42, \"close\": 158.57, \"volume\": 162262200, \"adjusted\": 158.57},\n        {\"date\": 15882, \"open\": 159.87, \"high\": 160.5, \"low\": 159.25, \"close\": 160.14, \"volume\": 134848000, \"adjusted\": 160.14},\n        {\"date\": 15883, \"open\": 161.1, \"high\": 161.82, \"low\": 160.95, \"close\": 161.08, \"volume\": 129483700, \"adjusted\": 161.08},\n        {\"date\": 15884, \"open\": 160.63, \"high\": 161.4, \"low\": 159.86, \"close\": 160.42, \"volume\": 160402900, \"adjusted\": 160.42},\n        {\"date\": 15887, \"open\": 161.26, \"high\": 162.48, \"low\": 161.08, \"close\": 161.36, \"volume\": 131954800, \"adjusted\": 161.36},\n        {\"date\": 15888, \"open\": 161.12, \"high\": 162.3, \"low\": 160.5, \"close\": 161.21, \"volume\": 154863700, \"adjusted\": 161.21},\n        {\"date\": 15889, \"open\": 160.48, \"high\": 161.77, \"low\": 160.22, \"close\": 161.28, \"volume\": 75216400, \"adjusted\": 161.28},\n        {\"date\": 15891, \"open\": 162.47, \"high\": 163.08, \"low\": 161.3, \"close\": 163.02, \"volume\": 122416900, \"adjusted\": 163.02},\n        {\"date\": 15894, \"open\": 163.86, \"high\": 164.39, \"low\": 163.08, \"close\": 163.95, \"volume\": 108092500, \"adjusted\": 163.95},\n        {\"date\": 15895, \"open\": 164.98, \"high\": 165.33, \"low\": 164.27, \"close\": 165.13, \"volume\": 119298000, \"adjusted\": 165.13},\n        {\"date\": 15896, \"open\": 164.97, \"high\": 165.75, \"low\": 164.63, \"close\": 165.19, \"volume\": 121410100, \"adjusted\": 165.19},\n        {\"date\": 15897, \"open\": 167.11, \"high\": 167.61, \"low\": 165.18, \"close\": 167.44, \"volume\": 135592200, \"adjusted\": 167.44},\n        {\"date\": 15898, \"open\": 167.39, \"high\": 167.93, \"low\": 167.13, \"close\": 167.51, \"volume\": 104212700, \"adjusted\": 167.51},\n        {\"date\": 15901, \"open\": 167.97, \"high\": 168.39, \"low\": 167.68, \"close\": 168.15, \"volume\": 69450600, \"adjusted\": 168.15},\n        {\"date\": 15902, \"open\": 168.26, \"high\": 168.36, \"low\": 167.07, \"close\": 167.52, \"volume\": 88702100, \"adjusted\": 167.52},\n        {\"date\": 15903, \"open\": 168.16, \"high\": 168.48, \"low\": 167.73, \"close\": 167.95, \"volume\": 92873900, \"adjusted\": 167.95},\n        {\"date\": 15904, \"open\": 168.31, \"high\": 169.27, \"low\": 168.2, \"close\": 168.87, \"volume\": 103620100, \"adjusted\": 168.87},\n        {\"date\": 15905, \"open\": 168.52, \"high\": 169.23, \"low\": 168.31, \"close\": 169.17, \"volume\": 103831700, \"adjusted\": 169.17},\n        {\"date\": 15908, \"open\": 169.41, \"high\": 169.74, \"low\": 169.01, \"close\": 169.5, \"volume\": 79428600, \"adjusted\": 169.5},\n        {\"date\": 15909, \"open\": 169.8, \"high\": 169.83, \"low\": 169.05, \"close\": 169.14, \"volume\": 80829700, \"adjusted\": 169.14},\n        {\"date\": 15910, \"open\": 169.79, \"high\": 169.86, \"low\": 168.18, \"close\": 168.52, \"volume\": 112914000, \"adjusted\": 168.52},\n        {\"date\": 15911, \"open\": 168.22, \"high\": 169.08, \"low\": 167.94, \"close\": 168.93, \"volume\": 111088600, \"adjusted\": 168.93},\n        {\"date\": 15912, \"open\": 168.22, \"high\": 169.16, \"low\": 167.52, \"close\": 169.11, \"volume\": 107814600, \"adjusted\": 169.11},\n        {\"date\": 15915, \"open\": 168.68, \"high\": 169.06, \"low\": 168.11, \"close\": 168.59, \"volume\": 79695000, \"adjusted\": 168.59},\n        {\"date\": 15916, \"open\": 169.1, \"high\": 169.28, \"low\": 168.19, \"close\": 168.59, \"volume\": 85209600, \"adjusted\": 168.59},\n        {\"date\": 15917, \"open\": 168.94, \"high\": 169.85, \"low\": 168.49, \"close\": 168.71, \"volume\": 142388700, \"adjusted\": 168.71},\n        {\"date\": 15918, \"open\": 169.99, \"high\": 170.81, \"low\": 169.9, \"close\": 170.66, \"volume\": 110438400, \"adjusted\": 170.66},\n        {\"date\": 15919, \"open\": 170.28, \"high\": 170.97, \"low\": 170.05, \"close\": 170.95, \"volume\": 91116700, \"adjusted\": 170.95},\n        {\"date\": 15922, \"open\": 170.57, \"high\": 170.96, \"low\": 170.35, \"close\": 170.7, \"volume\": 54072700, \"adjusted\": 170.7},\n        {\"date\": 15923, \"open\": 170.37, \"high\": 170.74, \"low\": 169.35, \"close\": 169.73, \"volume\": 87495000, \"adjusted\": 169.73},\n        {\"date\": 15924, \"open\": 169.19, \"high\": 169.43, \"low\": 168.55, \"close\": 169.18, \"volume\": 84854700, \"adjusted\": 169.18},\n        {\"date\": 15925, \"open\": 169.98, \"high\": 170.18, \"low\": 168.93, \"close\": 169.8, \"volume\": 102181300, \"adjusted\": 169.8},\n        {\"date\": 15926, \"open\": 169.58, \"high\": 170.1, \"low\": 168.72, \"close\": 169.31, \"volume\": 91757700, \"adjusted\": 169.31},\n        {\"date\": 15929, \"open\": 168.46, \"high\": 169.31, \"low\": 168.38, \"close\": 169.11, \"volume\": 68593300, \"adjusted\": 169.11},\n        {\"date\": 15930, \"open\": 169.41, \"high\": 169.9, \"low\": 168.41, \"close\": 169.61, \"volume\": 80806000, \"adjusted\": 169.61},\n        {\"date\": 15931, \"open\": 169.53, \"high\": 169.8, \"low\": 168.7, \"close\": 168.74, \"volume\": 79829200, \"adjusted\": 168.74},\n        {\"date\": 15932, \"open\": 167.41, \"high\": 167.43, \"low\": 166.09, \"close\": 166.38, \"volume\": 152931800, \"adjusted\": 166.38},\n        {\"date\": 15933, \"open\": 166.06, \"high\": 166.63, \"low\": 165.5, \"close\": 165.83, \"volume\": 130868200, \"adjusted\": 165.83},\n        {\"date\": 15936, \"open\": 165.64, \"high\": 166.21, \"low\": 164.76, \"close\": 164.77, \"volume\": 96437600, \"adjusted\": 164.77},\n        {\"date\": 15937, \"open\": 165.04, \"high\": 166.2, \"low\": 164.86, \"close\": 165.58, \"volume\": 89294400, \"adjusted\": 165.58},\n        {\"date\": 15938, \"open\": 165.12, \"high\": 166.03, \"low\": 164.19, \"close\": 164.56, \"volume\": 159530500, \"adjusted\": 164.56},\n        {\"date\": 15939, \"open\": 164.9, \"high\": 166.3, \"low\": 164.89, \"close\": 166.06, \"volume\": 101471400, \"adjusted\": 166.06},\n        {\"date\": 15940, \"open\": 166.55, \"high\": 166.83, \"low\": 165.77, \"close\": 166.62, \"volume\": 90888900, \"adjusted\": 166.62},\n        {\"date\": 15943, \"open\": 166.79, \"high\": 167.3, \"low\": 165.89, \"close\": 166, \"volume\": 89702100, \"adjusted\": 166},\n        {\"date\": 15944, \"open\": 164.36, \"high\": 166, \"low\": 163.21, \"close\": 163.33, \"volume\": 158619400, \"adjusted\": 163.33},\n        {\"date\": 15945, \"open\": 163.26, \"high\": 164.49, \"low\": 163.05, \"close\": 163.91, \"volume\": 108113000, \"adjusted\": 163.91},\n        {\"date\": 15946, \"open\": 163.55, \"high\": 165.04, \"low\": 163.4, \"close\": 164.17, \"volume\": 119200500, \"adjusted\": 164.17},\n        {\"date\": 15947, \"open\": 164.51, \"high\": 164.53, \"low\": 163.17, \"close\": 163.65, \"volume\": 134560800, \"adjusted\": 163.65},\n        {\"date\": 15951, \"open\": 165.23, \"high\": 165.58, \"low\": 163.7, \"close\": 164.39, \"volume\": 142322300, \"adjusted\": 164.39},\n        {\"date\": 15952, \"open\": 164.43, \"high\": 166.03, \"low\": 164.13, \"close\": 165.75, \"volume\": 97304000, \"adjusted\": 165.75},\n        {\"date\": 15953, \"open\": 165.85, \"high\": 166.4, \"low\": 165.73, \"close\": 165.96, \"volume\": 62930500, \"adjusted\": 165.96}\n    ]}];\n\n    nv.addGraph(function() {\n        var chart = nv.models.candlestickBar()\n            .x(function(d) { return d['date'] })\n            .y(function(d) { return d['close'] });\n        d3.select(\"#chart1 svg\")\n                .datum(data)\n                .transition().duration(500)\n                .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/candlestickChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    var data = [{values: [\n        {\"date\": 15854, \"open\": 165.42, \"high\": 165.8, \"low\": 164.34, \"close\": 165.22, \"volume\": 160363400, \"adjusted\": 164.35},\n        {\"date\": 15855, \"open\": 165.35, \"high\": 166.59, \"low\": 165.22, \"close\": 165.83, \"volume\": 107793800, \"adjusted\": 164.96},\n        {\"date\": 15856, \"open\": 165.37, \"high\": 166.31, \"low\": 163.13, \"close\": 163.45, \"volume\": 176850100, \"adjusted\": 162.59},\n        {\"date\": 15859, \"open\": 163.83, \"high\": 164.46, \"low\": 162.66, \"close\": 164.35, \"volume\": 168390700, \"adjusted\": 163.48},\n        {\"date\": 15860, \"open\": 164.44, \"high\": 165.1, \"low\": 162.73, \"close\": 163.56, \"volume\": 157631500, \"adjusted\": 162.7},\n        {\"date\": 15861, \"open\": 163.09, \"high\": 163.42, \"low\": 161.13, \"close\": 161.27, \"volume\": 211737800, \"adjusted\": 160.42},\n        {\"date\": 15862, \"open\": 161.2, \"high\": 162.74, \"low\": 160.25, \"close\": 162.73, \"volume\": 200225500, \"adjusted\": 161.87},\n        {\"date\": 15863, \"open\": 163.85, \"high\": 164.95, \"low\": 163.14, \"close\": 164.8, \"volume\": 188337800, \"adjusted\": 163.93},\n        {\"date\": 15866, \"open\": 165.31, \"high\": 165.4, \"low\": 164.37, \"close\": 164.8, \"volume\": 105667100, \"adjusted\": 163.93},\n        {\"date\": 15867, \"open\": 163.3, \"high\": 164.54, \"low\": 162.74, \"close\": 163.1, \"volume\": 159505400, \"adjusted\": 162.24},\n        {\"date\": 15868, \"open\": 164.22, \"high\": 164.39, \"low\": 161.6, \"close\": 161.75, \"volume\": 177361500, \"adjusted\": 160.9},\n        {\"date\": 15869, \"open\": 161.66, \"high\": 164.5, \"low\": 161.3, \"close\": 164.21, \"volume\": 163587800, \"adjusted\": 163.35},\n        {\"date\": 15870, \"open\": 164.03, \"high\": 164.67, \"low\": 162.91, \"close\": 163.18, \"volume\": 141197500, \"adjusted\": 162.32},\n        {\"date\": 15873, \"open\": 164.29, \"high\": 165.22, \"low\": 163.22, \"close\": 164.44, \"volume\": 136295600, \"adjusted\": 163.57},\n        {\"date\": 15874, \"open\": 164.53, \"high\": 165.99, \"low\": 164.52, \"close\": 165.74, \"volume\": 114695600, \"adjusted\": 164.87},\n        {\"date\": 15875, \"open\": 165.6, \"high\": 165.89, \"low\": 163.38, \"close\": 163.45, \"volume\": 206149500, \"adjusted\": 162.59},\n        {\"date\": 15876, \"open\": 161.86, \"high\": 163.47, \"low\": 158.98, \"close\": 159.4, \"volume\": 321255900, \"adjusted\": 158.56},\n        {\"date\": 15877, \"open\": 159.64, \"high\": 159.76, \"low\": 157.47, \"close\": 159.07, \"volume\": 271956800, \"adjusted\": 159.07},\n        {\"date\": 15880, \"open\": 157.41, \"high\": 158.43, \"low\": 155.73, \"close\": 157.06, \"volume\": 222329000, \"adjusted\": 157.06},\n        {\"date\": 15881, \"open\": 158.48, \"high\": 160.1, \"low\": 157.42, \"close\": 158.57, \"volume\": 162262200, \"adjusted\": 158.57},\n        {\"date\": 15882, \"open\": 159.87, \"high\": 160.5, \"low\": 159.25, \"close\": 160.14, \"volume\": 134848000, \"adjusted\": 160.14},\n        {\"date\": 15883, \"open\": 161.1, \"high\": 161.82, \"low\": 160.95, \"close\": 161.08, \"volume\": 129483700, \"adjusted\": 161.08},\n        {\"date\": 15884, \"open\": 160.63, \"high\": 161.4, \"low\": 159.86, \"close\": 160.42, \"volume\": 160402900, \"adjusted\": 160.42},\n        {\"date\": 15887, \"open\": 161.26, \"high\": 162.48, \"low\": 161.08, \"close\": 161.36, \"volume\": 131954800, \"adjusted\": 161.36},\n        {\"date\": 15888, \"open\": 161.12, \"high\": 162.3, \"low\": 160.5, \"close\": 161.21, \"volume\": 154863700, \"adjusted\": 161.21},\n        {\"date\": 15889, \"open\": 160.48, \"high\": 161.77, \"low\": 160.22, \"close\": 161.28, \"volume\": 75216400, \"adjusted\": 161.28},\n        {\"date\": 15891, \"open\": 162.47, \"high\": 163.08, \"low\": 161.3, \"close\": 163.02, \"volume\": 122416900, \"adjusted\": 163.02},\n        {\"date\": 15894, \"open\": 163.86, \"high\": 164.39, \"low\": 163.08, \"close\": 163.95, \"volume\": 108092500, \"adjusted\": 163.95},\n        {\"date\": 15895, \"open\": 164.98, \"high\": 165.33, \"low\": 164.27, \"close\": 165.13, \"volume\": 119298000, \"adjusted\": 165.13},\n        {\"date\": 15896, \"open\": 164.97, \"high\": 165.75, \"low\": 164.63, \"close\": 165.19, \"volume\": 121410100, \"adjusted\": 165.19},\n        {\"date\": 15897, \"open\": 167.11, \"high\": 167.61, \"low\": 165.18, \"close\": 167.44, \"volume\": 135592200, \"adjusted\": 167.44},\n        {\"date\": 15898, \"open\": 167.39, \"high\": 167.93, \"low\": 167.13, \"close\": 167.51, \"volume\": 104212700, \"adjusted\": 167.51},\n        {\"date\": 15901, \"open\": 167.97, \"high\": 168.39, \"low\": 167.68, \"close\": 168.15, \"volume\": 69450600, \"adjusted\": 168.15},\n        {\"date\": 15902, \"open\": 168.26, \"high\": 168.36, \"low\": 167.07, \"close\": 167.52, \"volume\": 88702100, \"adjusted\": 167.52},\n        {\"date\": 15903, \"open\": 168.16, \"high\": 168.48, \"low\": 167.73, \"close\": 167.95, \"volume\": 92873900, \"adjusted\": 167.95},\n        {\"date\": 15904, \"open\": 168.31, \"high\": 169.27, \"low\": 168.2, \"close\": 168.87, \"volume\": 103620100, \"adjusted\": 168.87},\n        {\"date\": 15905, \"open\": 168.52, \"high\": 169.23, \"low\": 168.31, \"close\": 169.17, \"volume\": 103831700, \"adjusted\": 169.17},\n        {\"date\": 15908, \"open\": 169.41, \"high\": 169.74, \"low\": 169.01, \"close\": 169.5, \"volume\": 79428600, \"adjusted\": 169.5},\n        {\"date\": 15909, \"open\": 169.8, \"high\": 169.83, \"low\": 169.05, \"close\": 169.14, \"volume\": 80829700, \"adjusted\": 169.14},\n        {\"date\": 15910, \"open\": 169.79, \"high\": 169.86, \"low\": 168.18, \"close\": 168.52, \"volume\": 112914000, \"adjusted\": 168.52},\n        {\"date\": 15911, \"open\": 168.22, \"high\": 169.08, \"low\": 167.94, \"close\": 168.93, \"volume\": 111088600, \"adjusted\": 168.93},\n        {\"date\": 15912, \"open\": 168.22, \"high\": 169.16, \"low\": 167.52, \"close\": 169.11, \"volume\": 107814600, \"adjusted\": 169.11},\n        {\"date\": 15915, \"open\": 168.68, \"high\": 169.06, \"low\": 168.11, \"close\": 168.59, \"volume\": 79695000, \"adjusted\": 168.59},\n        {\"date\": 15916, \"open\": 169.1, \"high\": 169.28, \"low\": 168.19, \"close\": 168.59, \"volume\": 85209600, \"adjusted\": 168.59},\n        {\"date\": 15917, \"open\": 168.94, \"high\": 169.85, \"low\": 168.49, \"close\": 168.71, \"volume\": 142388700, \"adjusted\": 168.71},\n        {\"date\": 15918, \"open\": 169.99, \"high\": 170.81, \"low\": 169.9, \"close\": 170.66, \"volume\": 110438400, \"adjusted\": 170.66},\n        {\"date\": 15919, \"open\": 170.28, \"high\": 170.97, \"low\": 170.05, \"close\": 170.95, \"volume\": 91116700, \"adjusted\": 170.95},\n        {\"date\": 15922, \"open\": 170.57, \"high\": 170.96, \"low\": 170.35, \"close\": 170.7, \"volume\": 54072700, \"adjusted\": 170.7},\n        {\"date\": 15923, \"open\": 170.37, \"high\": 170.74, \"low\": 169.35, \"close\": 169.73, \"volume\": 87495000, \"adjusted\": 169.73},\n        {\"date\": 15924, \"open\": 169.19, \"high\": 169.43, \"low\": 168.55, \"close\": 169.18, \"volume\": 84854700, \"adjusted\": 169.18},\n        {\"date\": 15925, \"open\": 169.98, \"high\": 170.18, \"low\": 168.93, \"close\": 169.8, \"volume\": 102181300, \"adjusted\": 169.8},\n        {\"date\": 15926, \"open\": 169.58, \"high\": 170.1, \"low\": 168.72, \"close\": 169.31, \"volume\": 91757700, \"adjusted\": 169.31},\n        {\"date\": 15929, \"open\": 168.46, \"high\": 169.31, \"low\": 168.38, \"close\": 169.11, \"volume\": 68593300, \"adjusted\": 169.11},\n        {\"date\": 15930, \"open\": 169.41, \"high\": 169.9, \"low\": 168.41, \"close\": 169.61, \"volume\": 80806000, \"adjusted\": 169.61},\n        {\"date\": 15931, \"open\": 169.53, \"high\": 169.8, \"low\": 168.7, \"close\": 168.74, \"volume\": 79829200, \"adjusted\": 168.74},\n        {\"date\": 15932, \"open\": 167.41, \"high\": 167.43, \"low\": 166.09, \"close\": 166.38, \"volume\": 152931800, \"adjusted\": 166.38},\n        {\"date\": 15933, \"open\": 166.06, \"high\": 166.63, \"low\": 165.5, \"close\": 165.83, \"volume\": 130868200, \"adjusted\": 165.83},\n        {\"date\": 15936, \"open\": 165.64, \"high\": 166.21, \"low\": 164.76, \"close\": 164.77, \"volume\": 96437600, \"adjusted\": 164.77},\n        {\"date\": 15937, \"open\": 165.04, \"high\": 166.2, \"low\": 164.86, \"close\": 165.58, \"volume\": 89294400, \"adjusted\": 165.58},\n        {\"date\": 15938, \"open\": 165.12, \"high\": 166.03, \"low\": 164.19, \"close\": 164.56, \"volume\": 159530500, \"adjusted\": 164.56},\n        {\"date\": 15939, \"open\": 164.9, \"high\": 166.3, \"low\": 164.89, \"close\": 166.06, \"volume\": 101471400, \"adjusted\": 166.06},\n        {\"date\": 15940, \"open\": 166.55, \"high\": 166.83, \"low\": 165.77, \"close\": 166.62, \"volume\": 90888900, \"adjusted\": 166.62},\n        {\"date\": 15943, \"open\": 166.79, \"high\": 167.3, \"low\": 165.89, \"close\": 166, \"volume\": 89702100, \"adjusted\": 166},\n        {\"date\": 15944, \"open\": 164.36, \"high\": 166, \"low\": 163.21, \"close\": 163.33, \"volume\": 158619400, \"adjusted\": 163.33},\n        {\"date\": 15945, \"open\": 163.26, \"high\": 164.49, \"low\": 163.05, \"close\": 163.91, \"volume\": 108113000, \"adjusted\": 163.91},\n        {\"date\": 15946, \"open\": 163.55, \"high\": 165.04, \"low\": 163.4, \"close\": 164.17, \"volume\": 119200500, \"adjusted\": 164.17},\n        {\"date\": 15947, \"open\": 164.51, \"high\": 164.53, \"low\": 163.17, \"close\": 163.65, \"volume\": 134560800, \"adjusted\": 163.65},\n        {\"date\": 15951, \"open\": 165.23, \"high\": 165.58, \"low\": 163.7, \"close\": 164.39, \"volume\": 142322300, \"adjusted\": 164.39},\n        {\"date\": 15952, \"open\": 164.43, \"high\": 166.03, \"low\": 164.13, \"close\": 165.75, \"volume\": 97304000, \"adjusted\": 165.75},\n        {\"date\": 15953, \"open\": 165.85, \"high\": 166.4, \"low\": 165.73, \"close\": 165.96, \"volume\": 62930500, \"adjusted\": 165.96}\n    ]}];\n\n    nv.addGraph(function() {\n        var chart = nv.models.candlestickBarChart()\n            .x(function(d) { return d['date'] })\n            .y(function(d) { return d['close'] })\n            .duration(250)\n            .margin({left: 75, bottom: 50});\n\n        // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        chart.xAxis\n                .axisLabel(\"Dates\")\n                .tickFormat(function(d) {\n                    // I didn't feel like changing all the above date values\n                    // so I hack it to make each value fall on a different date\n                    return d3.time.format('%x')(new Date(new Date() - (20000 * 86400000) + (d * 86400000)));\n                });\n\n        chart.yAxis\n                .axisLabel('Stock Price')\n                .tickFormat(function(d,i){ return '$' + d3.format(',.1f')(d); });\n\n\n\n        d3.select(\"#chart1 svg\")\n                .datum(data)\n                .transition().duration(500)\n                .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/cumulativeLineChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            width: 100%;\n            height: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    // Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs,\n    // and may do more in the future... it's NOT required\n    nv.addGraph(function() {\n        var chart = nv.models.cumulativeLineChart()\n            .useInteractiveGuideline(true)\n            .x(function(d) { return d[0] })\n            .y(function(d) { return d[1]/100 })\n            .color(d3.scale.category10().range())\n            .average(function(d) { return d.mean/100; })\n            .duration(300)\n            .clipVoronoi(false);\n        chart.dispatch.on('renderEnd', function() {\n            console.log('render complete: cumulative line with guide line');\n        });\n\n        chart.xAxis.tickFormat(function(d) {\n            return d3.time.format('%m/%d/%y')(new Date(d))\n        });\n\n        chart.yAxis.tickFormat(d3.format(',.1%'));\n\n        d3.select('#chart1 svg')\n            .datum(cumulativeTestData())\n            .call(chart);\n\n        //TODO: Figure out a good way to do this automatically\n        nv.utils.windowResize(chart.update);\n\n        chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n        chart.state.dispatch.on('change', function(state){\n            nv.log('state', JSON.stringify(state));\n        });\n\n        return chart;\n    });\n\n    function flatTestData() {\n        return [{\n            key: \"Snakes\",\n            values: [0,1,2,3,4,5,6,7,8,9].map(function(d) {\n                var currentDate = new Date();\n                currentDate.setDate(currentDate.getDate() + d);\n                return [currentDate, 0]\n            })\n        }];\n    }\n\n    function cumulativeTestData() {\n        return [\n            {\n                key: \"Long\",\n                values: [ [ 1083297600000 , -2.974623048543] , [ 1085976000000 , -1.7740300785979] , [ 1088568000000 , 4.4681318138177] , [ 1091246400000 , 7.0242541001353] , [ 1093924800000 , 7.5709603667586] , [ 1096516800000 , 20.612245065736] , [ 1099195200000 , 21.698065237316] , [ 1101790800000 , 40.501189458018] , [ 1104469200000 , 50.464679413194] , [ 1107147600000 , 48.917421973355] , [ 1109566800000 , 63.750936549160] , [ 1112245200000 , 59.072499126460] , [ 1114833600000 , 43.373158880492] , [ 1117512000000 , 54.490918947556] , [ 1120104000000 , 56.661178852079] , [ 1122782400000 , 73.450103545496] , [ 1125460800000 , 71.714526354907] , [ 1128052800000 , 85.221664349607] , [ 1130734800000 , 77.769261392481] , [ 1133326800000 , 95.966528716500] , [ 1136005200000 , 107.59132116397] , [ 1138683600000 , 127.25740096723] , [ 1141102800000 , 122.13917498830] , [ 1143781200000 , 126.53657279774] , [ 1146369600000 , 132.39300992970] , [ 1149048000000 , 120.11238242904] , [ 1151640000000 , 118.41408917750] , [ 1154318400000 , 107.92918924621] , [ 1156996800000 , 110.28057249569] , [ 1159588800000 , 117.20485334692] , [ 1162270800000 , 141.33556756948] , [ 1164862800000 , 159.59452727893] , [ 1167541200000 , 167.09801853304] , [ 1170219600000 , 185.46849659215] , [ 1172638800000 , 184.82474099990] , [ 1175313600000 , 195.63155213887] , [ 1177905600000 , 207.40597044171] , [ 1180584000000 , 230.55966698196] , [ 1183176000000 , 239.55649035292] , [ 1185854400000 , 241.35915085208] , [ 1188532800000 , 239.89428956243] , [ 1191124800000 , 260.47781917715] , [ 1193803200000 , 276.39457482225] , [ 1196398800000 , 258.66530682672] , [ 1199077200000 , 250.98846121893] , [ 1201755600000 , 226.89902618127] , [ 1204261200000 , 227.29009273807] , [ 1206936000000 , 218.66476654350] , [ 1209528000000 , 232.46605902918] , [ 1212206400000 , 253.25667081117] , [ 1214798400000 , 235.82505363925] , [ 1217476800000 , 229.70112774254] , [ 1220155200000 , 225.18472705952] , [ 1222747200000 , 189.13661746552] , [ 1225425600000 , 149.46533007301] , [ 1228021200000 , 131.00340772114] , [ 1230699600000 , 135.18341728866] , [ 1233378000000 , 109.15296887173] , [ 1235797200000 , 84.614772549760] , [ 1238472000000 , 100.60810015326] , [ 1241064000000 , 141.50134895610] , [ 1243742400000 , 142.50405083675] , [ 1246334400000 , 139.81192372672] , [ 1249012800000 , 177.78205544583] , [ 1251691200000 , 194.73691933074] , [ 1254283200000 , 209.00838460225] , [ 1256961600000 , 198.19855877420] , [ 1259557200000 , 222.37102417812] , [ 1262235600000 , 234.24581081250] , [ 1264914000000 , 228.26087689346] , [ 1267333200000 , 248.81895126250] , [ 1270008000000 , 270.57301075186] , [ 1272600000000 , 292.64604322550] , [ 1275278400000 , 265.94088520518] , [ 1277870400000 , 237.82887467569] , [ 1280548800000 , 265.55973314204] , [ 1283227200000 , 248.30877330928] , [ 1285819200000 , 278.14870066912] , [ 1288497600000 , 292.69260960288] , [ 1291093200000 , 300.84263809599] , [ 1293771600000 , 326.17253914628] , [ 1296450000000 , 337.69335966505] , [ 1298869200000 , 339.73260965121] , [ 1301544000000 , 346.87865120765] , [ 1304136000000 , 347.92991526628] , [ 1306814400000 , 342.04627502669] , [ 1309406400000 , 333.45386231233] , [ 1312084800000 , 323.15034181243] , [ 1314763200000 , 295.66126882331] , [ 1317355200000 , 251.48014579253] , [ 1320033600000 , 295.15424257905] , [ 1322629200000 , 294.54766764397] , [ 1325307600000 , 295.72906119051] , [ 1327986000000 , 325.73351347613] , [ 1330491600000 , 340.16106061186] , [ 1333166400000 , 345.15514071490] , [ 1335758400000 , 337.10259395679] , [ 1338436800000 , 318.68216333837] , [ 1341028800000 , 317.03683945246] , [ 1343707200000 , 318.53549659997] , [ 1346385600000 , 332.85381464104] , [ 1348977600000 , 337.36534373477] , [ 1351656000000 , 350.27872156161] , [ 1354251600000 , 349.45128876100]]\n                ,\n                mean: 250\n            },\n            {\n                key: \"Short\",\n                values: [ [ 1083297600000 , -0.77078283705125] , [ 1085976000000 , -1.8356366650335] , [ 1088568000000 , -5.3121322073127] , [ 1091246400000 , -4.9320975829662] , [ 1093924800000 , -3.9835408823225] , [ 1096516800000 , -6.8694685316805] , [ 1099195200000 , -8.4854877428545] , [ 1101790800000 , -15.933627197384] , [ 1104469200000 , -15.920980069544] , [ 1107147600000 , -12.478685045651] , [ 1109566800000 , -17.297761889305] , [ 1112245200000 , -15.247129891020] , [ 1114833600000 , -11.336459046839] , [ 1117512000000 , -13.298990907415] , [ 1120104000000 , -16.360027000056] , [ 1122782400000 , -18.527929522030] , [ 1125460800000 , -22.176516738685] , [ 1128052800000 , -23.309665368330] , [ 1130734800000 , -21.629973409748] , [ 1133326800000 , -24.186429093486] , [ 1136005200000 , -29.116707312531] , [ 1138683600000 , -37.188037874864] , [ 1141102800000 , -34.689264821198] , [ 1143781200000 , -39.505932105359] , [ 1146369600000 , -45.339572492759] , [ 1149048000000 , -43.849353192764] , [ 1151640000000 , -45.418353922571] , [ 1154318400000 , -44.579281059919] , [ 1156996800000 , -44.027098363370] , [ 1159588800000 , -41.261306759439] , [ 1162270800000 , -47.446018534027] , [ 1164862800000 , -53.413782948909] , [ 1167541200000 , -50.700723647419] , [ 1170219600000 , -56.374090913296] , [ 1172638800000 , -61.754245220322] , [ 1175313600000 , -66.246241587629] , [ 1177905600000 , -75.351650899999] , [ 1180584000000 , -81.699058262032] , [ 1183176000000 , -82.487023368081] , [ 1185854400000 , -86.230055113277] , [ 1188532800000 , -84.746914818507] , [ 1191124800000 , -100.77134971977] , [ 1193803200000 , -109.95435565947] , [ 1196398800000 , -99.605672965057] , [ 1199077200000 , -99.607249394382] , [ 1201755600000 , -94.874614950188] , [ 1204261200000 , -105.35899063105] , [ 1206936000000 , -106.01931193802] , [ 1209528000000 , -110.28883571771] , [ 1212206400000 , -119.60256203030] , [ 1214798400000 , -115.62201315802] , [ 1217476800000 , -106.63824185202] , [ 1220155200000 , -99.848746318951] , [ 1222747200000 , -85.631219602987] , [ 1225425600000 , -63.547909262067] , [ 1228021200000 , -59.753275364457] , [ 1230699600000 , -63.874977883542] , [ 1233378000000 , -56.865697387488] , [ 1235797200000 , -54.285579501988] , [ 1238472000000 , -56.474659581885] , [ 1241064000000 , -63.847137745644] , [ 1243742400000 , -68.754247867325] , [ 1246334400000 , -69.474257009155] , [ 1249012800000 , -75.084828197067] , [ 1251691200000 , -77.101028237237] , [ 1254283200000 , -80.454866854387] , [ 1256961600000 , -78.984349952220] , [ 1259557200000 , -83.041230807854] , [ 1262235600000 , -84.529748348935] , [ 1264914000000 , -83.837470195508] , [ 1267333200000 , -87.174487671969] , [ 1270008000000 , -90.342293007487] , [ 1272600000000 , -93.550928464991] , [ 1275278400000 , -85.833102140765] , [ 1277870400000 , -79.326501831592] , [ 1280548800000 , -87.986196903537] , [ 1283227200000 , -85.397862121771] , [ 1285819200000 , -94.738167050020] , [ 1288497600000 , -98.661952897151] , [ 1291093200000 , -99.609665952708] , [ 1293771600000 , -103.57099836183] , [ 1296450000000 , -104.04353411322] , [ 1298869200000 , -108.21382792587] , [ 1301544000000 , -108.74006900920] , [ 1304136000000 , -112.07766650960] , [ 1306814400000 , -109.63328199118] , [ 1309406400000 , -106.53578966772] , [ 1312084800000 , -103.16480871469] , [ 1314763200000 , -95.945078001828] , [ 1317355200000 , -81.226687340874] , [ 1320033600000 , -90.782206596168] , [ 1322629200000 , -89.484445370113] , [ 1325307600000 , -88.514723135326] , [ 1327986000000 , -93.381292724320] , [ 1330491600000 , -97.529705609172] , [ 1333166400000 , -99.520481439189] , [ 1335758400000 , -99.430184898669] , [ 1338436800000 , -93.349934521973] , [ 1341028800000 , -95.858475286491] , [ 1343707200000 , -95.522755836605] , [ 1346385600000 , -98.503848862036] , [ 1348977600000 , -101.49415251896] , [ 1351656000000 , -101.50099325672] , [ 1354251600000 , -99.487094927489]]\n                ,\n                mean: -60\n            },\n            {\n                key: \"Gross\",\n                mean: 125,\n                values: [ [ 1083297600000 , -3.7454058855943] , [ 1085976000000 , -3.6096667436314] , [ 1088568000000 , -0.8440003934950] , [ 1091246400000 , 2.0921565171691] , [ 1093924800000 , 3.5874194844361] , [ 1096516800000 , 13.742776534056] , [ 1099195200000 , 13.212577494462] , [ 1101790800000 , 24.567562260634] , [ 1104469200000 , 34.543699343650] , [ 1107147600000 , 36.438736927704] , [ 1109566800000 , 46.453174659855] , [ 1112245200000 , 43.825369235440] , [ 1114833600000 , 32.036699833653] , [ 1117512000000 , 41.191928040141] , [ 1120104000000 , 40.301151852023] , [ 1122782400000 , 54.922174023466] , [ 1125460800000 , 49.538009616222] , [ 1128052800000 , 61.911998981277] , [ 1130734800000 , 56.139287982733] , [ 1133326800000 , 71.780099623014] , [ 1136005200000 , 78.474613851439] , [ 1138683600000 , 90.069363092366] , [ 1141102800000 , 87.449910167102] , [ 1143781200000 , 87.030640692381] , [ 1146369600000 , 87.053437436941] , [ 1149048000000 , 76.263029236276] , [ 1151640000000 , 72.995735254929] , [ 1154318400000 , 63.349908186291] , [ 1156996800000 , 66.253474132320] , [ 1159588800000 , 75.943546587481] , [ 1162270800000 , 93.889549035453] , [ 1164862800000 , 106.18074433002] , [ 1167541200000 , 116.39729488562] , [ 1170219600000 , 129.09440567885] , [ 1172638800000 , 123.07049577958] , [ 1175313600000 , 129.38531055124] , [ 1177905600000 , 132.05431954171] , [ 1180584000000 , 148.86060871993] , [ 1183176000000 , 157.06946698484] , [ 1185854400000 , 155.12909573880] , [ 1188532800000 , 155.14737474392] , [ 1191124800000 , 159.70646945738] , [ 1193803200000 , 166.44021916278] , [ 1196398800000 , 159.05963386166] , [ 1199077200000 , 151.38121182455] , [ 1201755600000 , 132.02441123108] , [ 1204261200000 , 121.93110210702] , [ 1206936000000 , 112.64545460548] , [ 1209528000000 , 122.17722331147] , [ 1212206400000 , 133.65410878087] , [ 1214798400000 , 120.20304048123] , [ 1217476800000 , 123.06288589052] , [ 1220155200000 , 125.33598074057] , [ 1222747200000 , 103.50539786253] , [ 1225425600000 , 85.917420810943] , [ 1228021200000 , 71.250132356683] , [ 1230699600000 , 71.308439405118] , [ 1233378000000 , 52.287271484242] , [ 1235797200000 , 30.329193047772] , [ 1238472000000 , 44.133440571375] , [ 1241064000000 , 77.654211210456] , [ 1243742400000 , 73.749802969425] , [ 1246334400000 , 70.337666717565] , [ 1249012800000 , 102.69722724876] , [ 1251691200000 , 117.63589109350] , [ 1254283200000 , 128.55351774786] , [ 1256961600000 , 119.21420882198] , [ 1259557200000 , 139.32979337027] , [ 1262235600000 , 149.71606246357] , [ 1264914000000 , 144.42340669795] , [ 1267333200000 , 161.64446359053] , [ 1270008000000 , 180.23071774437] , [ 1272600000000 , 199.09511476051] , [ 1275278400000 , 180.10778306442] , [ 1277870400000 , 158.50237284410] , [ 1280548800000 , 177.57353623850] , [ 1283227200000 , 162.91091118751] , [ 1285819200000 , 183.41053361910] , [ 1288497600000 , 194.03065670573] , [ 1291093200000 , 201.23297214328] , [ 1293771600000 , 222.60154078445] , [ 1296450000000 , 233.35556801977] , [ 1298869200000 , 231.22452435045] , [ 1301544000000 , 237.84432503045] , [ 1304136000000 , 235.55799131184] , [ 1306814400000 , 232.11873570751] , [ 1309406400000 , 226.62381538123] , [ 1312084800000 , 219.34811113539] , [ 1314763200000 , 198.69242285581] , [ 1317355200000 , 168.90235629066] , [ 1320033600000 , 202.64725756733] , [ 1322629200000 , 203.05389378105] , [ 1325307600000 , 204.85986680865] , [ 1327986000000 , 229.77085616585] , [ 1330491600000 , 239.65202435959] , [ 1333166400000 , 242.33012622734] , [ 1335758400000 , 234.11773262149] , [ 1338436800000 , 221.47846307887] , [ 1341028800000 , 216.98308827912] , [ 1343707200000 , 218.37781386755] , [ 1346385600000 , 229.39368622736] , [ 1348977600000 , 230.54656412916] , [ 1351656000000 , 243.06087025523] , [ 1354251600000 , 244.24733578385]]\n            },\n            {\n                key: \"S&P 1500\",\n                values: [ [ 1083297600000 , -1.7798428181819] , [ 1085976000000 , -0.36883324836999] , [ 1088568000000 , 1.7312581046040] , [ 1091246400000 , -1.8356125950460] , [ 1093924800000 , -1.5396564170877] , [ 1096516800000 , -0.16867791409247] , [ 1099195200000 , 1.3754263993413] , [ 1101790800000 , 5.8171640898041] , [ 1104469200000 , 9.4350145241608] , [ 1107147600000 , 6.7649081510160] , [ 1109566800000 , 9.1568499314776] , [ 1112245200000 , 7.2485090994419] , [ 1114833600000 , 4.8762222306595] , [ 1117512000000 , 8.5992339354652] , [ 1120104000000 , 9.0896517982086] , [ 1122782400000 , 13.394644048577] , [ 1125460800000 , 12.311842010760] , [ 1128052800000 , 13.221003650717] , [ 1130734800000 , 11.218481009206] , [ 1133326800000 , 15.565352598445] , [ 1136005200000 , 15.623703865926] , [ 1138683600000 , 19.275255326383] , [ 1141102800000 , 19.432433717836] , [ 1143781200000 , 21.232881244655] , [ 1146369600000 , 22.798299192958] , [ 1149048000000 , 19.006125095476] , [ 1151640000000 , 19.151889158536] , [ 1154318400000 , 19.340022855452] , [ 1156996800000 , 22.027934841859] , [ 1159588800000 , 24.903300681329] , [ 1162270800000 , 29.146492833877] , [ 1164862800000 , 31.781626082589] , [ 1167541200000 , 33.358770738428] , [ 1170219600000 , 35.622684613497] , [ 1172638800000 , 33.332821711366] , [ 1175313600000 , 34.878748635832] , [ 1177905600000 , 40.582332613844] , [ 1180584000000 , 45.719535502920] , [ 1183176000000 , 43.239344722386] , [ 1185854400000 , 38.550955100342] , [ 1188532800000 , 40.585368816283] , [ 1191124800000 , 45.601374057981] , [ 1193803200000 , 48.051404337892] , [ 1196398800000 , 41.582581696032] , [ 1199077200000 , 40.650580792748] , [ 1201755600000 , 32.252222066493] , [ 1204261200000 , 28.106390258553] , [ 1206936000000 , 27.532698196687] , [ 1209528000000 , 33.986390463852] , [ 1212206400000 , 36.302660526438] , [ 1214798400000 , 25.015574480172] , [ 1217476800000 , 23.989494069029] , [ 1220155200000 , 25.934351445531] , [ 1222747200000 , 14.627592011699] , [ 1225425600000 , -5.2249403809749] , [ 1228021200000 , -12.330933408050] , [ 1230699600000 , -11.000291508188] , [ 1233378000000 , -18.563864948088] , [ 1235797200000 , -27.213097001687] , [ 1238472000000 , -20.834133840523] , [ 1241064000000 , -12.717886701719] , [ 1243742400000 , -8.1644613083526] , [ 1246334400000 , -7.9108408918201] , [ 1249012800000 , -0.77002391591209] , [ 1251691200000 , 2.8243816569672] , [ 1254283200000 , 6.8761411421070] , [ 1256961600000 , 4.5060912230294] , [ 1259557200000 , 10.487179794349] , [ 1262235600000 , 13.251375597594] , [ 1264914000000 , 9.2207594803415] , [ 1267333200000 , 12.836276936538] , [ 1270008000000 , 19.816793904978] , [ 1272600000000 , 22.156787167211] , [ 1275278400000 , 12.518039090576] , [ 1277870400000 , 6.4253587440854] , [ 1280548800000 , 13.847372028409] , [ 1283227200000 , 8.5454736090364] , [ 1285819200000 , 18.542801953304] , [ 1288497600000 , 23.037064683183] , [ 1291093200000 , 23.517422401888] , [ 1293771600000 , 31.804723416068] , [ 1296450000000 , 34.778247386072] , [ 1298869200000 , 39.584883855230] , [ 1301544000000 , 40.080647664875] , [ 1304136000000 , 44.180050667889] , [ 1306814400000 , 42.533535927221] , [ 1309406400000 , 40.105374449011] , [ 1312084800000 , 37.014659267156] , [ 1314763200000 , 29.263745084262] , [ 1317355200000 , 19.637463417584] , [ 1320033600000 , 33.157645345770] , [ 1322629200000 , 32.895053150988] , [ 1325307600000 , 34.111544824647] , [ 1327986000000 , 40.453985817473] , [ 1330491600000 , 46.435700783313] , [ 1333166400000 , 51.062385488671] , [ 1335758400000 , 50.130448220658] , [ 1338436800000 , 41.035476682018] , [ 1341028800000 , 46.591932296457] , [ 1343707200000 , 48.349391180634] , [ 1346385600000 , 51.913011286919] , [ 1348977600000 , 55.747238313752] , [ 1351656000000 , 52.991824077209] , [ 1354251600000 , 49.556311883284]]\n            }\n        ];\n    }\n\n</script>\n</body></html>"
  },
  {
    "path": "examples/differenceChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\" />\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.2/moment.js\"></script>\n    <script src=\"../build/nv.d3.js?dsf\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n<script>\n  var expandLegend = function() {\n      var exp = chart.multiChart.legend.expanded();\n      chart.multiChart.legend.align(false);\n      chart.update();\n  }\n</script>\n<svg id=\"chart2\"></svg>\n<div style=\"height: 1000px; background-color: red;\">\n\n</div>\n<script>\n  'use strict';\n\n  // Use the browser's built-in functionality to quickly and safely escape\n  // the string\n  function escapeHtml(str) {\n    var div = document.createElement('div');\n    div.appendChild(document.createTextNode(str));\n    return div.innerHTML;\n  }\n\n  var chart;\n\n  function readTextFile(file) {\n    return new Promise(function (resolve) {\n      var rawFile = new XMLHttpRequest();\n      rawFile.overrideMimeType('application/json');\n      rawFile.open('GET', file, true);\n      rawFile.onreadystatechange = function () {\n        if (rawFile.readyState === 4 && rawFile.status == '200') {\n          resolve(rawFile.responseText);\n        }\n      };\n      rawFile.send(null);\n    });\n  }\n\n  var keyForActualLessThanPredicted = 'Savings (kWh)';\n  var keyForActualGreaterThanPredicted = 'Excess Usage (kWh)';\n\n  function loadData() {\n    return Promise.all([readTextFile('./actual.json'), readTextFile('./predicted.json')]).then(function (jsonResult) {\n      return new Promise(function (resolve, reject) {\n        var actualData = JSON.parse(jsonResult[0]);\n        var predictedData = JSON.parse(jsonResult[1]);\n\n        resolve([{\n          key: 'Actual usage (kWh)',\n          type: 'actual',\n          values: actualData[0].values,\n          color: 'black'\n        }, {\n          key: 'Predicted usage (kWh)',\n          type: 'expected',\n          values: predictedData.map(function (d) {\n            return {\n              recorded_at: d.falling_edge,\n              value: d.predicted\n            };\n          }),\n          color: 'blue'\n        }]);\n      });\n    });\n  }\n\n  function main() {\n    var colors = d3.scale.category20();\n    var lang = d3.locale({\n      \"dateTime\": '%H:%M %A %e %B, %Y',\n      \"date\": '%Y-%m-%d',\n      \"time\": \"%H:%M:%S\",\n      \"periods\": ['am', 'pm'],\n      \"days\": [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"],\n      \"shortDays\": [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n      \"months\": [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n      \"shortMonths\": [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n    });\n\n    var tickFormatMaxMin = lang.timeFormat.multi([[\"%b %d\", function (d) {\n      return true;\n    }]]);\n    var tickFormat = lang.timeFormat.multi([[\":%L\", function (d) {\n      return d.getMilliseconds();\n    }], [\"%S\", function (d) {\n      return d.getSeconds();\n    }], [\"%H:%M\", function (d) {\n      return d.getMinutes();\n    }], [\"%H:%M\", function (d) {\n      return d.getHours();\n    }], [\"%d/%m\", function (d) {\n      return d.getDay() && d.getDate() != 1;\n    }], [\"%b %d\", function (d) {\n      return d.getDate() != 1;\n    }], [\"%b\", function (d) {\n      return d.getMonth();\n    }], [\"%Y\", function () {\n      return true;\n    }]]);\n\n    loadData().then(function (data) {\n      nv.addGraph(function () {\n        chart = nv.models.differenceChart();\n        chart.keyForXValue('recorded_at').x(function (d) {\n          return new Date(d.recorded_at);\n        }).y(function (d) {\n          return d.value;\n        }).keyForActualLessThanPredicted(keyForActualLessThanPredicted).keyForActualGreaterThanPredicted(keyForActualGreaterThanPredicted).height(500).showPredictedLine(true).interpolate('step-before').tickFormat(tickFormat).strokeWidth(0.5);\n\n        chart.multiChart.interactiveLayer.tooltip.contentGenerator(function (d) {\n          var header = d.value;\n          var headerhtml = \"<thead><tr><td colspan='3'><strong class='x-value'>\" + header + \"</strong></td></tr></thead>\";\n          var bodyhtml = \"<tbody>\";\n          var series = d.series;\n          series.forEach(function (c) {\n            var value = (c.value || 0).toFixed(2);\n            if (c.key === keyForActualGreaterThanPredicted || c.key === keyForActualLessThanPredicted) {\n              var diff = Math.abs(c.data.y0 - c.data.y1);\n              if (diff === 0) {\n                value = '-';\n              } else {\n                value = diff.toFixed(2);\n              }\n            }\n            bodyhtml = bodyhtml + \"<tr><td class='legend-color-guide'><div style='background-color: \" + escapeHtml(c.color) + \";'></div></td><td class='key'>\" + escapeHtml(c.key) + \"</td><td class='value'>\" + escapeHtml(value) + \"</td></tr>\";\n          });\n          bodyhtml = bodyhtml + \"</tbody>\";\n          return \"<table>\" + headerhtml + '' + bodyhtml + \"</table>\";\n        });\n\n        chart.xAxis.tickFormatMaxMin(tickFormatMaxMin);\n        chart.focus.xAxis.tickFormatMaxMin(tickFormatMaxMin);\n\n        chart.focus.height(40);\n        chart.focusMargin({ top: 10 });\n\n        chart.margin({ top: 60 });\n\n        d3.select('svg#chart2').datum(data).call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n      });\n    });\n  }\n\n  main();\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/discreteBarChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    historicalBarChart = [\n        {\n            key: \"Cumulative Return\",\n            values: [\n                {\n                    \"label\" : \"A\" ,\n                    \"value\" : 29.765957771107\n                } ,\n                {\n                    \"label\" : \"B\" ,\n                    \"value\" : 0\n                } ,\n                {\n                    \"label\" : \"C\" ,\n                    \"value\" : 32.807804682612\n                } ,\n                {\n                    \"label\" : \"D\" ,\n                    \"value\" : 196.45946739256\n                } ,\n                {\n                    \"label\" : \"E\" ,\n                    \"value\" : 0.19434030906893\n                } ,\n                {\n                    \"label\" : \"F\" ,\n                    \"value\" : 98.079782601442\n                } ,\n                {\n                    \"label\" : \"G\" ,\n                    \"value\" : 13.925743130903\n                } ,\n                {\n                    \"label\" : \"H\" ,\n                    \"value\" : 5.1387322875705\n                }\n            ]\n        }\n    ];\n\n    nv.addGraph(function() {\n        var chart = nv.models.discreteBarChart()\n            .x(function(d) { return d.label })\n            .y(function(d) { return d.value })\n            .staggerLabels(true)\n            //.staggerLabels(historicalBarChart[0].values.length > 8)\n            .showValues(true)\n            .duration(250)\n            ;\n\n        d3.select('#chart1 svg')\n            .datum(historicalBarChart)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/distroPlotChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<script src=\"https://cdn.rawgit.com/Kcnarf/d3-beeswarm/fbda9b54/build/d3-beeswarm.min.js\"></script>\n\n\n<head>\n    <style>\n\n          #chart {\n            height: 400px;\n          }\n\n          g.nv-distroplot {\n            stroke-width: 1.5;\n          }\n\n          html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n            font-family: 'system-ui';\n          }\n\n          .nv-distroplot-observation circle {\n            opacity: 0.7;\n            stroke-width: 1;\n          }\n\n          .nv-distroplot-outlier circle {\n            fill-opacity: 1;\n            opacity: 0.9;\n            stroke: #5C5C5C !important;\n            fill: #5C5C5C !important;\n          }\n\n          .buttons {\n            margin-top: 5px;\n            margin-left: 10px;\n            font-size: 80%;\n          }\n\n          button {\n            margin-bottom: 5px;\n          }\n\n          line.hover {\n            stroke-width:4;\n          }\n\n          circle.hover {\n            stroke-width: 8;\n            opacity: 1;\n          }\n\n    </style>\n</head>\n\n<body>\n\n    <div class=\"buttons\">\n        Plot types\n        <button onclick=\"updatePlot(defaultBox);\">Box</button>\n        <button onclick=\"updatePlot({plotType: 'violin'});\">Violin</button>\n        <button onclick=\"updatePlot({plotType: false});\">Scatter</button>\n         | X-axis\n        <button onclick=\"updatePlot({x: function(d) { return d.Isolator; }});\">Isolator</button>\n        <button onclick=\"updatePlot({x: function(d) { return d.Protocol; }});\">Protocol</button>\n        <button onclick=\"updatePlot({x: function(d) { return d.Subject; }});\">Subject</button>\n        <button onclick=\"updatePlot({x: function(d) { return d.Drug; }});\">Drug</button>\n        <button onclick=\"updatePlot({x: function(d) { return d.Study; }});\">Study</button>\n        <br>\n        Decorations\n        <button onclick=\"updatePlot({notchBox: true, plotType: 'box'});\">Notched box</button>\n        <button onclick=\"updatePlot({centralTendency: 'mean'});\">Mean line</button>\n        <button onclick=\"updatePlot({centralTendency: 'median'});\">Median line</button>\n        <button onclick=\"updatePlot({centralTendency: false});\">Remove mean/median line</button>\n        <button onclick=\"updatePlot({clampViolin: true});\">Clamp violins</button>\n        <br>\n        Observation positions\n        <button onclick=\"updatePlot({observationType: 'random'});\">Random</button>\n        <button onclick=\"showOnlyOutliers=!showOnlyOutliers; updatePlot({showOnlyOutliers: showOnlyOutliers});\">toggle showOnlyOutliers</button>\n        <button onclick=\"updatePlot({observationType: 'swarm'});\">Swarm</button>\n        <button onclick=\"updatePlot({observationType: 'centered'});\">Center</button>\n        <button onclick=\"updatePlot({observationType: 'line'});\">Line</button>\n        <button onclick=\"updatePlot({observationType: false});\">Hidden</button>\n        <br>\n        Whisker definitions\n        <button onclick=\"updatePlot({whiskerDef: 'iqr', hideWhiskers: false});\">Tukey</button>\n        <button onclick=\"updatePlot({whiskerDef: 'stddev', hideWhiskers: false});\">1 * std. dev.</button>\n        <button onclick=\"updatePlot({whiskerDef: 'minmax', hideWhiskers: false});\">min/max</button>\n        <button onclick=\"updatePlot({hideWhiskers: true});\">Hidden</button>\n         | Grouping\n        <button onclick=\"updatePlot({colorGroup: function(d) { return d.Isolator; }, squash: false});\">No squash</button>\n        <button onclick=\"updatePlot({colorGroup: function(d) { return d.Isolator; }, squash: true});\">Squashed</button>\n    </div>\n\n    <div id=\"chart\">\n        <svg></svg>\n    </div>\n\n</body>\n\n<script>\n\n    var chart = nv.models.distroPlotChart();\n    var showOnlyOutliers = true;\n    var defaultBox = {\n        x: function(d) { return d.Study },\n        y: function(d) { return d.Weight },\n        colorGroup: false,\n        resolution: 50,\n        bandwidth: 'scott',\n        maxBoxWidth: null,\n        xLabel: false,\n        yLabel: false,\n        centralTendency: 'median',\n        squash: false,\n        plotType: 'box',\n        observationType: 'random',\n        jitter: 0.7,\n        hideWhiskers: false,\n        notchBox: false,\n        clampViolin: false,\n        showOnlyOutliers: showOnlyOutliers,\n    }\n\n    // setup default chart\n    nv.addGraph(function() {\n\n        setChart(defaultBox);\n\n        d3.select('#chart svg')\n            .datum(data)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    })\n\n    // update chart with new settings\n    function updatePlot(update) {\n\n        setChart(update);\n        chart.update();\n    }\n\n    // set chart settings\n    function setChart(update) {\n\n        Object.keys(update).forEach(function(optName, i) {\n            var optVal = Object.values(update)[i];\n            chart[optName](optVal)\n        });\n\n    }\n\n    var data = [\n        {Subject: 157418, Study: 'I', Weight: 11.7, Date: '2016-07-26', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 10.9, Date: '2016-07-27', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 12.9, Date: '2016-07-29', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 14.4, Date: '2016-08-02', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 16.6, Date: '2016-08-09', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 17.1, Date: '2016-08-16', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 17.6, Date: '2016-08-23', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 157418, Study: 'I', Weight: 18.2, Date: '2016-08-30', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 15.9, Date: '2016-07-26', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 14.5, Date: '2016-07-27', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 15.5, Date: '2016-07-29', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 16.1, Date: '2016-08-02', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 16.8, Date: '2016-08-09', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 17.6, Date: '2016-08-16', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 18.4, Date: '2016-08-23', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 407601, Study: 'I', Weight: 17.6, Date: '2016-08-30', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 12, Date: '2016-07-26', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 11.6, Date: '2016-07-27', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 11.7, Date: '2016-07-29', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 14.2, Date: '2016-08-02', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 15.5, Date: '2016-08-09', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 15.3, Date: '2016-08-16', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 14.8, Date: '2016-08-23', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 158150, Study: 'I', Weight: 15.5, Date: '2016-08-30', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 10.4, Date: '2016-07-26', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 10.5, Date: '2016-07-27', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 12.5, Date: '2016-07-29', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 14.4, Date: '2016-08-02', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 17.4, Date: '2016-08-09', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 17.5, Date: '2016-08-16', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 17.7, Date: '2016-08-23', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 155953, Study: 'I', Weight: 18.2, Date: '2016-08-30', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 12.5, Date: '2016-07-26', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 11.9, Date: '2016-07-27', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 14.4, Date: '2016-07-29', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 15, Date: '2016-08-02', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 16.4, Date: '2016-08-09', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 16.5, Date: '2016-08-16', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 16.5, Date: '2016-08-23', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 906502, Study: 'I', Weight: 16.9, Date: '2016-08-30', Protocol: 'control', Drug: 'zeta', Isolator: 'A'},\n        {Subject: 405404, Study: 'I', Weight: 15.1, Date: '2016-07-26', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 13.9, Date: '2016-07-27', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 15.2, Date: '2016-07-29', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 16.2, Date: '2016-08-02', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 17.3, Date: '2016-08-09', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 18.4, Date: '2016-08-16', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 18.4, Date: '2016-08-23', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 405404, Study: 'I', Weight: 18.5, Date: '2016-08-30', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 10.9, Date: '2016-07-26', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 12, Date: '2016-07-27', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 13.3, Date: '2016-07-29', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 13.6, Date: '2016-08-02', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 17.5, Date: '2016-08-09', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 19.4, Date: '2016-08-16', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 19.9, Date: '2016-08-23', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657052, Study: 'I', Weight: 20.1, Date: '2016-08-30', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 12.7, Date: '2016-07-26', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 12.1, Date: '2016-07-27', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 13.9, Date: '2016-07-29', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 15.3, Date: '2016-08-02', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 17.7, Date: '2016-08-09', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 18.8, Date: '2016-08-16', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 18.3, Date: '2016-08-23', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 907235, Study: 'I', Weight: 19.3, Date: '2016-08-30', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 10.9, Date: '2016-07-26', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 10.6, Date: '2016-07-27', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 13.3, Date: '2016-07-29', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 13, Date: '2016-08-02', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 17.3, Date: '2016-08-09', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 17.3, Date: '2016-08-16', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 18.1, Date: '2016-08-23', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 657784, Study: 'I', Weight: 18.6, Date: '2016-08-30', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 12.6, Date: '2016-07-26', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 12.3, Date: '2016-07-27', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 14.3, Date: '2016-07-29', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 16, Date: '2016-08-02', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 18.2, Date: '2016-08-09', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 18.6, Date: '2016-08-16', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 18.7, Date: '2016-08-23', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 655587, Study: 'I', Weight: 18.9, Date: '2016-08-30', Protocol: 'control', Drug: 'iota', Isolator: 'B'},\n        {Subject: 408333, Study: 'I', Weight: 11.6, Date: '2016-07-26', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 13.2, Date: '2016-07-27', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 13.2, Date: '2016-07-29', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 15.1, Date: '2016-08-02', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 17.4, Date: '2016-08-09', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 17.2, Date: '2016-08-16', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 17.4, Date: '2016-08-23', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 408333, Study: 'I', Weight: 17.8, Date: '2016-08-30', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 13, Date: '2016-07-26', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 13.2, Date: '2016-07-27', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 14.7, Date: '2016-07-29', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 15.1, Date: '2016-08-02', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 16, Date: '2016-08-09', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 16.2, Date: '2016-08-16', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 16.5, Date: '2016-08-23', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 908700, Study: 'I', Weight: 17.5, Date: '2016-08-30', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 13.8, Date: '2016-07-26', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 14, Date: '2016-07-27', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 14.6, Date: '2016-07-29', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 14.7, Date: '2016-08-02', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 18.5, Date: '2016-08-09', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 19, Date: '2016-08-16', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 19.3, Date: '2016-08-23', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 406136, Study: 'I', Weight: 20, Date: '2016-08-30', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 10.2, Date: '2016-07-26', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 10.5, Date: '2016-07-27', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 12.5, Date: '2016-07-29', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 13.2, Date: '2016-08-02', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 16.7, Date: '2016-08-09', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 17.6, Date: '2016-08-16', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 17.1, Date: '2016-08-23', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 656319, Study: 'I', Weight: 17.2, Date: '2016-08-30', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 14.5, Date: '2016-07-26', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 13.7, Date: '2016-07-27', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 16.6, Date: '2016-07-29', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 17.5, Date: '2016-08-02', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 18.3, Date: '2016-08-09', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 19.7, Date: '2016-08-16', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 20.2, Date: '2016-08-23', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 156685, Study: 'I', Weight: 20.7, Date: '2016-08-30', Protocol: 'control', Drug: 'beta', Isolator: 'C'},\n        {Subject: 157418, Study: 'I', Weight: 14.4, Date: '2016-07-26', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 13.1, Date: '2016-07-27', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 15.4, Date: '2016-07-29', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 16.1, Date: '2016-08-02', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 17.4, Date: '2016-08-09', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 18.7, Date: '2016-08-16', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 18.3, Date: '2016-08-23', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 157418, Study: 'I', Weight: 18.8, Date: '2016-08-30', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 15.4, Date: '2016-07-26', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 14.3, Date: '2016-07-27', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 16.4, Date: '2016-07-29', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 16.6, Date: '2016-08-02', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 17.4, Date: '2016-08-09', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 18.5, Date: '2016-08-16', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 19, Date: '2016-08-23', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 907967, Study: 'I', Weight: 18.8, Date: '2016-08-30', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 11.3, Date: '2016-07-26', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 10.6, Date: '2016-07-27', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 13.1, Date: '2016-07-29', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 13.8, Date: '2016-08-02', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 17.3, Date: '2016-08-09', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 17.9, Date: '2016-08-16', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 18.3, Date: '2016-08-23', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 155953, Study: 'I', Weight: 18, Date: '2016-08-30', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 13.4, Date: '2016-07-26', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 12.5, Date: '2016-07-27', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 14.5, Date: '2016-07-29', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 16.4, Date: '2016-08-02', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 19.1, Date: '2016-08-09', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 18.6, Date: '2016-08-16', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 19, Date: '2016-08-23', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 156685, Study: 'I', Weight: 19.4, Date: '2016-08-30', Protocol: 'control', Drug: 'delta', Isolator: 'D'},\n        {Subject: 405404, Study: 'I', Weight: 12.6, Date: '2016-07-26', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 12, Date: '2016-07-27', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 14.8, Date: '2016-07-29', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 16.6, Date: '2016-08-02', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 18, Date: '2016-08-09', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 17.8, Date: '2016-08-16', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 18.2, Date: '2016-08-23', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 405404, Study: 'I', Weight: 18.8, Date: '2016-08-30', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 14.8, Date: '2016-07-26', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 13.2, Date: '2016-07-27', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 15.9, Date: '2016-07-29', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 17.3, Date: '2016-08-02', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 17.8, Date: '2016-08-09', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 18.9, Date: '2016-08-16', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 18.1, Date: '2016-08-23', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 907235, Study: 'I', Weight: 18.5, Date: '2016-08-30', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 11.4, Date: '2016-07-26', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 10.3, Date: '2016-07-27', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 13.4, Date: '2016-07-29', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 15.8, Date: '2016-08-02', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 18.1, Date: '2016-08-09', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 17.5, Date: '2016-08-16', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 17, Date: '2016-08-23', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657784, Study: 'I', Weight: 17.3, Date: '2016-08-30', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 14.3, Date: '2016-07-26', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 14.9, Date: '2016-07-27', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 14.8, Date: '2016-07-29', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 15, Date: '2016-08-02', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 15.2, Date: '2016-08-09', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 16.1, Date: '2016-08-16', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 15.8, Date: '2016-08-23', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 655587, Study: 'I', Weight: 15.8, Date: '2016-08-30', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 12.8, Date: '2016-07-26', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 12.4, Date: '2016-07-27', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 13.4, Date: '2016-07-29', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 16.5, Date: '2016-08-02', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 20.1, Date: '2016-08-09', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 20.7, Date: '2016-08-16', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 20.6, Date: '2016-08-23', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 406868, Study: 'I', Weight: 21, Date: '2016-08-30', Protocol: 'control', Drug: 'epsilon', Isolator: 'E'},\n        {Subject: 657052, Study: 'I', Weight: 12.6, Date: '2016-07-26', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 11.1, Date: '2016-07-27', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 14, Date: '2016-07-29', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 15.3, Date: '2016-08-02', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 18.1, Date: '2016-08-09', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 17.7, Date: '2016-08-16', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 17.5, Date: '2016-08-23', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 657052, Study: 'I', Weight: 17.6, Date: '2016-08-30', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 18.2, Date: '2016-07-26', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 15, Date: '2016-07-27', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 17.7, Date: '2016-07-29', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 16.4, Date: '2016-08-02', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 18.1, Date: '2016-08-09', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 18.7, Date: '2016-08-16', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 18.3, Date: '2016-08-23', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 158150, Study: 'I', Weight: 18, Date: '2016-08-30', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 15.1, Date: '2016-07-26', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 14.2, Date: '2016-07-27', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 15.2, Date: '2016-07-29', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 14.9, Date: '2016-08-02', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 15.3, Date: '2016-08-09', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 16.1, Date: '2016-08-16', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 16.2, Date: '2016-08-23', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 905770, Study: 'I', Weight: 16.5, Date: '2016-08-30', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 12.8, Date: '2016-07-26', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 12.1, Date: '2016-07-27', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 14.5, Date: '2016-07-29', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 14.9, Date: '2016-08-02', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 17, Date: '2016-08-09', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 17.4, Date: '2016-08-16', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 17.6, Date: '2016-08-23', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 406136, Study: 'I', Weight: 18, Date: '2016-08-30', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 13.6, Date: '2016-07-26', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 12.8, Date: '2016-07-27', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 14.4, Date: '2016-07-29', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 14.6, Date: '2016-08-02', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 15.1, Date: '2016-08-09', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 16, Date: '2016-08-16', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 16.3, Date: '2016-08-23', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 656319, Study: 'I', Weight: 17.1, Date: '2016-08-30', Protocol: 'control', Drug: 'eta', Isolator: 'F'},\n        {Subject: 907235, Study: 'II', Weight: 15.4, Date: '2016-09-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907235, Study: 'II', Weight: 15.9, Date: '2016-09-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907235, Study: 'II', Weight: 16.8, Date: '2016-09-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907235, Study: 'II', Weight: 18.4, Date: '2016-09-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907235, Study: 'II', Weight: 18.5, Date: '2016-09-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907235, Study: 'II', Weight: 18.8, Date: '2016-10-07', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 13.9, Date: '2016-09-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 15, Date: '2016-09-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 16.2, Date: '2016-09-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 17.5, Date: '2016-09-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 18.8, Date: '2016-09-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657784, Study: 'II', Weight: 19.6, Date: '2016-10-07', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 10.9, Date: '2016-09-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 12.1, Date: '2016-09-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 15, Date: '2016-09-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 17.1, Date: '2016-09-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 18.1, Date: '2016-09-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'II', Weight: 17.9, Date: '2016-10-07', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 13.6, Date: '2016-09-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 14.9, Date: '2016-09-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 16.8, Date: '2016-09-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 17.7, Date: '2016-09-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 18.4, Date: '2016-09-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'II', Weight: 17.9, Date: '2016-10-07', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 13.9, Date: '2016-09-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 14.2, Date: '2016-09-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 16.8, Date: '2016-09-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 17.1, Date: '2016-09-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 17.4, Date: '2016-09-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'II', Weight: 17.2, Date: '2016-10-07', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 405404, Study: 'II', Weight: 14.1, Date: '2016-09-09', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 14.9, Date: '2016-09-12', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 17, Date: '2016-09-16', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 18.1, Date: '2016-09-23', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 17.5, Date: '2016-09-30', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 17.4, Date: '2016-10-07', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 14.9, Date: '2016-09-09', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 15.7, Date: '2016-09-12', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 16.6, Date: '2016-09-16', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 17.2, Date: '2016-09-23', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 17.4, Date: '2016-09-30', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 158150, Study: 'II', Weight: 17.7, Date: '2016-10-07', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 15.8, Date: '2016-09-09', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 16.5, Date: '2016-09-12', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 17, Date: '2016-09-16', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 17.2, Date: '2016-09-23', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 18.1, Date: '2016-09-30', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 408333, Study: 'II', Weight: 18.8, Date: '2016-10-07', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 14.5, Date: '2016-09-09', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 15.5, Date: '2016-09-12', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 17.4, Date: '2016-09-16', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 17.9, Date: '2016-09-23', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 19.3, Date: '2016-09-30', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 658516, Study: 'II', Weight: 19.3, Date: '2016-10-07', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 11.5, Date: '2016-09-09', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 12.5, Date: '2016-09-12', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 14.8, Date: '2016-09-16', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 16.8, Date: '2016-09-23', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 17.3, Date: '2016-09-30', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 406136, Study: 'II', Weight: 18.1, Date: '2016-10-07', Protocol: 'control', Drug: 'zeta', Isolator: 'B'},\n        {Subject: 405404, Study: 'II', Weight: 14.2, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'II', Weight: 15.8, Date: '2016-09-12', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'II', Weight: 15.8, Date: '2016-09-16', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'II', Weight: 16.8, Date: '2016-09-23', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'II', Weight: 17.9, Date: '2016-09-30', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'II', Weight: 17.6, Date: '2016-10-07', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 15.6, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 17, Date: '2016-09-12', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 17.5, Date: '2016-09-16', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 17.7, Date: '2016-09-23', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 18.6, Date: '2016-09-30', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 407601, Study: 'II', Weight: 19, Date: '2016-10-07', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 14.9, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 16.2, Date: '2016-09-12', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 15.8, Date: '2016-09-16', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 16.8, Date: '2016-09-23', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 17.1, Date: '2016-09-30', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907967, Study: 'II', Weight: 17, Date: '2016-10-07', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 12, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 13.9, Date: '2016-09-12', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 14.8, Date: '2016-09-16', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 17, Date: '2016-09-23', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 17.7, Date: '2016-09-30', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 408333, Study: 'II', Weight: 17.3, Date: '2016-10-07', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 14.8, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 16.3, Date: '2016-09-12', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 16.5, Date: '2016-09-16', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 17.2, Date: '2016-09-23', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 18.1, Date: '2016-09-30', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 656319, Study: 'II', Weight: 17.9, Date: '2016-10-07', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'II', Weight: 12.6, Date: '2016-09-09', Protocol: 'control', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'II', Weight: 13, Date: '2016-09-09', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 657784, Study: 'II', Weight: 15.3, Date: '2016-09-12', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 657784, Study: 'II', Weight: 16.3, Date: '2016-09-16', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 657784, Study: 'II', Weight: 18.4, Date: '2016-09-23', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 657784, Study: 'II', Weight: 18.9, Date: '2016-09-30', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 657784, Study: 'II', Weight: 19.6, Date: '2016-10-07', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 14.8, Date: '2016-09-09', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 15.7, Date: '2016-09-12', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 16, Date: '2016-09-16', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 17, Date: '2016-09-23', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 17.6, Date: '2016-09-30', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 655587, Study: 'II', Weight: 18.1, Date: '2016-10-07', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 15.6, Date: '2016-09-09', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 15.6, Date: '2016-09-12', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 16.2, Date: '2016-09-16', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 16.9, Date: '2016-09-23', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 17.5, Date: '2016-09-30', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 905770, Study: 'II', Weight: 17.3, Date: '2016-10-07', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 15.3, Date: '2016-09-09', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 15.2, Date: '2016-09-12', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 15.6, Date: '2016-09-16', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 16.9, Date: '2016-09-23', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 17.7, Date: '2016-09-30', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 155953, Study: 'II', Weight: 17.4, Date: '2016-10-07', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 12.2, Date: '2016-09-09', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 13.8, Date: '2016-09-12', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 14.9, Date: '2016-09-16', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 16.1, Date: '2016-09-23', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 16.9, Date: '2016-09-30', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 156685, Study: 'II', Weight: 16.8, Date: '2016-10-07', Protocol: 'P3', Drug: 'zeta', Isolator: 'D'},\n        {Subject: 907967, Study: 'II', Weight: 15.6, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'II', Weight: 16.4, Date: '2016-09-12', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'II', Weight: 15.8, Date: '2016-09-16', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'II', Weight: 17.1, Date: '2016-09-23', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'II', Weight: 17.4, Date: '2016-09-30', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'II', Weight: 17.2, Date: '2016-10-07', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 11.8, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 14.1, Date: '2016-09-12', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 14.6, Date: '2016-09-16', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 17.7, Date: '2016-09-23', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 17.7, Date: '2016-09-30', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 158150, Study: 'II', Weight: 18.4, Date: '2016-10-07', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 15.2, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 16.1, Date: '2016-09-12', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 16.9, Date: '2016-09-16', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 17.4, Date: '2016-09-23', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 18.4, Date: '2016-09-30', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 658516, Study: 'II', Weight: 18, Date: '2016-10-07', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 13.7, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 16.3, Date: '2016-09-12', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 15.4, Date: '2016-09-16', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 17.3, Date: '2016-09-23', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 18.6, Date: '2016-09-30', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'II', Weight: 18.4, Date: '2016-10-07', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 11.2, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 13.1, Date: '2016-09-12', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 14.1, Date: '2016-09-16', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 16.7, Date: '2016-09-23', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 17.2, Date: '2016-09-30', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'II', Weight: 17.6, Date: '2016-10-07', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406868, Study: 'II', Weight: 13.9, Date: '2016-09-09', Protocol: 'P3', Drug: 'eta', Isolator: 'E'},\n        {Subject: 157418, Study: 'III', Weight: 11.2, Date: '2016-11-01', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 10.8, Date: '2016-11-02', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 13.2, Date: '2016-11-04', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 14.2, Date: '2016-11-08', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 16.5, Date: '2016-11-15', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 17, Date: '2016-11-22', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'III', Weight: 17.4, Date: '2016-11-29', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 12.6, Date: '2016-11-01', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 12.6, Date: '2016-11-02', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 14.5, Date: '2016-11-04', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 14, Date: '2016-11-08', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 16.6, Date: '2016-11-15', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 17.7, Date: '2016-11-22', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 907967, Study: 'III', Weight: 17.8, Date: '2016-11-29', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 8.9, Date: '2016-11-01', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 8.8, Date: '2016-11-02', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 10.9, Date: '2016-11-04', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 12.2, Date: '2016-11-08', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 18.4, Date: '2016-11-15', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 19.5, Date: '2016-11-22', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 655587, Study: 'III', Weight: 19.6, Date: '2016-11-29', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 14.4, Date: '2016-11-01', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 14.3, Date: '2016-11-02', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 15, Date: '2016-11-04', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 13.5, Date: '2016-11-08', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 16.6, Date: '2016-11-15', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 17.3, Date: '2016-11-22', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 905770, Study: 'III', Weight: 17.2, Date: '2016-11-29', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 12.2, Date: '2016-11-01', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 11.4, Date: '2016-11-02', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 13.6, Date: '2016-11-04', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 16.4, Date: '2016-11-08', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 17.5, Date: '2016-11-15', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 17.6, Date: '2016-11-22', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'III', Weight: 17.5, Date: '2016-11-29', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 657052, Study: 'III', Weight: 10.5, Date: '2016-11-01', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 9.9, Date: '2016-11-02', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 12.5, Date: '2016-11-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 14.3, Date: '2016-11-08', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 17.4, Date: '2016-11-15', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 17.8, Date: '2016-11-22', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 657052, Study: 'III', Weight: 19.1, Date: '2016-11-29', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 11, Date: '2016-11-01', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 11.7, Date: '2016-11-02', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 14.4, Date: '2016-11-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 14.9, Date: '2016-11-08', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 16.8, Date: '2016-11-15', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 18, Date: '2016-11-22', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907235, Study: 'III', Weight: 18.4, Date: '2016-11-29', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 14.8, Date: '2016-11-01', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 13.3, Date: '2016-11-02', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 16.3, Date: '2016-11-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 17.1, Date: '2016-11-08', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 17.4, Date: '2016-11-15', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 18.6, Date: '2016-11-22', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 155953, Study: 'III', Weight: 18.5, Date: '2016-11-29', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 12.6, Date: '2016-11-01', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 12.9, Date: '2016-11-02', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 15.4, Date: '2016-11-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 15.7, Date: '2016-11-08', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 19.2, Date: '2016-11-15', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 20, Date: '2016-11-22', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 656319, Study: 'III', Weight: 20.7, Date: '2016-11-29', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 11, Date: '2016-11-01', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 11.9, Date: '2016-11-02', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 13.7, Date: '2016-11-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 15.6, Date: '2016-11-08', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 18.1, Date: '2016-11-15', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 18.1, Date: '2016-11-22', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 906502, Study: 'III', Weight: 18.9, Date: '2016-11-29', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 405404, Study: 'III', Weight: 11.5, Date: '2016-11-01', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 12.8, Date: '2016-11-02', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 14, Date: '2016-11-04', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 15.6, Date: '2016-11-08', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 17.4, Date: '2016-11-15', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 17.7, Date: '2016-11-22', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 405404, Study: 'III', Weight: 18.5, Date: '2016-11-29', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 13.2, Date: '2016-11-01', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 12.8, Date: '2016-11-02', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 15.5, Date: '2016-11-04', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 17.2, Date: '2016-11-08', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 19.5, Date: '2016-11-15', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 18.9, Date: '2016-11-22', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 408333, Study: 'III', Weight: 19.2, Date: '2016-11-29', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 11.9, Date: '2016-11-01', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 12.7, Date: '2016-11-02', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 13.7, Date: '2016-11-04', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 15.2, Date: '2016-11-08', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 18.7, Date: '2016-11-15', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 18, Date: '2016-11-22', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 658516, Study: 'III', Weight: 18.8, Date: '2016-11-29', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 13.1, Date: '2016-11-01', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 13.7, Date: '2016-11-02', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 14.7, Date: '2016-11-04', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 15.8, Date: '2016-11-08', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 16.6, Date: '2016-11-15', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 17.1, Date: '2016-11-22', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 655587, Study: 'III', Weight: 17, Date: '2016-11-29', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 10.7, Date: '2016-11-01', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 11.9, Date: '2016-11-02', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 13, Date: '2016-11-04', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 14.1, Date: '2016-11-08', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 16.5, Date: '2016-11-15', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 17, Date: '2016-11-22', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 156685, Study: 'III', Weight: 17.5, Date: '2016-11-29', Protocol: 'control', Drug: 'gamma', Isolator: 'C'},\n        {Subject: 657052, Study: 'III', Weight: 12.5, Date: '2016-11-01', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 12.7, Date: '2016-11-02', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 14.7, Date: '2016-11-04', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 15.7, Date: '2016-11-08', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 17.5, Date: '2016-11-15', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 17, Date: '2016-11-22', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 657052, Study: 'III', Weight: 19, Date: '2016-11-29', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 11.9, Date: '2016-11-01', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 11.8, Date: '2016-11-02', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 13.5, Date: '2016-11-04', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 15, Date: '2016-11-08', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 16.6, Date: '2016-11-15', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 16.6, Date: '2016-11-22', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 407601, Study: 'III', Weight: 17.4, Date: '2016-11-29', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 14, Date: '2016-11-01', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 14, Date: '2016-11-02', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 15.4, Date: '2016-11-04', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 16, Date: '2016-11-08', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 16.8, Date: '2016-11-15', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 17.1, Date: '2016-11-22', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 158150, Study: 'III', Weight: 17.2, Date: '2016-11-29', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 12.6, Date: '2016-11-01', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 12.4, Date: '2016-11-02', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 15, Date: '2016-11-04', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 16.5, Date: '2016-11-08', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 16.8, Date: '2016-11-15', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 17.5, Date: '2016-11-22', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 155953, Study: 'III', Weight: 17.7, Date: '2016-11-29', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 10.2, Date: '2016-11-01', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 9.8, Date: '2016-11-02', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 12.7, Date: '2016-11-04', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 13.9, Date: '2016-11-08', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 16.5, Date: '2016-11-15', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 16.9, Date: '2016-11-22', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 656319, Study: 'III', Weight: 17.1, Date: '2016-11-29', Protocol: 'control', Drug: 'theta', Isolator: 'D'},\n        {Subject: 157418, Study: 'IV', Weight: 9, Date: '2016-12-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 10.1, Date: '2016-12-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 12, Date: '2016-12-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 14, Date: '2016-12-19', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 15.6, Date: '2016-12-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 16.6, Date: '2016-12-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 157418, Study: 'IV', Weight: 16.1, Date: '2017-01-06', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 11, Date: '2016-12-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 12.4, Date: '2016-12-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 12.7, Date: '2016-12-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 13.2, Date: '2016-12-19', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 16.4, Date: '2016-12-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 16.6, Date: '2016-12-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 407601, Study: 'IV', Weight: 16.8, Date: '2017-01-06', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 13, Date: '2016-12-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 14.7, Date: '2016-12-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 16.6, Date: '2016-12-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 18.4, Date: '2016-12-19', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 19.2, Date: '2016-12-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 19, Date: '2016-12-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 408333, Study: 'IV', Weight: 19.4, Date: '2017-01-06', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 9.5, Date: '2016-12-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 11.9, Date: '2016-12-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 13.8, Date: '2016-12-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 15.6, Date: '2016-12-19', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 16.7, Date: '2016-12-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 17.7, Date: '2016-12-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 155953, Study: 'IV', Weight: 17.2, Date: '2017-01-06', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 9.2, Date: '2016-12-09', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 11.1, Date: '2016-12-12', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 12.8, Date: '2016-12-16', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 14.7, Date: '2016-12-19', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 16, Date: '2016-12-23', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 16.6, Date: '2016-12-30', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 406868, Study: 'IV', Weight: 16.5, Date: '2017-01-06', Protocol: 'control', Drug: 'iota', Isolator: 'A'},\n        {Subject: 405404, Study: 'IV', Weight: 9.8, Date: '2016-12-09', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 11.9, Date: '2016-12-12', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 15.1, Date: '2016-12-16', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 17.4, Date: '2016-12-19', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 17.9, Date: '2016-12-23', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 18.6, Date: '2016-12-30', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'IV', Weight: 18.6, Date: '2017-01-06', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 8.4, Date: '2016-12-09', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 10.5, Date: '2016-12-12', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 13, Date: '2016-12-16', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 15, Date: '2016-12-19', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 16.9, Date: '2016-12-23', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 16.6, Date: '2016-12-30', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 905770, Study: 'IV', Weight: 16.9, Date: '2017-01-06', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 406136, Study: 'IV', Weight: 12.1, Date: '2016-12-09', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 8.9, Date: '2016-12-09', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 10.6, Date: '2016-12-12', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 13.5, Date: '2016-12-16', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 14.9, Date: '2016-12-19', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 16.6, Date: '2016-12-23', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 17.1, Date: '2016-12-30', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'IV', Weight: 17.2, Date: '2017-01-06', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 9.7, Date: '2016-12-09', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 11, Date: '2016-12-12', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 14.3, Date: '2016-12-16', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 15.9, Date: '2016-12-19', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 17.1, Date: '2016-12-23', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 17.4, Date: '2016-12-30', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 906502, Study: 'IV', Weight: 16.9, Date: '2017-01-06', Protocol: 'control', Drug: 'eta', Isolator: 'B'},\n        {Subject: 657784, Study: 'IV', Weight: 8.6, Date: '2016-12-09', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 11.1, Date: '2016-12-12', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 13.4, Date: '2016-12-16', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 14.8, Date: '2016-12-19', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 16.2, Date: '2016-12-23', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 17.4, Date: '2016-12-30', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'IV', Weight: 17.4, Date: '2017-01-06', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 7.8, Date: '2016-12-09', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 9.8, Date: '2016-12-12', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 11.8, Date: '2016-12-16', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 14.1, Date: '2016-12-19', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 16.6, Date: '2016-12-23', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 16.9, Date: '2016-12-30', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 158150, Study: 'IV', Weight: 17.4, Date: '2017-01-06', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 9.8, Date: '2016-12-09', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 12.2, Date: '2016-12-12', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 14, Date: '2016-12-16', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 16.2, Date: '2016-12-19', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 17.8, Date: '2016-12-23', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 18.5, Date: '2016-12-30', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 658516, Study: 'IV', Weight: 18.5, Date: '2017-01-06', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 12.6, Date: '2016-12-09', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 14.2, Date: '2016-12-12', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 15.5, Date: '2016-12-16', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 16, Date: '2016-12-19', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 16.3, Date: '2016-12-23', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 17.8, Date: '2016-12-30', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'IV', Weight: 17.9, Date: '2017-01-06', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 9.7, Date: '2016-12-09', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 11.3, Date: '2016-12-12', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 11.8, Date: '2016-12-16', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 14, Date: '2016-12-19', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 15.8, Date: '2016-12-23', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 18.3, Date: '2016-12-30', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'IV', Weight: 17.5, Date: '2017-01-06', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 907235, Study: 'IV', Weight: 10.5, Date: '2016-12-09', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 11.1, Date: '2016-12-12', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 13.7, Date: '2016-12-16', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 15.9, Date: '2016-12-19', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 17.1, Date: '2016-12-23', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 17.2, Date: '2016-12-30', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 907235, Study: 'IV', Weight: 17.2, Date: '2017-01-06', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 7.2, Date: '2016-12-09', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 8.4, Date: '2016-12-12', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 9.9, Date: '2016-12-16', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 12, Date: '2016-12-19', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 14.3, Date: '2016-12-23', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 15.4, Date: '2016-12-30', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 655587, Study: 'IV', Weight: 14.9, Date: '2017-01-06', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 9.2, Date: '2016-12-09', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 11.1, Date: '2016-12-12', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 13.1, Date: '2016-12-16', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 15.8, Date: '2016-12-19', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 17.7, Date: '2016-12-23', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 18.4, Date: '2016-12-30', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 155953, Study: 'IV', Weight: 18.8, Date: '2017-01-06', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 14.7, Date: '2016-12-09', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 15.1, Date: '2016-12-12', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 16.1, Date: '2016-12-16', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 17.6, Date: '2016-12-19', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 17.6, Date: '2016-12-23', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 18.6, Date: '2016-12-30', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'IV', Weight: 18.2, Date: '2017-01-06', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 10.5, Date: '2016-12-09', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 11.6, Date: '2016-12-12', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 14.1, Date: '2016-12-16', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 16, Date: '2016-12-19', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 17.7, Date: '2016-12-23', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 17.4, Date: '2016-12-30', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 156685, Study: 'IV', Weight: 18, Date: '2017-01-06', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 405404, Study: 'IV', Weight: 15.1, Date: '2016-12-09', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 16.7, Date: '2016-12-12', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 18, Date: '2016-12-16', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 19.2, Date: '2016-12-19', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 18.8, Date: '2016-12-23', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 19.8, Date: '2016-12-30', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'IV', Weight: 19.4, Date: '2017-01-06', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 10.3, Date: '2016-12-09', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 11.4, Date: '2016-12-12', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 13, Date: '2016-12-16', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 14.9, Date: '2016-12-19', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 16.9, Date: '2016-12-23', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 16.5, Date: '2016-12-30', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'IV', Weight: 16.5, Date: '2017-01-06', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 7, Date: '2016-12-09', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 9.1, Date: '2016-12-12', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 10.5, Date: '2016-12-16', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 13, Date: '2016-12-19', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 15.1, Date: '2016-12-23', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 16, Date: '2016-12-30', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907967, Study: 'IV', Weight: 15.8, Date: '2017-01-06', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 9.1, Date: '2016-12-09', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 11.2, Date: '2016-12-12', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 11.7, Date: '2016-12-16', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 14, Date: '2016-12-19', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 16.2, Date: '2016-12-23', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 16.8, Date: '2016-12-30', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'IV', Weight: 16.3, Date: '2017-01-06', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 10.4, Date: '2016-12-09', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 12.7, Date: '2016-12-12', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 14, Date: '2016-12-16', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 15.4, Date: '2016-12-19', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 16.7, Date: '2016-12-23', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 17.4, Date: '2016-12-30', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'IV', Weight: 16.9, Date: '2017-01-06', Protocol: 'P4', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 12.7, Date: '2017-03-14', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 14.1, Date: '2017-03-17', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 15.7, Date: '2017-03-21', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 16.9, Date: '2017-03-24', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 17, Date: '2017-03-28', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 17.7, Date: '2017-04-04', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 16.9, Date: '2017-04-11', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'V', Weight: 16.7, Date: '2017-04-18', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 9.3, Date: '2017-03-14', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 10.8, Date: '2017-03-17', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 12.9, Date: '2017-03-21', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 14.4, Date: '2017-03-24', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 15, Date: '2017-03-28', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 16, Date: '2017-04-04', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 15.9, Date: '2017-04-11', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'V', Weight: 16, Date: '2017-04-18', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 13.5, Date: '2017-03-14', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 14.7, Date: '2017-03-17', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 16.5, Date: '2017-03-21', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 16.8, Date: '2017-03-24', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 17.1, Date: '2017-03-28', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 18.4, Date: '2017-04-04', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 18.6, Date: '2017-04-11', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'V', Weight: 18.2, Date: '2017-04-18', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 13.5, Date: '2017-03-14', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 14.3, Date: '2017-03-17', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 14.1, Date: '2017-03-21', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 16.9, Date: '2017-03-24', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 15.9, Date: '2017-03-28', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 17.7, Date: '2017-04-04', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 17.2, Date: '2017-04-11', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 906502, Study: 'V', Weight: 16.8, Date: '2017-04-18', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 9.6, Date: '2017-03-14', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 11.5, Date: '2017-03-17', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 14.3, Date: '2017-03-21', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 15.5, Date: '2017-03-24', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 16.7, Date: '2017-03-28', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 17.4, Date: '2017-04-04', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 16.7, Date: '2017-04-11', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 156685, Study: 'V', Weight: 16.9, Date: '2017-04-18', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'V', Weight: 12.7, Date: '2017-03-14', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 14.4, Date: '2017-03-17', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 15.2, Date: '2017-03-21', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 15.8, Date: '2017-03-24', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 17.5, Date: '2017-03-28', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 18.1, Date: '2017-04-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 18.1, Date: '2017-04-11', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 18.8, Date: '2017-04-18', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 12, Date: '2017-03-14', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 13, Date: '2017-03-17', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 14.2, Date: '2017-03-21', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 14.8, Date: '2017-03-24', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 15.8, Date: '2017-03-28', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 16.8, Date: '2017-04-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 17.1, Date: '2017-04-11', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 407601, Study: 'V', Weight: 17.1, Date: '2017-04-18', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 13.4, Date: '2017-03-14', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 15.4, Date: '2017-03-17', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 15.7, Date: '2017-03-21', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 15.9, Date: '2017-03-24', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 16.8, Date: '2017-03-28', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 18.4, Date: '2017-04-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 18, Date: '2017-04-11', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 907967, Study: 'V', Weight: 18.4, Date: '2017-04-18', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 8.5, Date: '2017-03-14', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 11.2, Date: '2017-03-17', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 13, Date: '2017-03-21', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 14.5, Date: '2017-03-24', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 17.3, Date: '2017-03-28', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 17.6, Date: '2017-04-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 17.5, Date: '2017-04-11', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 655587, Study: 'V', Weight: 16.5, Date: '2017-04-18', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 9.5, Date: '2017-03-14', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 11.4, Date: '2017-03-17', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 13.1, Date: '2017-03-21', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 14, Date: '2017-03-24', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 17.6, Date: '2017-03-28', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 18.7, Date: '2017-04-04', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 18.2, Date: '2017-04-11', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 406868, Study: 'V', Weight: 18.4, Date: '2017-04-18', Protocol: 'control', Drug: 'alpha', Isolator: 'B'},\n        {Subject: 157418, Study: 'V', Weight: 9.1, Date: '2017-03-14', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 11.6, Date: '2017-03-17', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 13.4, Date: '2017-03-21', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 15.9, Date: '2017-03-24', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 17.3, Date: '2017-03-28', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 18.1, Date: '2017-04-04', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 18.9, Date: '2017-04-11', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 157418, Study: 'V', Weight: 18.6, Date: '2017-04-18', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 13.4, Date: '2017-03-14', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 14.9, Date: '2017-03-17', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 15.7, Date: '2017-03-21', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 16.7, Date: '2017-03-24', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 16.6, Date: '2017-03-28', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 17.3, Date: '2017-04-04', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 18.3, Date: '2017-04-11', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 905770, Study: 'V', Weight: 18.4, Date: '2017-04-18', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 9.7, Date: '2017-03-14', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 12, Date: '2017-03-17', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 13.7, Date: '2017-03-21', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 16.2, Date: '2017-03-24', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 17.9, Date: '2017-03-28', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 18.7, Date: '2017-04-04', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 18.5, Date: '2017-04-11', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 155953, Study: 'V', Weight: 18.6, Date: '2017-04-18', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 11.3, Date: '2017-03-14', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 12, Date: '2017-03-17', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 14.3, Date: '2017-03-21', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 16, Date: '2017-03-24', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 17.5, Date: '2017-03-28', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 17.5, Date: '2017-04-04', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 17.7, Date: '2017-04-11', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 406136, Study: 'V', Weight: 18.3, Date: '2017-04-18', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 14, Date: '2017-03-14', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 15.7, Date: '2017-03-17', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 16.7, Date: '2017-03-21', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 16.7, Date: '2017-03-24', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 17, Date: '2017-03-28', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 18.2, Date: '2017-04-04', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 18.2, Date: '2017-04-11', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'V', Weight: 18.3, Date: '2017-04-18', Protocol: 'P3', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657052, Study: 'V', Weight: 9.3, Date: '2017-03-14', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 11.4, Date: '2017-03-17', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 13.7, Date: '2017-03-21', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 15.6, Date: '2017-03-24', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 16.6, Date: '2017-03-28', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 17.5, Date: '2017-04-04', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 17.6, Date: '2017-04-11', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 657052, Study: 'V', Weight: 18.1, Date: '2017-04-18', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 14.1, Date: '2017-03-14', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 16.5, Date: '2017-03-17', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 16.2, Date: '2017-03-21', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 17, Date: '2017-03-24', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 17.9, Date: '2017-03-28', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 18.5, Date: '2017-04-04', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 18.3, Date: '2017-04-11', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 158150, Study: 'V', Weight: 18.9, Date: '2017-04-18', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 12.8, Date: '2017-03-14', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 14.6, Date: '2017-03-17', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 14.9, Date: '2017-03-21', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 16, Date: '2017-03-24', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 17.9, Date: '2017-03-28', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 18.7, Date: '2017-04-04', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 18.5, Date: '2017-04-11', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 408333, Study: 'V', Weight: 19.4, Date: '2017-04-18', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 10.2, Date: '2017-03-14', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 11.8, Date: '2017-03-17', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 14.6, Date: '2017-03-21', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 16.2, Date: '2017-03-24', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 17.4, Date: '2017-03-28', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 17.7, Date: '2017-04-04', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 17.2, Date: '2017-04-11', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 656319, Study: 'V', Weight: 18, Date: '2017-04-18', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 14.1, Date: '2017-03-14', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 15.8, Date: '2017-03-17', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 16.6, Date: '2017-03-21', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 16.9, Date: '2017-03-24', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 17.7, Date: '2017-03-28', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 17.9, Date: '2017-04-04', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 17.8, Date: '2017-04-11', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 406868, Study: 'V', Weight: 18.7, Date: '2017-04-18', Protocol: 'P1', Drug: 'eta', Isolator: 'D'},\n        {Subject: 405404, Study: 'V', Weight: 9.9, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 12.7, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 15.7, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 17.9, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 18.9, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 19.8, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 19.6, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 405404, Study: 'V', Weight: 19.9, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 12.4, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 14.6, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 15.4, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 16.5, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 16.6, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 17.9, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 17.7, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657052, Study: 'V', Weight: 18.5, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 14.2, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 15.7, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 16.3, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 17.5, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 17.9, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 18, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 18.7, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'V', Weight: 18.8, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 6.9, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 8.5, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 11.1, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 13.2, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 16.5, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 16.9, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 17.1, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 407601, Study: 'V', Weight: 17.2, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 7.4, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 9.4, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 11.2, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 14, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 16, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 17.2, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 16.8, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 657784, Study: 'V', Weight: 17.5, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 14.4, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 16.1, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 16, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 17.6, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 16.7, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 17.2, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 17, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 655587, Study: 'V', Weight: 17, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 12.5, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 13.9, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 15.5, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 17.2, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 18, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 18.9, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 18.8, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 905770, Study: 'V', Weight: 19.3, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 13.3, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 15.3, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 15.6, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 17.2, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 16.9, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 18.1, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 18.5, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 406136, Study: 'V', Weight: 19.5, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 14.5, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 15.9, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 15.6, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 16.4, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 16.6, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 16.9, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 17.3, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 656319, Study: 'V', Weight: 16.8, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 10.5, Date: '2017-03-14', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 12, Date: '2017-03-17', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 14.2, Date: '2017-03-21', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 15.9, Date: '2017-03-24', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 17.2, Date: '2017-03-28', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 17.7, Date: '2017-04-04', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 18, Date: '2017-04-11', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 906502, Study: 'V', Weight: 18.2, Date: '2017-04-18', Protocol: 'P2', Drug: 'eta', Isolator: 'E'},\n        {Subject: 907235, Study: 'VI', Weight: 9.9, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'VI', Weight: 12, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'VI', Weight: 13.1, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'VI', Weight: 15.2, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 907235, Study: 'VI', Weight: 17.1, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'VI', Weight: 11, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'VI', Weight: 14.1, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'VI', Weight: 15.8, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'VI', Weight: 17.4, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 157418, Study: 'VI', Weight: 18.2, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 407601, Study: 'VI', Weight: 11.3, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 407601, Study: 'VI', Weight: 13.9, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 407601, Study: 'VI', Weight: 15.3, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 407601, Study: 'VI', Weight: 16.4, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 407601, Study: 'VI', Weight: 17.4, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 408333, Study: 'VI', Weight: 8.8, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 408333, Study: 'VI', Weight: 10.2, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 408333, Study: 'VI', Weight: 12.1, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 408333, Study: 'VI', Weight: 14.3, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 408333, Study: 'VI', Weight: 17.3, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 905770, Study: 'VI', Weight: 10.3, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 905770, Study: 'VI', Weight: 11.8, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 905770, Study: 'VI', Weight: 12.4, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 905770, Study: 'VI', Weight: 15.1, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 905770, Study: 'VI', Weight: 17.5, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 7.3, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 9.2, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 10.4, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 13.1, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 15.1, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 11, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 12.9, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 14.1, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 16.4, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 155953, Study: 'VI', Weight: 18.2, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 11.2, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 13, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 14.8, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 15.7, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 16.5, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 10.7, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 12.8, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 14.1, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 16.9, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406136, Study: 'VI', Weight: 17.6, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406868, Study: 'VI', Weight: 7.9, Date: '2017-05-26', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406868, Study: 'VI', Weight: 10.3, Date: '2017-05-29', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406868, Study: 'VI', Weight: 12.5, Date: '2017-06-02', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406868, Study: 'VI', Weight: 14.6, Date: '2017-06-05', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 406868, Study: 'VI', Weight: 17.2, Date: '2017-06-09', Protocol: 'control', Drug: 'eta', Isolator: 'A'},\n        {Subject: 405404, Study: 'VI', Weight: 9.7, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'VI', Weight: 11.9, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'VI', Weight: 13, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'VI', Weight: 14.1, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'VI', Weight: 16.8, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 907967, Study: 'VI', Weight: 8.8, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 907967, Study: 'VI', Weight: 11.1, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 907967, Study: 'VI', Weight: 12, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 907967, Study: 'VI', Weight: 14.6, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 907967, Study: 'VI', Weight: 17, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 158150, Study: 'VI', Weight: 11.5, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 158150, Study: 'VI', Weight: 13.6, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 158150, Study: 'VI', Weight: 15.3, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 158150, Study: 'VI', Weight: 16.1, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 158150, Study: 'VI', Weight: 17.5, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 658516, Study: 'VI', Weight: 8.8, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 658516, Study: 'VI', Weight: 11, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 658516, Study: 'VI', Weight: 12.7, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 658516, Study: 'VI', Weight: 14.8, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 658516, Study: 'VI', Weight: 16.2, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'VI', Weight: 8.4, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'VI', Weight: 9.9, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'VI', Weight: 10.8, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'VI', Weight: 13.7, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 656319, Study: 'VI', Weight: 16.8, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'B'},\n        {Subject: 405404, Study: 'VI', Weight: 10.6, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'VI', Weight: 12.6, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'VI', Weight: 14.7, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'VI', Weight: 16.4, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 405404, Study: 'VI', Weight: 18.5, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'VI', Weight: 8.9, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'VI', Weight: 10.8, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'VI', Weight: 12.2, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'VI', Weight: 14.9, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657784, Study: 'VI', Weight: 17.7, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'VI', Weight: 10.1, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'VI', Weight: 12.4, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'VI', Weight: 14.7, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'VI', Weight: 16.2, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 655587, Study: 'VI', Weight: 18, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 906502, Study: 'VI', Weight: 11.2, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 906502, Study: 'VI', Weight: 13.7, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 906502, Study: 'VI', Weight: 15.7, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 906502, Study: 'VI', Weight: 16.2, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 906502, Study: 'VI', Weight: 17.7, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'VI', Weight: 7.7, Date: '2017-05-26', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'VI', Weight: 9.6, Date: '2017-05-29', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'VI', Weight: 11.6, Date: '2017-06-02', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'VI', Weight: 13.7, Date: '2017-06-05', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 156685, Study: 'VI', Weight: 16.8, Date: '2017-06-09', Protocol: 'P1', Drug: 'eta', Isolator: 'C'},\n        {Subject: 657052, Study: 'VI', Weight: 12, Date: '2017-05-26', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 657052, Study: 'VI', Weight: 12.6, Date: '2017-05-29', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 657052, Study: 'VI', Weight: 12.9, Date: '2017-06-02', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 657052, Study: 'VI', Weight: 16.1, Date: '2017-06-05', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 657052, Study: 'VI', Weight: 17.9, Date: '2017-06-09', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 655587, Study: 'VI', Weight: 9.5, Date: '2017-05-26', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 655587, Study: 'VI', Weight: 10.3, Date: '2017-05-29', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 655587, Study: 'VI', Weight: 10.6, Date: '2017-06-02', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 655587, Study: 'VI', Weight: 12.2, Date: '2017-06-05', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 655587, Study: 'VI', Weight: 14.5, Date: '2017-06-09', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 905770, Study: 'VI', Weight: 9.5, Date: '2017-05-26', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 905770, Study: 'VI', Weight: 10.5, Date: '2017-05-29', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 905770, Study: 'VI', Weight: 10, Date: '2017-06-02', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 905770, Study: 'VI', Weight: 11.2, Date: '2017-06-05', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 905770, Study: 'VI', Weight: 13.9, Date: '2017-06-09', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 906502, Study: 'VI', Weight: 9.4, Date: '2017-05-26', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 906502, Study: 'VI', Weight: 9.9, Date: '2017-05-29', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 906502, Study: 'VI', Weight: 9.9, Date: '2017-06-02', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 906502, Study: 'VI', Weight: 10.7, Date: '2017-06-05', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 906502, Study: 'VI', Weight: 14.6, Date: '2017-06-09', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 156685, Study: 'VI', Weight: 8.5, Date: '2017-05-26', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 156685, Study: 'VI', Weight: 9.1, Date: '2017-05-29', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 156685, Study: 'VI', Weight: 9.3, Date: '2017-06-02', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 156685, Study: 'VI', Weight: 10.7, Date: '2017-06-05', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n        {Subject: 156685, Study: 'VI', Weight: 13.9, Date: '2017-06-09', Protocol: 'control', Drug: 'placebo', Isolator: 'D'},\n    ];\n\n\n</script>\n"
  },
  {
    "path": "examples/documentation.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\">\n    <title>Nvd3 - reusable charts for D3.js</title>\n    <link rel=\"stylesheet\" href=\"stylesheets/styles.css\">\n    <link rel=\"stylesheet\" href=\"stylesheets/pygment_trac.css\">\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <link rel=\"stylesheet\" href=\"https://cdn.rawgit.com/isagalaev/highlight.js/8.4/src/styles/tomorrow.css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/highlight.min.js\"></script>\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.4/languages/javascript.min.js\"></script>\n\n    <script>\n\n        function expandall(name) {\n            $('#ul_' + name).show().find(\"li\").click();\n        }\n\n        function expandchart(name) {\n            $('#ul_' + name).toggle();\n        }\n\n        function parse_options(container, obj) {\n            var t = obj.name;\n            var extra = obj.note;\n\n            var op = $('<li>');\n            if (extra !== undefined) {\n                t += ' <span class=\"inherited\">' + extra + '</span>';\n            }\n            op.addClass('option');\n            op.prop('name', obj.name);\n            op.html(t);\n            container.append(op);\n        }\n\n        function getProps(obj, key) {\n            var props = [];\n            if (obj.hasOwnProperty(key)) {\n                var _obj = obj[key];\n                if (typeof _obj === 'object') {\n                    props.push.apply(props, Object.keys(_obj));\n                }\n            }\n            return props;\n        }\n\n        $('body').ready(function () {\n            var charts = [\n                'pieChart',\n                'lineChart',\n                'parallelCoordinatesChart',\n                'scatterChart',\n                'stackedAreaChart',\n                'sparklinePlus',\n                'multiChart',\n                'multiBarHorizontalChart',\n                'multiBarChart',\n                'lineWithFocusChart',\n                'linePlusBarChart',\n                'historicalBarChart',\n                'discreteBarChart',\n                'cumulativeLineChart',\n                'bulletChart',\n                'ohlcBarChart',\n                'boxPlotChart',\n                'sunburstChart',\n                'distroPlotChart',\n                'candlestickBarChart'\n            ].sort();\n            var parts = [\n                'line',\n                'axis',\n                'bullet',\n                'scatter',\n                'ohlcBar',\n                'pie',\n                'historicalBar',\n                'multiBarHorizontal',\n                'multiBar',\n                'legend',\n                'tooltip',\n                'boxPlot',\n                'candlestickBar',\n                'sparkline',\n                'discreteBar',\n                'sunburst',\n                'parallelCoordinates'\n            ].sort();\n            var c = $('#optionlist');\n            var jump = $('#optionjump');\n            charts = charts.concat(parts);\n\n            // loop through chart options, build the list of options for each\n            for (var i in charts) {\n                var name = charts[i];\n                if (nv.models[name]) {\n                    var chart = nv.models[name]();\n\n                    // add the chart object name, and jump link to it\n                    c.append(\"<h3 class='option' id='\" + name + \"'>\" + name + \" <span class='expand'>[ <a href=\\\"javascript:expandchart('\" + name + \"')\\\">toggle</a> | <a href=\\\"javascript:expandall('\" + name + \"')\\\">toggle options</a> | <a href='#'>Top</a> ]</span></h3>\");\n                    jump.append(\"<div><a href='#\" + name + \"'>\" + name + \"</a></div>\");\n\n                    // build list of sub-components for this chart object\n                    var props = Object.getOwnPropertyNames(chart);\n                    var propdom = $('<div></div>').addClass('propdom');\n                    var proplist = {};\n                    var dispatchList = [];\n\n                    for (var p in props) {\n                        try {\n                            var prop = chart[props[p]];\n                            if ((prop instanceof Object) && !(prop instanceof Array) && prop._options) {\n                                proplist[props[p]] = props[p];\n                            }\n                        } catch(e) {}\n                    }\n\n                    // only add sub-component list if some exist.\n                    if (Object.keys(proplist).length > 0) {\n                        propdom.append($('<span class=\"label\">Components: </span>'));\n                        var pstrings = [];\n                        for (var p in proplist) {\n                            pstrings.push('<span class=\"prop\">' + p + '</span>');\n                        }\n                        propdom.append($(pstrings.join(', ')));\n                    }\n\n                    // add event dispatchers by the chart;\n                    dispatchList = getProps(chart, 'dispatch');\n                    if (dispatchList.length) {\n                        propdom.append($('<br/>'));\n                        propdom.append($('<span class=\"label\">Events: </span>'));\n                        var dispatchString = dispatchList.map(function(dispatcherName) {\n                            return '<span class=\"event\">' + dispatcherName + '</span>';\n                        }).join(' ');\n                        propdom.append(dispatchString);\n                    }\n\n                    if (propdom.children().length) {\n                        propdom.addClass('populated');\n                        c.append(propdom);\n                    }\n\n                    // build the list of options for this chart object\n                    var ul = $('<ul id=\"ul_' + name +'\">');\n\n                    // collect all the options\n                    var alloptions = {};\n                    if (chart._options) {\n                        var ops = Object.getOwnPropertyNames(chart._options);\n                        for (var t in ops) {\n                            alloptions[ops[t]] = {name: ops[t]}\n                        }\n                    }\n                    if (chart._inherited) {\n                        for (var j2 in chart._inherited) {\n                            var op = chart._inherited[j2];\n                            if (chart._options[op] === undefined) {\n                                alloptions[op] = {name: op, note: '(inherited)'};\n                            }\n                        }\n                    }\n                    if (chart._d3options) {\n                        for (var j3 in chart._d3options) {\n                            var op2 = chart._d3options[j3];\n                            alloptions[op2] = {name: op2, note: '(inherited from D3)'}\n                        }\n                    }\n\n                    // now print the all out in alphabetical order\n                    var alpha = Object.keys(alloptions).sort();\n                    for (var j4 in alpha) {\n                        // ignore internal options (start with an underscore)\n                        if (alpha[j4].substring(0, 1) !== '_') {\n                            parse_options(ul, alloptions[alpha[j4]]);\n                        }\n                    }\n\n                    // append the list of options to the dom\n                    c.append(ul);\n                } else {\n                    console.log('Chart missing: ', name);\n                }\n            }\n\n            // set each option so if it's clicked, it will build and display the option information\n            $('.option').click(function(evt) {\n                var a = $(evt.target);\n                var name = a.prop('name');\n\n                // trigger only for li, not child dom\n                if (!a.is('li')) return;\n\n                if (a.find('.option-info').length) {\n                    a.removeClass('option-selected');\n                    a.find('.option-info').remove();\n                } else {\n                    a.addClass('option-selected');\n                    var info = '';\n                    if (option_info[name]) {\n\n\n\n                        var desc = option_info[name]['desc'];\n                        var def;\n                        // if defaultValueGetter exists, it is a function to pull the actual default value from an instance of the chart\n                        if (option_info[name]['defaultValueGetter']) {\n                            var chartName = a.parent().attr('id').substring(3); // first 3 chars are a 'ul_' appended to the chart name\n                            def = JSON.stringify(option_info[name]['defaultValueGetter'](nv.models[chartName]()), null, 1);\n                        } else {\n                            def = option_info[name]['default'];\n                        }\n                        var ex = option_info[name]['examples'];\n                        var refs = option_info[name]['refs'] || [];\n                        var example_obj = option_info[name]['example_object'] || 'chart';\n                        var examples = [];\n                        var inputs = [];\n\n                        // process examples\n                        for (var i in ex) {\n                            var e = ex[i];\n                            var etype = e instanceof Array ? 'array' : typeof e;\n                            if (inputs.indexOf(etype) < 0) {\n                                inputs.push(etype);\n                            }\n                            if (etype == 'object' || etype == 'array' || etype == 'string')\n                                e = JSON.stringify(e);\n                            if (etype == 'function') {\n                                // if function, remove the first 20 spaces in each line\n                                // due to indention in the info object\n                                e = e.toString().replace(/(\\r\\n|\\n|\\r)\\s{16}/gm,'\\n');\n                            }\n                            examples.push(example_obj + '.' + name + '(' + $('<div/>').text(e).html() + ')');\n                        }\n\n                        // build html of other option info\n                        if (desc) {\n                            info += \"<div class='part'>Description:</div>\";\n                            info += \"<div>\" + desc + \"</div>\";\n                            for (var r in refs) {\n                                info += '<div><a target=\"nvref\" href=\"' + refs[r] + '\">' + refs[r] + '</a></div>';\n                            }\n                        }\n                        if (inputs.length) {\n                            info += \"<div class='part'>Input Type(s):</div>\";\n                            info += \"<div>\" + inputs.join(' or ') + \"</div>\";\n                        }\n                        if (def !== undefined) {\n                            info += \"<div class='part'>Default:</div>\";\n                            info += \"<div>\" + def + \"</div>\";\n                        }\n                        if (examples.length) {\n                            info += \"<div class='part'>Example(s):</div>\";\n                            info += \"<div class='example'><code class='javascript'>\" + examples.join(\"</code><code class='javascript'>\") + \"</code></div>\";\n                        }\n                    } else {\n                        info = 'No info for this option yet...';\n                    }\n                    a.append('<div class=\"option-info\">' + info + '</div>');\n                    a.find('code').each(function(i, block) {\n                        hljs.highlightBlock(block);\n                    });\n                }\n            });\n        });\n    </script>\n    <!--[if lt IE 9]>\n    <script src=\"//html5shiv.googlecode.com/svn/trunk/html5.js\"></script>\n    <![endif]-->\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n\n</head>\n<body>\n\n<header>\n    <h1>Nvd3</h1>\n    <p>A reusable chart library for d3.js</p>\n</header>\n\n<div id=\"banner\">\n    <div>\n        <span id=\"logo\"></span>\n\n        <a href=\"https://github.com/nvd3-community/nvd3\" target=\"github\" class=\"button fork\"><strong>GitHub</strong></a>\n        <a href=\"site.html\" class=\"button fork docs\"><strong>Examples</strong></a>\n        <a href=\"documentation.html\" class=\"button fork docs selected\"><strong>Documentation</strong></a>\n        <div class=\"downloads\">\n            <span>Downloads:</span>\n            <ul>\n                <li><a href=\"https://github.com/nvd3-community/nvd3/zipball/master\" class=\"button\">ZIP</a></li>\n                <li><a href=\"https://github.com/nvd3-community/nvd3/tarball/master\" class=\"button\">TAR</a></li>\n            </ul>\n        </div>\n    </div>\n</div><!-- end banner -->\n\n<div class=\"wrapper\">\n    <nav>\n        <ul></ul>\n    </nav>\n    <section>\n        <h3>\n            NVD3 Documentation\n        </h3>\n\n        <p>\n            This page lists out all options available to the charts and is generated programatically using\n            the new options object model.  All options can be called as functions on the chart object\n            to get the option vaue (if no argument given) or to set the value.   Alternatively,\n            you can use the options() method on the chart object and pass in a dictionary of the\n            option names and values to set them all at once.\n        </p>\n\n        Example:\n        <pre>\n            var chart = nv.models.pieChart();\n            chart.width(500);\n            chart.title('stuff').titleOffset(-10);\n            chart.options({height: 500, donut: true});\n        </pre>\n        <h3>Shortcuts to Charts and Chart Parts</h3>\n        <div id=\"optionjump\"></div>\n\n        <div style=\"height: 50px\"></div>\n\n        <h3 class=\"option\"><span class=\"expand all\">[ <a href=\"javascript:$('#optionlist>ul').toggle()\">toggle all</a> ]</span></h3>\n\n        <div id=\"optionlist\"></div>\n\n    </section>\n</div>\n<!--[if !IE]><script>fixScale(document);</script><![endif]-->\n\n\n<!--\nstart option info\nOptions for each chart type check this dictionary for info about the option.\nEach option can have a description, what the default value is (if any),\nand an example input list that is used to build what inputs are accepted\nas well as used to print out examples using those example inputs.\n-->\n<script>\n    var option_info = {\n        title: {\n            desc: \"Text to include within the middle of a donut chart\",\n            default: \"Blank String\",\n            examples: ['Customers']\n        },\n        titleOffset: {\n            desc: \"Vertical offset for the donut chart title\",\n            examples: [-10, 23]\n        },\n        color: {\n            desc: \"Colors to use for the different data.  If an array is given, it is converted to a function automatically.\",\n            default: \"nv.utils.defaultColor()\",\n            examples: [\n                ['#FF0000', '#00FF00', '#0000FF'],\n                function (d, i) {\n                    var colors = d3.scale.category20().range().slice(10);\n                    return colors[i % colors.length-1];\n                }\n            ]\n        },\n        showLegend: {\n            desc: \"Whether to display the legend or not\",\n            default: true,\n            examples: [true]\n        },\n        showControls: {\n            desc: \"Whether to show extra controls or not.  Extra controls include things like making mulitBar charts stacked or side by side.\",\n            default: true,\n            examples: [true]\n        },\n        tooltips: {\n            desc: \"Deprecated.  Use chart.tooltip.enabled or chart.interactive to control if tooltips are enabled or not.\"\n        },\n        tooltipContent: {\n            desc: \"Deprecated.  Use chart.tooltip.contentGenerator or chart.interactiveGuideline.tooltip.contentGenerator to control tooltip content.\"\n        },\n        noData: {\n            desc: \"Message to display if no data is provided\",\n            default: 'No Data Available.',\n            examples: [\"There is no Data to display\"]\n        },\n        duration: {\n            desc: \"Duration in ms to take when updating chart.  For things like bar charts, each bar can animate by itself but the total time taken should be this value.\",\n            default: 250,\n            examples: [1000]\n        },\n        defaultState: {\n            desc: \"No longer used.  Use chart.dispatch.changeState(...) instead.\"\n        },\n        showLabels: {\n            desc: \"Show pie/donut chart labels for each slice\",\n            default: true,\n            examples: [true]\n        },\n        width: {\n            desc: \"The width the graph or component created inside the SVG should be made.\",\n            default: \"The width of the container element (normally the svg itself)\",\n            examples: [900]\n        },\n        height: {\n            desc: \"The height the graph or component created inside the SVG should be made.\",\n            default: \"The height of the container element (normally the svg itself)\",\n            examples: [600]\n        },\n        donut: {\n            desc: \"Whether to make a pie graph a donut graph or not.\",\n            default: false,\n            examples: [true]\n        },\n        margin: {\n            desc: \"Object containing the margins for the chart or component.  You can specify only certain margins in the object to change just those parts.\",\n            defaultValueGetter: function(chart){ return chart.margin(); },\n            examples: [\n                {top: 10, bottom: 10},\n                {left: 5, right: 5, top: 10, bottom: 10}\n            ]\n        },\n        growOnHover: {\n            desc: \"For pie/donut charts, whether to increase slice radius on hover or not\",\n            default: true,\n            examples: [true]\n        },\n        labelsOutside: {\n            desc: \"Whether pie/donut chart labels should be outside the slices instead of inside them\",\n            default: true,\n            examples: [true]\n        },\n        cornerRadius: {\n            desc: \"D3 3.4+, For donut charts only, the corner radius of the slices.  Typically used with padAngle.\",\n            default: false,\n            examples: [true]\n        },\n        padAngle: {\n            desc: \"D3 3.4+, For donut charts only, the percent of the chart that should be spacing between slices.\",\n            default: 0,\n            examples: [0.05]\n        },\n        labelThreshold: {\n            desc: \"Pie/donut and Sunburst charts: The slice threshold size to not display the label because it would be too small of a space\",\n            default: 0.02,\n            examples: [0.05]\n        },\n        startAngle: {\n            desc: \"Function used to manage the starting angle of the pie/donut chart\",\n            default: \"Ignored unless set\",\n            examples: [\n                function(d) {\n                    return d.startAngle/2 - Math.PI/2;\n                }\n            ]\n        },\n        endAngle: {\n            desc: \"Function used to manage the ending angle of the pie/donut chart\",\n            default: \"Ignored unless set\",\n            examples: [\n                function(d) {\n                    return d.endAngle/2 - Math.PI/2;\n                }\n            ]\n        },\n        labelType: {\n            desc: \"pie/donut charts only: what kind of data to display for the slice labels.  Options are key, value, or percent. \",\n            default: 'key',\n            examples: ['key', 'value', 'percent']\n        },\n        x: {\n            desc: \"Proxy function to return the X value so adjustments can be made if needed.  For pie/donut chart this returns the key for the slice.\",\n            default: \"function(d){ return d.x; }\",\n            examples: [\n                function(d){\n                    return d.x;\n                }\n            ]\n        },\n        y: {\n            desc: \"Proxy function to return the Y value so adjustments can be made if needed.  For pie/donut chart this returns the value for the slice.\",\n            default: \"function(d){ return d.y; }\",\n            examples: [\n                function(d){\n                    // don't show negative values\n                    return d.y < 0 ? 0 : d.y;\n                }\n            ]\n        },\n        id: {\n            desc: \"Applies the provided ID as part of the unique class name for the chart.  For tooltip, this value is read-only.  For charts, you can use this to specify custom CSS for particular charts.  For example, if you set the chart to have id 'woot', you can customize the CSS using the selector .nvd3.nv-chart-woot\",\n            default: \"A random ID is generated by default\",\n            examples: [123, \"chart56\"]\n        },\n        showXAxis: {\n            desc: \"Display or hide the X axis\",\n            default: true,\n            examples: [false]\n        },\n        showYAxis: {\n            desc: \"Display or hide the Y axis\",\n            default: true,\n            examples: [false]\n        },\n        rightAlignYAxis: {\n            desc: \"When only one Y axis is used, this puts the Y axis on the right side instead of the left.\",\n            default: false,\n            examples: [true]\n        },\n        useInteractiveGuideline: {\n            desc: \"Sets the chart to use a guideline and floating tooltip instead of requiring the user to hover over specific hotspots.  Turning this on will set the 'interactive' and 'useVoronoi' options to false to avoid conflicting.\",\n            default: false,\n            examples: [true]\n        },\n        defined: {\n            desc: \"A provided function that allows a line to be non-continuous when not defined.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/SVG-Shapes#line_defined\"],\n            default: \"function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null }\",\n            examples: [\n                function(d,i) {\n                    // returns false if Y value is non-numeric or null\n                    return !isNaN(getY(d,i)) && getY(d,i) !== null\n                }\n            ]\n        },\n        interpolate: {\n            desc: \"controls the line interpolation between points, many options exist, see the D3 reference:\",\n            refs: ['https://github.com/mbostock/d3/wiki/SVG-Shapes#line_interpolate'],\n            default: \"linear\",\n            examples: [\"linear\", \"step\"]\n        },\n        clipEdge: {\n            desc: \"If true, masks lines within the X and Y scales using a clip-path\",\n            default: false,\n            examples: [true]\n        },\n        isArea: {\n            desc: \"Function to define if a line is a normal line or if it fills in the area.  Notice the default gets the value from the line's definition in data.  If a non-function is given, it the value is used for all lines.\",\n            default: \"function(d) { return d.area }\",\n            examples: [\n                true,\n                function(d) {\n                    return !!d.myCustomAttribute;\n                }\n            ]\n        },\n        useVoronoi: {\n            desc: \"Use voronoi diagram to select nearest point to display tooltip instead of requiring a hover over the specific point itself.  Setting this to false will also set clipVoronoi to false.\",\n            refs: [\n                \"https://github.com/mbostock/d3/wiki/Voronoi-Geom\",\n                \"http://bl.ocks.org/njvack/1405439\",\n                \"http://bl.ocks.org/mbostock/8033015\"],\n            default: true,\n            examples: [false]\n        },\n        clipVoronoi: {\n            desc: \"When useVoronoi is on, this masks each voronoi section with a circle to limit selection to smaller area.\",\n            refs: [\n                \"https://github.com/mbostock/d3/wiki/Voronoi-Geom\",\n                \"http://bl.ocks.org/njvack/1405439\",\n                \"http://bl.ocks.org/mbostock/8033015\"],\n            default: true,\n            examples: [false]\n        },\n        showVoronoi: {\n            desc: \"Displays the voronoi areas on the chart.  This is mostly helpful when debugging issues.\",\n            refs: [\n                \"https://github.com/mbostock/d3/wiki/Voronoi-Geom\",\n                \"http://bl.ocks.org/njvack/1405439\",\n                \"http://bl.ocks.org/mbostock/8033015\"],\n            default: false,\n            examples: [true]\n        },\n        clipRadius: {\n            desc: \"When useVoronoi and clipVoronoi are true, you can control the clip radius with this option.  Essentially this lets you set how far away from the actual point you can put the mouse for it to select the point.\",\n            default: 25,\n            examples: [\n                20,\n                function(d) {\n                    return 20;\n                }\n            ]\n        },\n        xScale: {\n            desc: \"Override the default scale type for the X axis\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear\"],\n            default: \"d3.scale.linear()\"\n        },\n        yScale: {\n            desc: \"Override the default scale type for the Y axis\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear\"],\n            default: \"d3.scale.linear()\"\n        },\n        pointScale: {\n            desc: \"Override the default scale type for the shapes used in the scatter plot. Scatter is also used to make the hover points on lines.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear\"],\n            default: \"d3.scale.linear()\"\n        },\n        pointSize: {\n            desc: \"Specifies the size of the points in a scatter.  Scatter is also used to make the hover points on lines.\",\n            default: \"function(d) { return d.size || 1}\",\n            refs: [\"https://github.com/mbostock/d3/wiki/SVG-Shapes#symbol_size\"],\n            examples: [\n                0.5,\n                function(d) {\n                    // use function attached to the data to calculate size\n                    return d.calculateSymbolSize();\n                }\n            ]\n        },\n        forcePoint: {\n            desc: \"Like forceX and forceY, this forces certain values onto the point scale\",\n            default: \"[]\",\n            examples: [1,2,3,4]\n        },\n        pointDomain: {\n            desc: \"Like xDomain and yDomain, this sets the range for the point scale.  Scatter is also used to make the hover points on lines.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_domain\"],\n            default: \"The scale is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        pointRange: {\n            desc: \"Like xRange and yRange, this sets the range for the point scale.  Scatter is also used to make the hover points on lines.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_range\"],\n            default: \"The range is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        pointShape: {\n            desc: \"Specify the shape of the points in a scatter.  Scatter is also used to make the hover points on lines.  You can also create your own symbols and set them onto nv.utils.symbolMap if you want, then just reference them by name like the others (see scatterGraph example for a demo)\",\n            refs: [\"https://github.com/mbostock/d3/wiki/SVG-Shapes#symbol_type\"],\n            default: \"function(d) { return d.shape || 'circle' }\",\n            examples: [\n                'circle',\n                'cross',\n                function (d) {\n                    return d.calculateSymbolType();\n                }\n            ]\n        },\n        pointActive: {\n            desc: \"Function used to determine if scatter points are active or not, returns false to denote them as inactive and true for active.\",\n            default: \"function(d) { return !d.notActive }\",\n            examples: [\n                function(d) {\n                    // d has x, y, size, shape, and series attributes.\n                    // here, we disable all points that are not a circle\n                    return d.shape !== 'circle';\n                }\n            ]\n        },\n        xDomain: {\n            desc: \"Defines the whole X scale's domain.  Using this will disable calculating the domain based on the data.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_domain\"],\n            default: \"The scale is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        yDomain: {\n            desc: \"Defines the whole Y scale's domain.  Using this will disable calculating the domain based on the data.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_domain\"],\n            default: \"The scale is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        xRange: {\n            desc: \"Override the X scale's range.  Using this will disable calculating the range based on the data and chart width/height.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_range\"],\n            default: \"The range is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        yRange: {\n            desc: \"Override the Y scale's range.  Using this will disable calculating the range based on the data and chart width/height.\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Quantitative-Scales#linear_range\"],\n            default: \"The range is dynamically calculated based on graph data\",\n            examples: [\n                [-20, -10, 0, 10, 20],\n                [-1, -0.5, 0.5, 1]\n            ]\n        },\n        forceX: {\n            desc: \"List of numbers to Force into the X scale (ie. 0, or a max / min, etc.).  This ensures the numbers are in the X domain but doesn't override the whole domain.  This option only applies if you have not overridden the whole domain with the xDomain option.\",\n            default: \"[]\",\n            examples: [\n                [-50, 0, 50]\n            ]\n        },\n        forceY: {\n            desc: \"List of numbers to Force into the Y scale (ie. 0, or a max / min, etc.).  This ensures the numbers are in the Y domain but doesn't override the whole domain.  This option only applies if you have not overridden the whole domain with the yDomain option.\",\n            default: \"[]\",\n            examples: [\n                [-50, 0, 50]\n            ]\n        },\n        valueFormat: {\n            desc: \"D3 Format object for the label of pie/donut, discrete bar and multibar charts.\",\n            default: \"d3.format(',.2f')\"\n        },\n        donutRatio: {\n            desc: \"Percent of pie radius to cut out of the middle to make the donut.  It is multiplied by the outer radius to calculate the inner radius, thus it should be between 0 and 1.\",\n            default: \"0.5\",\n            examples: [0.75]\n        },\n        legendPosition: {\n            desc: \"Position of the legend (top or right)\",\n            default: \"top\",\n            examples: [\"top\", \"right\"]\n        },\n        labelSunbeamLayout: {\n            desc: \"?\",\n            default: false,\n            examples: [true]\n        },\n        interactive: {\n            desc: \"A master flag for turning chart interaction on and off.  This overrides all tooltip, voronoi, and guideline options.\",\n            default: true,\n            examples: [false]\n        },\n        interactiveUpdateDelay: {\n            desc: \"Advanced option.  This is the delay in milliseconds before updating the interactive elements in a chart.  If set to 0, the interactive components are synchronously updated during the chart's update cycle.  If set to a larger value, then a timeout is created and the interactive elements are updated asynchronously. There is a mild performance advantage to using 0, while the default of 300 is intended to allow smoother animations.\",\n            default: 300,\n            examples: [0,300]\n        },\n        staggerLabels: {\n            desc: \"Makes the X labels stagger at different distances from the axis so they're less likely to overlap.\",\n            default: false,\n            examples: [true]\n        },\n        showValues: {\n            desc: \"Prints the Y values on the top of the bars.  Only recommended to use if there aren't many bars.\",\n            default: false,\n            examples: [true]\n        },\n        showLastValue: {\n            desc: \"Shows the last value in the sparkline to the right of the line.\",\n            default: true,\n            examples: [false]\n        },\n        padData: {\n            desc: \"?\",\n            default: false,\n            examples: [true]\n        },\n        barColor: {\n            desc: \"For bar charts, the 'color' option makes each bar a different color.  For multibar, this option lets you specific a color for each bar group to have the same color but differentiated by shading.\",\n            default: \"Not Enabled\",\n            examples: [\n                ['#FF0000', '#00FF00', '#0000FF'],\n                function (d, i) {\n                    var colors = d3.scale.category20().range().slice(10);\n                    return colors[i % colors.length-1];\n                }\n            ]\n        },\n        rotateLabels: {\n            desc: \"Rotates the X axis labels by the specified degree.\",\n            default: 0,\n            examples: [90, -45]\n        },\n        legendLeftAxisHint: {\n            desc: \"The extra text after the label in the legend that tells what axis the series belongs to, for any series on the left axis.\",\n            default: \" (left axis)\",\n            examples: [\" (L)\", \" [LEFT]\"]\n        },\n        legendRightAxisHint: {\n            desc: \"The extra text after the label in the legend that tells what axis the series belongs to, for any seris on the right axis.\",\n            default: \" (right axis)\",\n            examples: [\" (R)\", \" [RIGHT]\"]\n        },\n        controlLabels: {\n            desc: \"Object that defines the labels for control items in the graph.  For instance, in the stackedAreaChart, there are controls for making it stacked, expanded, or stream.  For stacked bar charts, there is stacked and grouped.\",\n            default: \"Depends on chart type\",\n            examples: [\n                {stacked: \"Stack It\", stream: \"Stream dat\", expanded: \"Xpand\"},\n                {grouped: \"Group em\", stacked: \"Stack em\"}\n            ]\n        },\n        controlOptions: {\n            desc: \"Override the labels for control items in the graph displayed\",\n            default: \"['Stacked', 'Stream', 'Expanded']\",\n            examples: [\n                ['Stacked', 'Stream'],\n                ['Stacked', 'Expanded'],\n                ['Stream', 'Expanded'],\n            ]\n        },\n        groupSpacing: {\n            desc: \"The padding between bar groups, this is passed as the padding attribute of rangeBands\",\n            refs: [\"https://github.com/mbostock/d3/wiki/Ordinal-Scales#ordinal_rangeBands\"],\n            default: 0.1,\n            examples: [0.5]\n        },\n        padding: {\n            desc: \"Specifies how much spacing there is between legend items.\",\n            default: \"28\",\n            examples: [\"40\"]\n        },\n        arcsRadius: {\n            desc: \"Specifies each slice size, by an inner and a outer radius. Values between 0 and 1.\",\n            default: \"[{inner: donutRatio, outer: 1}]\",\n            examples: [{inner: 0.6, outer: 0.8}]\n        },\n        lineTension: {\n            desc: \"Specifies each line tension. Values between 0 and 1.\",\n            default: 1,\n            examples: [0.85]\n        },\n        dimensions: {\n            desc: \"Deprecated. Use dimensionData instead. \"\n        },\n        dimensionNames: {\n            desc: \"Deprecated. Use dimensionData instead. \"\n        },\n        dimensionFormats: {\n            desc: \"Deprecated. Use dimensionData instead. \"\n        },\n        dimensionData: {\n            desc: \"Deprecated. Use dimensionData instead. \",\n            default: \"[]\",\n            examples: [\n            \t[\n            \t    {key:\"P1\",format: \"0.2f\", tooltip: \"Parameter 1\"},\n\t                { key: \"P2\", format: \"%\", tooltip: \"Parameter 2\" }\n\t            ]\n\t        ]\n        },\n        displayBrush: {\n            desc: \"Support brush on axis\",\n            default: true,\n            examples: [false]\n        },\n        filters: {\n\t    desc: \"Contain all informations on active brush\",\n            default: \"[]\",\n            examples: [\n            \t[\n            \t\t{dimension: \"P1\", extent: [0, 1]},\n\t\t\t        {dimension: \"P3\", extent: [0.4, 0.8]}\n\t\t        ]\n\t        ]\n        },\n        gravity: {\n            desc: \"Can be 'n','s','e','w'. Determines how tooltip is positioned.\",\n            default: \"w\",\n            examples: ['n'],\n            example_object: 'chart.tooltip'\n        },\n        snapDistance: {\n            desc: \"Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)\",\n            default: 0,\n            examples: [10],\n            example_object: 'chart.tooltip'\n        },\n        fixedTop: {\n            desc: \"For tooltip: If not null, this fixes the top position of the tooltip.\",\n            default: 'null',\n            examples: [50],\n            example_object: 'chart.tooltip'\n        },\n        chartContainer: {\n            desc: \"For tooltip: Parent dom element of the SVG that holds the chart.  This will make the tooltip dom be created inside this container instead of on the document body.\",\n            default: 'null',\n            example_object: 'chart.tooltip'\n        },\n        hidden: {\n            desc: \"For tooltip: show or hide the tooltip by setting this to true or false.  Tooltips used to be created and destroyed, but now we re-used the element and set opacity to 1 or 0.\",\n            default: 'false',\n            examples: [true],\n            example_object: 'chart.tooltip'\n        },\n        hideDelay: {\n            desc: \"Delay in ms before the tooltip hides itself after a mouseout event.  A new mouseover event cancels the hide if within this timeout period.\",\n            default: 400,\n            examples: [200],\n            example_object: 'chart.tooltip'\n        },\n        position: {\n            desc: \"For tooltip: sets the top/left positioning for the tooltip.  Should be given an object with 'left' and/or 'top' attributes.  You can override just one, just like the 'margin' option on charts.\",\n            default: \"Starts off with {top: 0, left: 0}\",\n            examples: [{top: 200, left: 300}, {left: 50}],\n            example_object: 'chart.tooltip'\n        },\n        contentGenerator: {\n            desc: \"For tooltip: Function that generates the tooltip content html.  This replaces the 'tooltipContent' option that was on most charts.  Please note that the data passed this function is usually different depending on the chart, so you'll probably need to console.log() the input object.  Also, the data passed is always a single object now, so previous functions written for the tooltipContent option will have to be adjusted accordingly.\",\n            default: \"See contentGenerator function in tooltip.js\",\n            examples: [function(obj, elem) { return JSON.stringify(obj)}],\n            example_object: 'chart.tooltip'\n        },\n        valueFormatter: {\n            desc: \"For tooltip: formats the y axis value(s) in the tooltip\",\n            default: \"Uses the yAxis' tickFormat() option\",\n            examples: [function(d) { return d > 0 ? d : 0; }],\n            example_object: 'chart.tooltip'\n        },\n        headerFormatter: {\n            desc: \"For tooltip: formats the x axis value in the tooltip\",\n            default: \"Uses the xAxis' tickFormat() option\",\n            examples: [function(d) { return d + ' monkeys' }],\n            example_object: 'chart.tooltip'\n        },\n        headerEnabled: {\n            desc: \"For tooltip: show the x axis value in the tooltip or not (not valid for pie charts for instance)\",\n            default: \"true\",\n            examples: [false],\n            example_object: 'chart.tooltip'\n        },\n        enabled: {\n            desc: \"For tooltip: completely enables or disabled the tooltip\",\n            default: \"true\",\n            examples: [false],\n            example_object: 'chart.tooltip'\n        },\n        tooltipElem: {\n            desc: \"For tooltip: returns the dom element of the tooltip.  This is read-only, you cannot set this value.\"\n        },\n        mode: {\n            desc: \"For sunburst only: specifies the mode of drawing the sunburst segments. Can be 'value' or 'count'. 'value' draws the segments according to the 'value' attribute of the leaf nodes, 'count' draws according to the amount of siblings a node has. 'size' is deprecated.\",\n            default: \"count\",\n            refs: [\"http://bl.ocks.org/kerryrodden/477c1bfb081b783f80ad\"],\n            examples: [\"value\"]\n        },\n        groupColorByParent: {\n            desc: \"For sunburst only: specifies wether the leaf elements of a parent get the same color as the parent or if they are colored individually.\",\n            default: \"true\",\n            examples: [true, false]\n        },\n        showLabels: {\n            desc: \"For sunburst only: specifies if labels are displayed. The labels are centered on the arcs. The actual output can be adjusted by specifying the 'labelFormat' function.\",\n            default: \"false\",\n            examples: [true, false]\n        },\n        labelFormat: {\n            desc: \"For sunburst only: you can alter the label output by providing a callback function. The function gets the data of the current arc as parameter. It expects you to return the plain text to be shown.\",\n            default: \"function(d){if(mode === 'count'){return d.name + ' #' + d.value}else{return d.name + ' ' + d.value}}\",\n            examples: [function(d){ return d.name;}]\n        },\n        sort: {\n            desc: \"For sunburst only: lets you specify the sort order of the arcs.\",\n            default: \"function(d1, d2){return d1.name > d2.name;}\",\n            examples: [function(d1, d2){return d1.value > d2.value;}]\n        },\n        key: {\n            desc: \"For sunburst only: you may specify how the elements are identified. The arc's data is passed into the provided function and expects an identifying string as return value. This is important when updating the chart with changed data.\",\n            default: \"function(d){return d.name;}\",\n            examples: [function(d){return d._id;}]\n        },\n        switchYAxisOrder: {\n            desc: \"If two Y axis are used, this option changes the order of both axis.\",\n            default: \"false\",\n            examples: [true, false]\n        },\n        wrapLabels: {\n            desc: \"Splits long X labels by new lines in order to prevent overlapping.\",\n            default: false,\n            examples: [true]\n        },\n        undefinedValuesLabel: {\n            desc: \"For parallel coordinate: Label displayed under the undefined values line.\",\n            default: 'undefined values',\n            examples: [\"values not defined\"]\n        },\n        fontSize: {\n            desc: \"Sets the font-size CSS style on axis labels.\",\n            default: \"undefined\",\n            examples: [\"12px\", \"1em\"]\n        },\n        nanValue: {\n            desc: \"For parallel coordinate: Text displayed in tooltip for NaN/Undefined values\",\n            default: 'undefined',\n            examples: [\"-\"]\n        },\n        showMinMaxPoints: {\n            desc: \"For sparklines: Toggle whether to highlight the minimum and maximum values with points\",\n            default: true,\n            examples: [true, false]\n        },\n        showCurrentPoint: {\n            desc: \"For sparklines: Toggle whether to highlight the current value with a point\",\n            default: true,\n            examples: [true, false]\n        },\n        pointBorderColor: {\n            desc: \"For scatter plot: colors the border of the different data points\",\n            default: \"Uses color attribute value\",\n            examples: ['#FF0000', '#00FF00', '#0000FF']\n        },\n        syncBrushing: {\n            desc: \"For focus: Toggle whether to constantly dispatch onBrush event when zooming or just when zoom end\",\n            default: true,\n            examples: [true, false]\n        },\n\t\tmaxBoxWidth: {\n            desc: \"limits the maximum box width (in pixels)\",\n            default: \"Don't limit width\",\n            examples: [50]\n        },\n\t\tplotType: {\n            desc: \"Specify the rendered plot type, choices are 'box', 'violin' or false/null in which case only scatter points will be drawn\",\n            default: false,\n            examples: ['box','violin']\n        },\n\t\tobservationType: {\n            desc: \"Specify how to position scatter points along the x-axis; choices are 'random', 'swarm', 'line', 'centered' or false. A value of false hides all observations. Note that d3-beeswarm (https://github.com/Kcnarf/d3-beeswarm) library must be loaded for 'swarm' to work.\",\n            default: 'random',\n            examples: ['random','swarm','line','centered']\n        },\n\t\twhiskerDef: {\n            desc: \"Method for calculating whisker length; choices are 'iqr', 'minmax', or 'stddev'. The type 'iqr' is the traditional way of drawing whiskers for boxplots and is defined as the lowest datum still within 1.5 IQR of the lower quartile, and the highest datum still within 1.5 IQR of the upper quartile. The type 'minmax' is simply the min or max observation within the group, and 'stddev' is 1 standard deviation from the mean. Note that changing the central tendency value (mean or median) does not change the location of any whisker type.\",\n            default: 'iqr',\n            examples: ['iqr','minmax','stddev']\n        },\n\t\tnotchBox: {\n            desc: \"Specifying this option as True will generate the boxplots with notches; notches are drawn as 95% confidence intervals around either the mean or median (central tendency +- 1.57 * IQR / n^0.5). If the notches of two plots do not overlap this is ‘strong evidence’ that the two medians differ (Chambers et al., 1983, p. 62). Note that adjusting the central tendency option will adjust the position of the notch.\",\n            default: false,\n            examples: [true, false]\n        },\n\t\thideWhiskers: {\n            desc: \"Whether to show or hide whisers when rendering with the box plotType\",\n            default: false,\n            examples: [true, false]\n        },\n\t\tcolorGroup: {\n            desc: \"If specified, this accessor function specifies the attribute to use within the data to group distrubtions along the x-axis.\",\n            default: \"false\",\n            examples: [\n                function(d){\n                    return d.group;\n                }\n            ]\n        },\n\t\tcentralTendency: {\n            desc: \"The type of central tendency to show for the distribution, this tendency will be drawn as a horizontal line; choices are 'mean', 'median' or false\",\n            default: false,\n            examples: ['mean','median',false]\n        },\n\t\tbandwidth: {\n            desc: \"Heuristic for the KDE bandwidth calculation, can be float or str, if str, must be one of 'scott' or 'silverman'\",\n            default: \"scott\",\n            examples: [\"scott\", \"silverman\"]\n        },\n\t\tresolution: {\n            desc: \"Resolution to use in kde calculation\",\n            default: 50,\n            examples: [0.1, 20]\n        },\n\t\tshowOnlyOutliers: {\n            desc: \"Whether to show only outliers in box plot - if false, all observations will be shown instead of just the outliers\",\n            default: true,\n            examples: [true, false]\n        },\n\t\tjitter: {\n            desc: \"Float value representing the percentage of box width that should be used for the random orientation of observations\",\n            default: 0.7,\n            examples: [0.2, 1]\n        },\n\t\tclampViolin: {\n            desc: \"Will limit the violin range within the range of observed data.\",\n            default: true,\n        },\n\t\tsquash: {\n            desc: \"Whether to squash boxes/violins together along the x-axi in the case where option colorGroup is specified. This removes the empty space beteween distributions in cases where the particular grouping data does not exist.\",\n            default: true,\n            examples: [true, false]\n        },\n        cellAspectRatio: {\n            desc: \"By default, cell sizes are automatically calculated to fit the screen width & height; by specifying this option, the height of cells will be calculated as cellWidth / cellAspectRatio, where cellWidth is maximized to fit the width of the screen.\",\n            default: false,\n            examples: [1.0],\n        },\n        cellRadius: {\n            desc: \"Sets the 'rx' and 'ry' attritubes of the cell to give it rounded corners\",\n            default: 2,\n            examples: [0],\n        },\n        cellBorderWidth: {\n            desc: \"Sets the border width around cells, in pixels\",\n            default: 4,\n            examples: [0],\n        },\n        cellValue: {\n            desc: \"Accessor function for setting identifying the key in the data used to set the cell value.\",\n            default: function(d) { d.value; },\n            examples: function(d) { d.cellVal; },\n        },\n        cellValueFormat: {\n            desc: \"Formatter for displayed cell value.\",\n            default: \"d3.format(',.0f')\",\n        },\n        colorRange: {\n            desc: \"Set the color range for cells\",\n            default: '[\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"]',\n            examples: [['#d01c8b','#f1b6da','#f7f7f7','#b8e186','#4dac26']]\n        },\n        colorDomain: {\n            desc: \"Set the color domain for cells; will otherwise be set automatically as either the cell value extend [if the cell values are numeric] or all cell values [if the cell values are categorical]\",\n        },\n        colorScale: {\n            desc: \"Override the default scale type for cell colors; will otherwise be set automatically as either d3.scale.quantize() [if cell values are numeric] or d3.scale.ordinal() [if cell values are categorical]\",\n        },\n        highContrastText: {\n            desc: \"Automatically set the cell label color in such a way to maximize contrast against the background color.\",\n            default: true,\n            examples: [false],\n        },\n        metaOffset: {\n            desc: \"Space between the metadata rectangles and the heatmap\",\n            default: 5,\n            examples: [0],\n        },\n        missingDataColor: {\n            desc: \"Cell color to give to those cells that have missing data; missing data occurrs either if it is not specified, or cannot be calculated due to normalization.\",\n            default: '#bcbcbc',\n            examples: ['#fff'] \n        },\n        missingDataLabel: {\n            desc: \"Cell label to give to those cells with missing data.\",\n            default: 'NaN',\n            examples: [\"\"],\n        },\n        normalize: {\n            desc: \"Normalization to apply to cells, must be one of either: 'centerRow', 'robustCenterRow', 'centerScaleRow', 'robustCenterScaleRow', 'centerColumn', 'robustCenterColumn', 'centerScaleColumn', 'robustCenterScaleColumn', 'centerAll', 'robustCenterAll', 'centerScaleAll', 'robustCenterScaleAll'.\",\n            refs: [\"http://www.arrayserver.com/wiki/index.php?title=Heatmap_normalization\"],\n            default: false,\n            examples: ['centerScaleColumn']\n        },\n        showCellValues: {\n            desc: \"Whether to show the cell values/labels\",\n            default: true,\n            examples: [false]\n        },\n        xMeta: {\n            desc: \"Accessor function to specify which key in the data should be used to display column metadata. This data will be represented as color squares positioned along with the x-axis.\",\n            default: false,\n            examples: [function(d) { return d.group; }]\n        },\n        xMetaColorScale: {\n            desc: \"Color scale to use for column metadata.\",\n            default: \"nv.utils.defaultColor()\",\n        },\n        xMetaHeight: {\n            desc: \"Function used to set the height of the column metadata rectangles\",\n            default: \"function(d) { return cellHeight / 3}\",\n            examples: [5]\n        },\n        yMeta: {\n            desc: \"Accessor function to specify which key in the data should be used to display row metadata. This data will be represented as color squares positioned along with the y-axis.\",\n            default: false,\n            examples: [function(d) { return d.group; }]\n        },\n        yMetaColorScale: {\n            desc: \"Color scale to use for row metadata.\",\n            default: \"nv.utils.defaultColor()\",\n        },\n        yMetaWidth: {\n            desc: \"Function used to set the width of the column metadata rectangles\",\n            default: \"function(d) { return cellWidth / 3}\",\n            examples: [5]\n        },\n        showGrid {\n            desc: \"Whether to show the grid lines surrounding cells.\",\n            default: \"false\",\n        },\n        cornerRadius: {\n            desc: \"This sets the corner radius (in pixels) of each bar in a discrete bar chart\",\n            default: 0,\n            examples: [1, 2, 3],\n        },\n    };\n</script>\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/donutChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n\n        svg {\n            display: block;\n            float: left;\n        }\n        #test2 {\n            height: 350px !important;\n            width: 350px !important;\n        }\n        #test1 {\n            height: 350px !important;\n            width: 350px !important;\n        }\n\n        html, body {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n        .nvd3.nv-pie.nv-chart-donut2 .nv-pie-title {\n            fill: rgba(70, 107, 168, 0.78);\n        }\n\n        .nvd3.nv-pie.nv-chart-donut1 .nv-pie-title {\n            opacity: 0.4;\n            fill: rgba(224, 116, 76, 0.91);\n        }\n\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<svg id=\"test1\" class=\"mypiechart\"></svg>\n\n<svg id=\"test2\" class=\"mypiechart\"></svg>\n\n\n\n<script>\n\n    var testdata = [\n        {key: \"One\", y: 5},\n        {key: \"Two\", y: 2},\n        {key: \"Three\", y: 9},\n        {key: \"Four\", y: 7},\n        {key: \"Five\", y: 4},\n        {key: \"Six\", y: 3},\n        {key: \"Seven\", y: 0.5}\n    ];\n\n    var height = 350;\n    var width = 350;\n\n    var chart1;\n    nv.addGraph(function() {\n        var chart1 = nv.models.pieChart()\n            .x(function(d) { return d.key })\n            .y(function(d) { return d.y })\n            .donut(true)\n            .width(width)\n            .height(height)\n            .padAngle(.08)\n            .cornerRadius(5)\n            .id('donut1'); // allow custom CSS for this one svg\n\n        chart1.title(\"100%\");\n        chart1.pie.labelsOutside(true).donut(true);\n\n        d3.select(\"#test1\")\n            .datum(testdata)\n            .transition().duration(1200)\n            .call(chart1);\n\n        // LISTEN TO WINDOW RESIZE\n        // nv.utils.windowResize(chart1.update);\n\n        // LISTEN TO CLICK EVENTS ON SLICES OF THE PIE/DONUT\n        // chart.pie.dispatch.on('elementClick', function() {\n        //     code...\n        // });\n\n        // chart.pie.dispatch.on('chartClick', function() {\n        //     code...\n        // });\n\n        // LISTEN TO DOUBLECLICK EVENTS ON SLICES OF THE PIE/DONUT\n        // chart.pie.dispatch.on('elementDblClick', function() {\n        //     code...\n        // });\n\n        // LISTEN TO THE renderEnd EVENT OF THE PIE/DONUT\n        // chart.pie.dispatch.on('renderEnd', function() {\n        //     code...\n        // });\n\n        // OTHER EVENTS DISPATCHED BY THE PIE INCLUDE: elementMouseover, elementMouseout, elementMousemove\n        // @see nv.models.pie\n\n        return chart1;\n\n    });\n\n    var chart2;\n    nv.addGraph(function() {\n        var chart2 = nv.models.pieChart()\n            .x(function(d) { return d.key })\n            .y(function(d) { return d.y })\n            //.labelThreshold(.08)\n            //.showLabels(false)\n            .color(d3.scale.category20().range().slice(10))\n            .width(width)\n            .height(height)\n            .donut(true)\n            .id('donut2')\n            .titleOffset(-30)\n            .title(\"woot\");\n\n        // MAKES IT HALF CIRCLE\n        chart2.pie\n            .startAngle(function(d) { return d.startAngle/2 -Math.PI/2 })\n            .endAngle(function(d) { return d.endAngle/2 -Math.PI/2 });\n\n        d3.select(\"#test2\")\n            //.datum(historicalBarChart)\n            .datum(testdata)\n            .transition().duration(1200)\n            .call(chart2);\n\n        return chart2;\n    });\n\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/forceDirected.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n    </style>\n</head>\n<body>\n\n<svg id=\"test1\"></svg>\n\n<script>\n    // Example based on http://bl.ocks.org/mbostock/4062045\n    nv.addGraph({\n        generate: function() {\n            var width = nv.utils.windowSize().width - 40,\n                height = nv.utils.windowSize().height - 40;\n\n            var d3Colors = d3.scale.category20();\n            var chart = nv.models.forceDirectedGraph()\n                .width(width)\n                .height(height)\n                .margin({top: 20, right: 20, bottom: 20, left: 20})\n                .color(function(d) { return d3Colors(d.group) })\n                .nodeExtras(function(node) {\n                  node\n                    .append(\"text\")\n                    .attr(\"dx\", 12)\n                    .attr(\"dy\", \".35em\")\n                    .text(function(d) { return d.name });\n                });\n\n            chart.dispatch.on('renderEnd', function(){\n                console.log('render complete');\n            });\n\n\n            d3.select('#test1')\n              .attr('width', width)\n              .attr('height', height)\n              .datum(all_data)  // all_data is set below\n              .call(chart);\n\n            return chart;\n        },\n        callback: function(graph) {\n            window.onresize = function() {\n                var width = nv.utils.windowSize().width - 40,\n                    height = nv.utils.windowSize().height - 40,\n                    margin = graph.margin();\n\n                if (width < margin.left + margin.right + 20)\n                    width = margin.left + margin.right + 20;\n\n                if (height < margin.top + margin.bottom + 20)\n                    height = margin.top + margin.bottom + 20;\n\n                graph.width(width).height(height);\n\n                d3.select('#test1')\n                    .attr('width', width)\n                    .attr('height', height)\n                    .call(graph);\n            };\n        }\n    });\n</script>\n<script>\nvar all_data = {\n    \"nodes\":[\n    {\"name\":\"Myriel\",\"group\":1},\n    {\"name\":\"Napoleon\",\"group\":1},\n    {\"name\":\"Mlle.Baptistine\",\"group\":1},\n    {\"name\":\"Mme.Magloire\",\"group\":1},\n    {\"name\":\"CountessdeLo\",\"group\":1},\n    {\"name\":\"Geborand\",\"group\":1},\n    {\"name\":\"Champtercier\",\"group\":1},\n    {\"name\":\"Cravatte\",\"group\":1},\n    {\"name\":\"Count\",\"group\":1},\n    {\"name\":\"OldMan\",\"group\":1},\n    {\"name\":\"Labarre\",\"group\":2},\n    {\"name\":\"Valjean\",\"group\":2},\n    {\"name\":\"Marguerite\",\"group\":3},\n    {\"name\":\"Mme.deR\",\"group\":2},\n    {\"name\":\"Isabeau\",\"group\":2},\n    {\"name\":\"Gervais\",\"group\":2},\n    {\"name\":\"Tholomyes\",\"group\":3},\n    {\"name\":\"Listolier\",\"group\":3},\n    {\"name\":\"Fameuil\",\"group\":3},\n    {\"name\":\"Blacheville\",\"group\":3},\n    {\"name\":\"Favourite\",\"group\":3},\n    {\"name\":\"Dahlia\",\"group\":3},\n    {\"name\":\"Zephine\",\"group\":3},\n    {\"name\":\"Fantine\",\"group\":3},\n    {\"name\":\"Mme.Thenardier\",\"group\":4},\n    {\"name\":\"Thenardier\",\"group\":4},\n    {\"name\":\"Cosette\",\"group\":5},\n    {\"name\":\"Javert\",\"group\":4},\n    {\"name\":\"Fauchelevent\",\"group\":0},\n    {\"name\":\"Bamatabois\",\"group\":2},\n    {\"name\":\"Perpetue\",\"group\":3},\n    {\"name\":\"Simplice\",\"group\":2},\n    {\"name\":\"Scaufflaire\",\"group\":2},\n    {\"name\":\"Woman1\",\"group\":2},\n    {\"name\":\"Judge\",\"group\":2},\n    {\"name\":\"Champmathieu\",\"group\":2},\n    {\"name\":\"Brevet\",\"group\":2},\n    {\"name\":\"Chenildieu\",\"group\":2},\n    {\"name\":\"Cochepaille\",\"group\":2},\n    {\"name\":\"Pontmercy\",\"group\":4},\n    {\"name\":\"Boulatruelle\",\"group\":6},\n    {\"name\":\"Eponine\",\"group\":4},\n    {\"name\":\"Anzelma\",\"group\":4},\n    {\"name\":\"Woman2\",\"group\":5},\n    {\"name\":\"MotherInnocent\",\"group\":0},\n    {\"name\":\"Gribier\",\"group\":0},\n    {\"name\":\"Jondrette\",\"group\":7},\n    {\"name\":\"Mme.Burgon\",\"group\":7},\n    {\"name\":\"Gavroche\",\"group\":8},\n    {\"name\":\"Gillenormand\",\"group\":5},\n    {\"name\":\"Magnon\",\"group\":5},\n    {\"name\":\"Mlle.Gillenormand\",\"group\":5},\n    {\"name\":\"Mme.Pontmercy\",\"group\":5},\n    {\"name\":\"Mlle.Vaubois\",\"group\":5},\n    {\"name\":\"Lt.Gillenormand\",\"group\":5},\n    {\"name\":\"Marius\",\"group\":8},\n    {\"name\":\"BaronessT\",\"group\":5},\n    {\"name\":\"Mabeuf\",\"group\":8},\n    {\"name\":\"Enjolras\",\"group\":8},\n    {\"name\":\"Combeferre\",\"group\":8},\n    {\"name\":\"Prouvaire\",\"group\":8},\n    {\"name\":\"Feuilly\",\"group\":8},\n    {\"name\":\"Courfeyrac\",\"group\":8},\n    {\"name\":\"Bahorel\",\"group\":8},\n    {\"name\":\"Bossuet\",\"group\":8},\n    {\"name\":\"Joly\",\"group\":8},\n    {\"name\":\"Grantaire\",\"group\":8},\n    {\"name\":\"MotherPlutarch\",\"group\":9},\n    {\"name\":\"Gueulemer\",\"group\":4},\n    {\"name\":\"Babet\",\"group\":4},\n    {\"name\":\"Claquesous\",\"group\":4},\n    {\"name\":\"Montparnasse\",\"group\":4},\n    {\"name\":\"Toussaint\",\"group\":5},\n    {\"name\":\"Child1\",\"group\":10},\n    {\"name\":\"Child2\",\"group\":10},\n    {\"name\":\"Brujon\",\"group\":4},\n    {\"name\":\"Mme.Hucheloup\",\"group\":8}\n],\n        \"links\":[\n    {\"source\":1,\"target\":0,\"value\":1},\n    {\"source\":2,\"target\":0,\"value\":8},\n    {\"source\":3,\"target\":0,\"value\":10},\n    {\"source\":3,\"target\":2,\"value\":6},\n    {\"source\":4,\"target\":0,\"value\":1},\n    {\"source\":5,\"target\":0,\"value\":1},\n    {\"source\":6,\"target\":0,\"value\":1},\n    {\"source\":7,\"target\":0,\"value\":1},\n    {\"source\":8,\"target\":0,\"value\":2},\n    {\"source\":9,\"target\":0,\"value\":1},\n    {\"source\":11,\"target\":10,\"value\":1},\n    {\"source\":11,\"target\":3,\"value\":3},\n    {\"source\":11,\"target\":2,\"value\":3},\n    {\"source\":11,\"target\":0,\"value\":5},\n    {\"source\":12,\"target\":11,\"value\":1},\n    {\"source\":13,\"target\":11,\"value\":1},\n    {\"source\":14,\"target\":11,\"value\":1},\n    {\"source\":15,\"target\":11,\"value\":1},\n    {\"source\":17,\"target\":16,\"value\":4},\n    {\"source\":18,\"target\":16,\"value\":4},\n    {\"source\":18,\"target\":17,\"value\":4},\n    {\"source\":19,\"target\":16,\"value\":4},\n    {\"source\":19,\"target\":17,\"value\":4},\n    {\"source\":19,\"target\":18,\"value\":4},\n    {\"source\":20,\"target\":16,\"value\":3},\n    {\"source\":20,\"target\":17,\"value\":3},\n    {\"source\":20,\"target\":18,\"value\":3},\n    {\"source\":20,\"target\":19,\"value\":4},\n    {\"source\":21,\"target\":16,\"value\":3},\n    {\"source\":21,\"target\":17,\"value\":3},\n    {\"source\":21,\"target\":18,\"value\":3},\n    {\"source\":21,\"target\":19,\"value\":3},\n    {\"source\":21,\"target\":20,\"value\":5},\n    {\"source\":22,\"target\":16,\"value\":3},\n    {\"source\":22,\"target\":17,\"value\":3},\n    {\"source\":22,\"target\":18,\"value\":3},\n    {\"source\":22,\"target\":19,\"value\":3},\n    {\"source\":22,\"target\":20,\"value\":4},\n    {\"source\":22,\"target\":21,\"value\":4},\n    {\"source\":23,\"target\":16,\"value\":3},\n    {\"source\":23,\"target\":17,\"value\":3},\n    {\"source\":23,\"target\":18,\"value\":3},\n    {\"source\":23,\"target\":19,\"value\":3},\n    {\"source\":23,\"target\":20,\"value\":4},\n    {\"source\":23,\"target\":21,\"value\":4},\n    {\"source\":23,\"target\":22,\"value\":4},\n    {\"source\":23,\"target\":12,\"value\":2},\n    {\"source\":23,\"target\":11,\"value\":9},\n    {\"source\":24,\"target\":23,\"value\":2},\n    {\"source\":24,\"target\":11,\"value\":7},\n    {\"source\":25,\"target\":24,\"value\":13},\n    {\"source\":25,\"target\":23,\"value\":1},\n    {\"source\":25,\"target\":11,\"value\":12},\n    {\"source\":26,\"target\":24,\"value\":4},\n    {\"source\":26,\"target\":11,\"value\":31},\n    {\"source\":26,\"target\":16,\"value\":1},\n    {\"source\":26,\"target\":25,\"value\":1},\n    {\"source\":27,\"target\":11,\"value\":17},\n    {\"source\":27,\"target\":23,\"value\":5},\n    {\"source\":27,\"target\":25,\"value\":5},\n    {\"source\":27,\"target\":24,\"value\":1},\n    {\"source\":27,\"target\":26,\"value\":1},\n    {\"source\":28,\"target\":11,\"value\":8},\n    {\"source\":28,\"target\":27,\"value\":1},\n    {\"source\":29,\"target\":23,\"value\":1},\n    {\"source\":29,\"target\":27,\"value\":1},\n    {\"source\":29,\"target\":11,\"value\":2},\n    {\"source\":30,\"target\":23,\"value\":1},\n    {\"source\":31,\"target\":30,\"value\":2},\n    {\"source\":31,\"target\":11,\"value\":3},\n    {\"source\":31,\"target\":23,\"value\":2},\n    {\"source\":31,\"target\":27,\"value\":1},\n    {\"source\":32,\"target\":11,\"value\":1},\n    {\"source\":33,\"target\":11,\"value\":2},\n    {\"source\":33,\"target\":27,\"value\":1},\n    {\"source\":34,\"target\":11,\"value\":3},\n    {\"source\":34,\"target\":29,\"value\":2},\n    {\"source\":35,\"target\":11,\"value\":3},\n    {\"source\":35,\"target\":34,\"value\":3},\n    {\"source\":35,\"target\":29,\"value\":2},\n    {\"source\":36,\"target\":34,\"value\":2},\n    {\"source\":36,\"target\":35,\"value\":2},\n    {\"source\":36,\"target\":11,\"value\":2},\n    {\"source\":36,\"target\":29,\"value\":1},\n    {\"source\":37,\"target\":34,\"value\":2},\n    {\"source\":37,\"target\":35,\"value\":2},\n    {\"source\":37,\"target\":36,\"value\":2},\n    {\"source\":37,\"target\":11,\"value\":2},\n    {\"source\":37,\"target\":29,\"value\":1},\n    {\"source\":38,\"target\":34,\"value\":2},\n    {\"source\":38,\"target\":35,\"value\":2},\n    {\"source\":38,\"target\":36,\"value\":2},\n    {\"source\":38,\"target\":37,\"value\":2},\n    {\"source\":38,\"target\":11,\"value\":2},\n    {\"source\":38,\"target\":29,\"value\":1},\n    {\"source\":39,\"target\":25,\"value\":1},\n    {\"source\":40,\"target\":25,\"value\":1},\n    {\"source\":41,\"target\":24,\"value\":2},\n    {\"source\":41,\"target\":25,\"value\":3},\n    {\"source\":42,\"target\":41,\"value\":2},\n    {\"source\":42,\"target\":25,\"value\":2},\n    {\"source\":42,\"target\":24,\"value\":1},\n    {\"source\":43,\"target\":11,\"value\":3},\n    {\"source\":43,\"target\":26,\"value\":1},\n    {\"source\":43,\"target\":27,\"value\":1},\n    {\"source\":44,\"target\":28,\"value\":3},\n    {\"source\":44,\"target\":11,\"value\":1},\n    {\"source\":45,\"target\":28,\"value\":2},\n    {\"source\":47,\"target\":46,\"value\":1},\n    {\"source\":48,\"target\":47,\"value\":2},\n    {\"source\":48,\"target\":25,\"value\":1},\n    {\"source\":48,\"target\":27,\"value\":1},\n    {\"source\":48,\"target\":11,\"value\":1},\n    {\"source\":49,\"target\":26,\"value\":3},\n    {\"source\":49,\"target\":11,\"value\":2},\n    {\"source\":50,\"target\":49,\"value\":1},\n    {\"source\":50,\"target\":24,\"value\":1},\n    {\"source\":51,\"target\":49,\"value\":9},\n    {\"source\":51,\"target\":26,\"value\":2},\n    {\"source\":51,\"target\":11,\"value\":2},\n    {\"source\":52,\"target\":51,\"value\":1},\n    {\"source\":52,\"target\":39,\"value\":1},\n    {\"source\":53,\"target\":51,\"value\":1},\n    {\"source\":54,\"target\":51,\"value\":2},\n    {\"source\":54,\"target\":49,\"value\":1},\n    {\"source\":54,\"target\":26,\"value\":1},\n    {\"source\":55,\"target\":51,\"value\":6},\n    {\"source\":55,\"target\":49,\"value\":12},\n    {\"source\":55,\"target\":39,\"value\":1},\n    {\"source\":55,\"target\":54,\"value\":1},\n    {\"source\":55,\"target\":26,\"value\":21},\n    {\"source\":55,\"target\":11,\"value\":19},\n    {\"source\":55,\"target\":16,\"value\":1},\n    {\"source\":55,\"target\":25,\"value\":2},\n    {\"source\":55,\"target\":41,\"value\":5},\n    {\"source\":55,\"target\":48,\"value\":4},\n    {\"source\":56,\"target\":49,\"value\":1},\n    {\"source\":56,\"target\":55,\"value\":1},\n    {\"source\":57,\"target\":55,\"value\":1},\n    {\"source\":57,\"target\":41,\"value\":1},\n    {\"source\":57,\"target\":48,\"value\":1},\n    {\"source\":58,\"target\":55,\"value\":7},\n    {\"source\":58,\"target\":48,\"value\":7},\n    {\"source\":58,\"target\":27,\"value\":6},\n    {\"source\":58,\"target\":57,\"value\":1},\n    {\"source\":58,\"target\":11,\"value\":4},\n    {\"source\":59,\"target\":58,\"value\":15},\n    {\"source\":59,\"target\":55,\"value\":5},\n    {\"source\":59,\"target\":48,\"value\":6},\n    {\"source\":59,\"target\":57,\"value\":2},\n    {\"source\":60,\"target\":48,\"value\":1},\n    {\"source\":60,\"target\":58,\"value\":4},\n    {\"source\":60,\"target\":59,\"value\":2},\n    {\"source\":61,\"target\":48,\"value\":2},\n    {\"source\":61,\"target\":58,\"value\":6},\n    {\"source\":61,\"target\":60,\"value\":2},\n    {\"source\":61,\"target\":59,\"value\":5},\n    {\"source\":61,\"target\":57,\"value\":1},\n    {\"source\":61,\"target\":55,\"value\":1},\n    {\"source\":62,\"target\":55,\"value\":9},\n    {\"source\":62,\"target\":58,\"value\":17},\n    {\"source\":62,\"target\":59,\"value\":13},\n    {\"source\":62,\"target\":48,\"value\":7},\n    {\"source\":62,\"target\":57,\"value\":2},\n    {\"source\":62,\"target\":41,\"value\":1},\n    {\"source\":62,\"target\":61,\"value\":6},\n    {\"source\":62,\"target\":60,\"value\":3},\n    {\"source\":63,\"target\":59,\"value\":5},\n    {\"source\":63,\"target\":48,\"value\":5},\n    {\"source\":63,\"target\":62,\"value\":6},\n    {\"source\":63,\"target\":57,\"value\":2},\n    {\"source\":63,\"target\":58,\"value\":4},\n    {\"source\":63,\"target\":61,\"value\":3},\n    {\"source\":63,\"target\":60,\"value\":2},\n    {\"source\":63,\"target\":55,\"value\":1},\n    {\"source\":64,\"target\":55,\"value\":5},\n    {\"source\":64,\"target\":62,\"value\":12},\n    {\"source\":64,\"target\":48,\"value\":5},\n    {\"source\":64,\"target\":63,\"value\":4},\n    {\"source\":64,\"target\":58,\"value\":10},\n    {\"source\":64,\"target\":61,\"value\":6},\n    {\"source\":64,\"target\":60,\"value\":2},\n    {\"source\":64,\"target\":59,\"value\":9},\n    {\"source\":64,\"target\":57,\"value\":1},\n    {\"source\":64,\"target\":11,\"value\":1},\n    {\"source\":65,\"target\":63,\"value\":5},\n    {\"source\":65,\"target\":64,\"value\":7},\n    {\"source\":65,\"target\":48,\"value\":3},\n    {\"source\":65,\"target\":62,\"value\":5},\n    {\"source\":65,\"target\":58,\"value\":5},\n    {\"source\":65,\"target\":61,\"value\":5},\n    {\"source\":65,\"target\":60,\"value\":2},\n    {\"source\":65,\"target\":59,\"value\":5},\n    {\"source\":65,\"target\":57,\"value\":1},\n    {\"source\":65,\"target\":55,\"value\":2},\n    {\"source\":66,\"target\":64,\"value\":3},\n    {\"source\":66,\"target\":58,\"value\":3},\n    {\"source\":66,\"target\":59,\"value\":1},\n    {\"source\":66,\"target\":62,\"value\":2},\n    {\"source\":66,\"target\":65,\"value\":2},\n    {\"source\":66,\"target\":48,\"value\":1},\n    {\"source\":66,\"target\":63,\"value\":1},\n    {\"source\":66,\"target\":61,\"value\":1},\n    {\"source\":66,\"target\":60,\"value\":1},\n    {\"source\":67,\"target\":57,\"value\":3},\n    {\"source\":68,\"target\":25,\"value\":5},\n    {\"source\":68,\"target\":11,\"value\":1},\n    {\"source\":68,\"target\":24,\"value\":1},\n    {\"source\":68,\"target\":27,\"value\":1},\n    {\"source\":68,\"target\":48,\"value\":1},\n    {\"source\":68,\"target\":41,\"value\":1},\n    {\"source\":69,\"target\":25,\"value\":6},\n    {\"source\":69,\"target\":68,\"value\":6},\n    {\"source\":69,\"target\":11,\"value\":1},\n    {\"source\":69,\"target\":24,\"value\":1},\n    {\"source\":69,\"target\":27,\"value\":2},\n    {\"source\":69,\"target\":48,\"value\":1},\n    {\"source\":69,\"target\":41,\"value\":1},\n    {\"source\":70,\"target\":25,\"value\":4},\n    {\"source\":70,\"target\":69,\"value\":4},\n    {\"source\":70,\"target\":68,\"value\":4},\n    {\"source\":70,\"target\":11,\"value\":1},\n    {\"source\":70,\"target\":24,\"value\":1},\n    {\"source\":70,\"target\":27,\"value\":1},\n    {\"source\":70,\"target\":41,\"value\":1},\n    {\"source\":70,\"target\":58,\"value\":1},\n    {\"source\":71,\"target\":27,\"value\":1},\n    {\"source\":71,\"target\":69,\"value\":2},\n    {\"source\":71,\"target\":68,\"value\":2},\n    {\"source\":71,\"target\":70,\"value\":2},\n    {\"source\":71,\"target\":11,\"value\":1},\n    {\"source\":71,\"target\":48,\"value\":1},\n    {\"source\":71,\"target\":41,\"value\":1},\n    {\"source\":71,\"target\":25,\"value\":1},\n    {\"source\":72,\"target\":26,\"value\":2},\n    {\"source\":72,\"target\":27,\"value\":1},\n    {\"source\":72,\"target\":11,\"value\":1},\n    {\"source\":73,\"target\":48,\"value\":2},\n    {\"source\":74,\"target\":48,\"value\":2},\n    {\"source\":74,\"target\":73,\"value\":3},\n    {\"source\":75,\"target\":69,\"value\":3},\n    {\"source\":75,\"target\":68,\"value\":3},\n    {\"source\":75,\"target\":25,\"value\":3},\n    {\"source\":75,\"target\":48,\"value\":1},\n    {\"source\":75,\"target\":41,\"value\":1},\n    {\"source\":75,\"target\":70,\"value\":1},\n    {\"source\":75,\"target\":71,\"value\":1},\n    {\"source\":76,\"target\":64,\"value\":1},\n    {\"source\":76,\"target\":65,\"value\":1},\n    {\"source\":76,\"target\":66,\"value\":1},\n    {\"source\":76,\"target\":63,\"value\":1},\n    {\"source\":76,\"target\":62,\"value\":1},\n    {\"source\":76,\"target\":48,\"value\":1},\n    {\"source\":76,\"target\":58,\"value\":1}\n]\n}\n</script>\n\n\n</body>\n</html>\n"
  },
  {
    "path": "examples/furiousLegend.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n<h3>Legend 1</h3>\n<button id=\"changeData\">Click to Expand/Contract</button>\n<svg id=\"test1\" class=\"nvd3\"></svg>\n\n<h3>Legend 2</h3>\n<p>Setting align(false)</p>\n<svg id=\"test2\" class=\"nvd3\"></svg>\n\n<h3>Legend 3</h3>\n<p>Setting legend padding distance</p>\n<svg id=\"test3\" class=\"nvd3\"></svg>\n\n<script>\n    var width = 500,\n        height = 40;\n\n    var legend = nv.models.legend().vers('furious');\n\n    d3.select('#test1')\n        .attr('width', width)\n        .attr('height', height)\n        .datum(sinAndCos());\n\n    var legend2 = nv.models.legend().vers('furious')\n        .align(false);\n\n    d3.select('#test2')\n        .attr('width', width)\n        .attr('height', height)\n        .datum(sinAndCos()).call(legend2);\n\n    var legend3 = nv.models.legend().vers('furious')\n        .width(900)\n        .padding(70);\n\n    d3.select('#test3')\n        .attr('width', 900)\n        .attr('height', 200)\n        .datum(sinAndCos()).call(legend3);\n\n    var update = function(i,l) {\n        d3.select('#test' + i).call(l);\n    }\n\n    update(1,legend);\n    legend.dispatch.on('stateChange', function(d) {\n        console.log(d);\n        update(1,legend);\n    });\n\n    legend2.dispatch.on('stateChange', function(d) {\n        console.log(d);\n        update(2,legend2);\n    });\n\n    legend3.dispatch.on('stateChange', function(d) {\n        console.log(d);\n        update(3,legend3);\n    });\n\n    d3.select('#changeData').on('click', function() {\n        var exp = legend.expanded();\n\n        legend.expanded(!exp);\n\n        d3.select('#test1')\n            .call(legend);\n    });\n\n    function sinAndCos() {\n        return [\n            {key: \"Sine Wave\"},\n            {key: \"averylongserieslabelthatcontainsmorethantwentycharacters\"},\n            {key: \"A Very Long Series Label\"},\n            {key: \"A Very Long Series Label\"},\n            {key: \"Cosine Wave\"},\n            {key: \"Another test label\"},\n            {key: \"Bonds\", disengaged: true},\n            {key: \"Stocks\", disengaged: true},\n            {key: \"Apple\", disengaged: true}\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/heatMap.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<head>\n    <style>\n\n        #chart {\n            height: 400px;\n        }\n\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n            font-family: 'system-ui';\n        }\n\n        .buttons {\n            margin-top: 5px;\n            margin-left: 10px;\n            font-size: 80%;\n        }\n\n        button {\n            margin-bottom: 5px;\n        }\n\n        .cell-hover rect {\n            stroke-width: 3;\n            fill-opacity: 0.2;\n        }\n\n        .cell-hover text {\n            fill: #000 !important;\n        }\n\n        .no-hover {\n            fill-opacity: 0.2;\n        }\n\n        .gridLines {\n            stroke: #bcbcbc;\n        }\n\n\n    </style>\n</head>\n\n<body>\n\n    <div class=\"buttons\">\n        <button onclick=\"updatePlot(defaultChart);\">Default</button>\n        <button onclick=\"updatePlot({cellAspectRatio: 1});\">Square</button>\n        <button onclick=\"updatePlot({cellBorderWidth: 0, cellRadius: 0});\">No border</button>\n        <button onclick=\"highContrast = !highContrast; updatePlot({highContrastText: highContrast});\">Toggle high contrast labels</button>\n        <button onclick=\"showAxes = !showAxes; updatePlot({showYAxis: showAxes, showXAxis: showAxes, showLegend: showAxes, showCellValues: showAxes});\">Toggle axes/legend/values</button>\n        <button onclick=\"showGrid = !showGrid; updatePlot({showGrid: showGrid});\">Toggle grid</button>\n        <button onclick=\"updatePlot({cellValue: function(d) { return d.level }, colorRange: ['#a50026','#d73027','#f46d43','#fdae61','#fee08b','#ffffbf','#d9ef8b','#a6d96a','#66bd63','#1a9850','#006837']});\">Discrete cell values</button>\n        <br>\n        Normalize\n        <button onclick=\"updatePlot({normalize: false});\">None</button>\n        <button onclick=\"updatePlot({normalize: 'centerRow'});\">centerRow</button>\n        <button onclick=\"updatePlot({normalize: 'centerScaleColumn'});\">centerScaleColumn</button>\n        <button onclick=\"updatePlot({normalize: 'robustCenterAll'});\">robustCenterAll</button>\n        <br>\n        Axes\n        <button onclick=\"updatePlot({alignXAxis: 'bottom'});\">X bottom</button>\n        <button onclick=\"updatePlot({alignXAxis: 'top'});\">X top</button>\n        <button onclick=\"updatePlot({alignYAxis: 'left'});\">Y left</button>\n        <button onclick=\"updatePlot({alignYAxis: 'right'});\">Y right</button>\n        | Metadata\n        <button onclick=\"updatePlot({xMeta: function(d) { return d.category }});\">X</button>\n        <button onclick=\"updatePlot({yMetaWidth: function() { return 30; }, yMeta: function(d) { return d.group }});\">Y</button>\n        | Cell Color\n        <button onclick=\"updatePlot({colorRange: ['#fff7f3','#fde0dd','#fcc5c0','#fa9fb5','#f768a1','#dd3497','#ae017e','#7a0177','#49006a']});\">Sequential color</button>\n        <button onclick=\"updatePlot({colorRange: ['#d01c8b','#f1b6da','#f7f7f7','#b8e186','#4dac26']});\">5-class diverging</button>\n    </div>\n\n    <svg id='heatMap'></svg>\n\n</body>\n\n<script>\n\n\tvar chart = nv.models.heatMapChart();\n    var highContrast = true;\n    var showGrid = false;\n    var showAxes = true;\n\tvar defaultChart = {\n        x: function(d) { return d.hour },\n        y: function(d) { return d.day },\n        cellValue: function(d) { return d.value },\n        cellAspectRatio: false,\n        normalize: false,\n        colorRange: [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"],\n        highContrastText: highContrast,\n        showXAxis: true,\n        showYAxis: true,\n        showLegend: true,\n        showGrid: showGrid,\n        showCellValues: true,\n        alignXAxis: 'top',\n        alignYAxis: 'left',\n        cellValueFormat: function(d) { return typeof d === 'number' ? d.toFixed(0) : d },\n        cellBorderWidth: 4,\n        cellRadius: 0,\n        missingDataColor: '#bcbcbc',\n        missingDataLabel: '',\n        xMeta: false,\n        yMeta: false,\n        metaOffset: 5,\n        margin: {top: 50, right: 50}\n\t}\n\n\n\t// setup default chart\n\tnv.addGraph(function() {\n\n\t\tsetChartOptions(defaultChart);\n\n\t\td3.select('svg#heatMap')\n\t\t\t.datum(data)\n\t\t\t.call(chart);\n\n\t\tnv.utils.windowResize(chart.update);\n\n\t\treturn chart;\n\t})\n\n\t// update chart with new settings\n\tfunction updatePlot(update) {\n\t\tsetChartOptions(update);\n\t\tchart.update();\n\t}\n\n\t// set chart settings\n\tfunction setChartOptions(update) {\n\n\t\tObject.keys(update).forEach(function(optName, i) {\n\t\t\tvar optVal = Object.values(update)[i];\n            console.log('Setting the option ' + optName + ' to ' + optVal);\n\t\t\tchart[optName](optVal)\n\t\t});\n\n\t}\n\n\n\tvar data = [\n        {day: 'Tu', hour: 1, value: 6, group: 13, category: 1, level: 'F'},\n        {day: 'Tu', hour: 2, value: 2, group: 13, category: 1, level: 'J'},\n        {day: 'Tu', hour: 3, value: 0, group: 13, category: 1, level: 'F'},\n        {day: 'Tu', hour: 15, value: 60, group: 13, category: 2, level: 'A'},\n        {day: 'Tu', hour: 16, value: 50, group: 13, category: 2, level: 'C'},\n        {day: 'Tu', hour: 17, value: 65, group: 13, category: 2, level: 'E'},\n        {day: 'Tu', hour: 18, value: 50, group: 13, category: 2, level: 'D'},\n        {day: 'Tu', hour: 19, value: 22, group: 13, category: 2, level: 'J'},\n        {day: 'Tu', hour: 20, value: 11, group: 13, category: 2, level: 'J'},\n        {day: 'Tu', hour: 21, value: 12, group: 13, category: 2, level: 'H'},\n        {day: 'Tu', hour: 4, value: 0, group: 13, category: 1, level: 'F'},\n        {day: 'Tu', hour: 5, value: 0, group: 13, category: 1, level: 'E'},\n        {day: 'Tu', hour: 6, value: 2, group: 13, category: 1, level: 'E'},\n        {day: 'Tu', hour: 7, value: 4, group: 13, category: 1, level: 'F'},\n        {day: 'Tu', hour: 8, value: 11, group: 13, category: 1, level: 'D'},\n        {day: 'Tu', hour: 9, value: 28, group: 13, category: 1, level: 'H'},\n        {day: 'Tu', hour: 10, value: 49, group: 13, category: 1, level: 'D'},\n        {day: 'Tu', hour: 11, value: 51, group: 13, category: 1, level: 'C'},\n        {day: 'Tu', hour: 12, value: 47, group: 13, category: 1, level: 'H'},\n        {day: 'Tu', hour: 13, value: 38, group: 13, category: 2, level: 'B'},\n        {day: 'Tu', hour: 14, value: 65, group: 13, category: 2, level: 'H'},\n        {day: 'Tu', hour: 22, value: 9, group: 13, category: 2, level: 'H'},\n        {day: 'Tu', hour: 23, value: 0, group: 13, category: 2, level: 'A'},\n        {day: 'Tu', hour: 24, value: 13, group: 13, category: 2, level: 'I'},\n        {day: 'Mo', hour: 7, value: 0, group: 84, category: 1, level: 'F'},\n        {day: 'Mo', hour: 8, value: 9, group: 84, category: 1, level: 'G'},\n        {day: 'Mo', hour: 1, value: 16, group: 84, category: 1, level: 'H'},\n        {day: 'Mo', hour: 6, value: 2, group: 84, category: 1, level: 'B'},\n        {day: 'Mo', hour: 9, value: 25, group: 84, category: 1, level: 'J'},\n        {day: 'Mo', hour: 10, value: 49, group: 84, category: 1, level: 'B'},\n        {day: 'Mo', hour: 11, value: 57, group: 84, category: 1, level: 'A'},\n        {day: 'Mo', hour: 12, value: 61, group: 84, category: 1, level: 'H'},\n        {day: 'Mo', hour: 13, value: 37, group: 84, category: 2, level: 'G'},\n        {day: 'Mo', hour: 14, value: 66, group: 84, category: 2, level: 'G'},\n        {day: 'Mo', hour: 15, value: 70, group: 84, category: 2, level: 'E'},\n        {day: 'Mo', hour: 16, value: 55, group: 84, category: 2, level: 'D'},\n        {day: 'Mo', hour: 2, value: 20, group: 84, category: 1, level: 'D'},\n        {day: 'Mo', hour: 3, value: 0, group: 84, category: 1, level: 'A'},\n        {day: 'Mo', hour: 4, value: 0, group: 84, category: 1, level: 'C'},\n        {day: 'Mo', hour: 5, value: 0, group: 84, category: 1, level: 'G'},\n        {day: 'Mo', hour: 17, value: 51, group: 84, category: 2, level: 'F'},\n        {day: 'Mo', hour: 18, value: 55, group: 84, category: 2, level: 'E'},\n        {day: 'Mo', hour: 19, value: 17, group: 84, category: 2, level: 'E'},\n        {day: 'Mo', hour: 20, value: 20, group: 84, category: 2, level: 'K'},\n        {day: 'Mo', hour: 21, value: 9, group: 84, category: 2, level: 'E'},\n        {day: 'Mo', hour: 22, value: 4, group: 84, category: 2, level: 'C'},\n        {day: 'Mo', hour: 23, value: 0, group: 84, category: 2, level: 'F'},\n        {day: 'Mo', hour: 24, value: 12, group: 84, category: 2, level: 'F'},\n        {day: 'We', hour: 1, value: 5, group: 84, category: 1, level: 'A'},\n        {day: 'We', hour: 2, value: 8, group: 84, category: 1, level: 'I'},\n        {day: 'We', hour: 3, value: 8, group: 84, category: 1, level: 'K'},\n        {day: 'We', hour: 9, value: 34, group: 84, category: 1, level: 'C'},\n        {day: 'We', hour: 10, value: 43, group: 84, category: 1, level: 'E'},\n        {day: 'We', hour: 11, value: 54, group: 84, category: 1, level: 'D'},\n        {day: 'We', hour: 12, value: 44, group: 84, category: 1, level: 'I'},\n        {day: 'We', hour: 13, value: 40, group: 84, category: 2, level: 'A'},\n        {day: 'We', hour: 14, value: 48, group: 84, category: 2, level: 'E'},\n        {day: 'We', hour: 15, value: 54, group: 84, category: 2, level: 'J'},\n        {day: 'We', hour: 16, value: 59, group: 84, category: 2, level: 'C'},\n        {day: 'We', hour: 4, value: 0, group: 84, category: 1, level: 'I'},\n        {day: 'We', hour: 5, value: 0, group: 84, category: 1, level: 'E'},\n        {day: 'We', hour: 6, value: 2, group: 84, category: 1, level: 'E'},\n        {day: 'We', hour: 7, value: 5, group: 84, category: 1, level: 'B'},\n        //{day: 'We', hour: 8, value: 12, group: 84, category: 1, level: 'B'}, // simulate missing data\n        {day: 'We', hour: 17, value: 60, group: 84, category: 2, level: 'D'},\n        {day: 'We', hour: 18, value: 51, group: 84, category: 2, level: 'A'},\n        {day: 'We', hour: 19, value: 21, group: 84, category: 2, level: 'F'},\n        {day: 'We', hour: 20, value: 16, group: 84, category: 2, level: 'E'},\n        {day: 'We', hour: 21, value: 9, group: 84, category: 2, level: 'B'},\n        {day: 'We', hour: 22, value: 5, group: 84, category: 2, level: 'K'},\n        {day: 'We', hour: 23, value: 4, group: 84, category: 2, level: 'C'},\n        {day: 'We', hour: 24, value: 7, group: 84, category: 2, level: 'B'},\n        {day: 'Th', hour: 1, value: 0, group: 13, category: 1, level: 'G'},\n        {day: 'Th', hour: 2, value: 0, group: 13, category: 1, level: 'I'},\n        {day: 'Th', hour: 7, value: 4, group: 13, category: 1, level: 'D'},\n        {day: 'Th', hour: 8, value: 13, group: 13, category: 1, level: 'J'},\n        {day: 'Th', hour: 9, value: 26, group: 13, category: 1, level: 'E'},\n        {day: 'Th', hour: 10, value: 58, group: 13, category: 1, level: 'J'},\n        {day: 'Th', hour: 11, value: 61, group: 13, category: 1, level: 'G'},\n        {day: 'Th', hour: 12, value: 59, group: 13, category: 1, level: 'E'},\n        {day: 'Th', hour: 3, value: 0, group: 13, category: 1, level: 'C'},\n        {day: 'Th', hour: 4, value: 0, group: 13, category: 1, level: 'I'},\n        {day: 'Th', hour: 5, value: 0, group: 13, category: 1, level: 'A'},\n        {day: 'Th', hour: 6, value: 2, group: 13, category: 1, level: 'A'},\n        {day: 'Th', hour: 13, value: 53, group: 13, category: 2, level: 'E'},\n        {day: 'Th', hour: 14, value: 54, group: 13, category: 2, level: 'G'},\n        {day: 'Th', hour: 15, value: 64, group: 13, category: 2, level: 'B'},\n        {day: 'Th', hour: 16, value: 55, group: 13, category: 2, level: 'C'},\n        {day: 'Th', hour: 17, value: 52, group: 13, category: 2, level: 'B'},\n        {day: 'Th', hour: 18, value: 53, group: 13, category: 2, level: 'I'},\n        {day: 'Th', hour: 19, value: 18, group: 13, category: 2, level: 'G'},\n        {day: 'Th', hour: 20, value: 3, group: 13, category: 2, level: 'C'},\n        {day: 'Th', hour: 21, value: 9, group: 13, category: 2, level: 'A'},\n        {day: 'Th', hour: 22, value: 12, group: 13, category: 2, level: 'G'},\n        {day: 'Th', hour: 23, value: 2, group: 13, category: 2, level: 'K'},\n        {day: 'Th', hour: 24, value: 8, group: 13, category: 2, level: 'K'},\n        {day: 'Fr', hour: 6, value: 2, group: 53, category: 1, level: 'B'},\n        {day: 'Fr', hour: 7, value: 4, group: 53, category: 1, level: 'E'},\n        {day: 'Fr', hour: 8, value: 14, group: 53, category: 1, level: 'K'},\n        {day: 'Fr', hour: 9, value: 31, group: 53, category: 1, level: 'C'},\n        {day: 'Fr', hour: 10, value: 48, group: 53, category: 1, level: 'C'},\n        {day: 'Fr', hour: 11, value: 46, group: 53, category: 1, level: 'F'},\n        {day: 'Fr', hour: 12, value: 50, group: 53, category: 1, level: 'A'},\n        {day: 'Fr', hour: 13, value: 66, group: 53, category: 2, level: 'H'},\n        {day: 'Fr', hour: 14, value: 54, group: 53, category: 2, level: 'E'},\n        {day: 'Fr', hour: 1, value: 2, group: 53, category: 1, level: 'C'},\n        {day: 'Fr', hour: 2, value: 0, group: 53, category: 1, level: 'K'},\n        //{day: 'Fr', hour: 3, value: 8, group: 53, category: 1, level: 'G'},  // simulate missing data\n        {day: 'Fr', hour: 4, value: 2, group: 53, category: 1, level: 'K'},\n        {day: 'Fr', hour: 5, value: 0, group: 53, category: 1, level: 'F'},\n        {day: 'Fr', hour: 15, value: 56, group: 53, category: 2, level: 'D'},\n        {day: 'Fr', hour: 16, value: 67, group: 53, category: 2, level: 'I'},\n        {day: 'Fr', hour: 17, value: 54, group: 53, category: 2, level: 'A'},\n        {day: 'Fr', hour: 18, value: 23, group: 53, category: 2, level: 'D'},\n        {day: 'Fr', hour: 19, value: 14, group: 53, category: 2, level: 'A'},\n        {day: 'Fr', hour: 20, value: 6, group: 53, category: 2, level: 'I'},\n        {day: 'Fr', hour: 21, value: 8, group: 53, category: 2, level: 'I'},\n        {day: 'Fr', hour: 22, value: 7, group: 53, category: 2, level: 'D'},\n        {day: 'Fr', hour: 23, value: 0, group: 53, category: 2, level: 'E'},\n        {day: 'Fr', hour: 24, value: 8, group: 53, category: 2, level: 'E'},\n        {day: 'Sa', hour: 1, value: 2, group: 53, category: 1, level: 'G'},\n        {day: 'Sa', hour: 2, value: 0, group: 53, category: 1, level: 'F'},\n        {day: 'Sa', hour: 3, value: 2, group: 53, category: 1, level: 'F'},\n        {day: 'Sa', hour: 8, value: 8, group: 53, category: 1, level: 'F'},\n        {day: 'Sa', hour: 9, value: 8, group: 53, category: 1, level: 'K'},\n        {day: 'Sa', hour: 10, value: 6, group: 53, category: 1, level: 'I'},\n        {day: 'Sa', hour: 11, value: 14, group: 53, category: 1, level: 'F'},\n        {day: 'Sa', hour: 12, value: 12, group: 53, category: 1, level: 'A'},\n        {day: 'Sa', hour: 13, value: 9, group: 53, category: 2, level: 'E'},\n        {day: 'Sa', hour: 14, value: 14, group: 53, category: 2, level: 'A'},\n        {day: 'Sa', hour: 15, value: 0, group: 53, category: 2, level: 'F'},\n        {day: 'Sa', hour: 4, value: 0, group: 53, category: 1, level: 'C'},\n        {day: 'Sa', hour: 5, value: 0, group: 53, category: 1, level: 'J'},\n        {day: 'Sa', hour: 6, value: 0, group: 53, category: 1, level: 'A'},\n        {day: 'Sa', hour: 7, value: 4, group: 53, category: 1, level: 'B'},\n        {day: 'Sa', hour: 16, value: 4, group: 53, category: 2, level: 'G'},\n        {day: 'Sa', hour: 17, value: 7, group: 53, category: 2, level: 'D'},\n        {day: 'Sa', hour: 18, value: 6, group: 53, category: 2, level: 'H'},\n        {day: 'Sa', hour: 19, value: 0, group: 53, category: 2, level: 'H'},\n        {day: 'Sa', hour: 20, value: 0, group: 53, category: 2, level: 'K'},\n        {day: 'Sa', hour: 21, value: 0, group: 53, category: 2, level: 'A'},\n        {day: 'Sa', hour: 22, value: 0, group: 53, category: 2, level: 'G'},\n        {day: 'Sa', hour: 23, value: 0, group: 53, category: 2, level: 'B'},\n        {day: 'Sa', hour: 24, value: 0, group: 53, category: 2, level: 'K'},\n        {day: 'Su', hour: 1, value: 7, group: 53, category: 1, level: 'G'},\n        {day: 'Su', hour: 2, value: 6, group: 53, category: 1, level: 'D'},\n        {day: 'Su', hour: 8, value: 0, group: 53, category: 1, level: 'B'},\n        {day: 'Su', hour: 9, value: 0, group: 53, category: 1, level: 'K'},\n        {day: 'Su', hour: 10, value: 0, group: 53, category: 1, level: 'J'},\n        {day: 'Su', hour: 11, value: 2, group: 53, category: 1, level: 'D'},\n        {day: 'Su', hour: 12, value: 2, group: 53, category: 1, level: 'G'},\n        {day: 'Su', hour: 3, value: 0, group: 53, category: 1, level: 'D'},\n        {day: 'Su', hour: 4, value: 0, group: 53, category: 1, level: 'A'},\n        {day: 'Su', hour: 5, value: 0, group: 53, category: 1, level: 'F'},\n        {day: 'Su', hour: 6, value: 0, group: 53, category: 1, level: 'A'},\n        {day: 'Su', hour: 7, value: 0, group: 53, category: 1, level: 'K'},\n        {day: 'Su', hour: 13, value: 5, group: 53, category: 2, level: 'K'},\n        {day: 'Su', hour: 14, value: 6, group: 53, category: 2, level: 'K'},\n        {day: 'Su', hour: 15, value: 0, group: 53, category: 2, level: 'D'},\n        {day: 'Su', hour: 16, value: 4, group: 53, category: 2, level: 'C'},\n        {day: 'Su', hour: 17, value: 0, group: 53, category: 2, level: 'D'},\n        {day: 'Su', hour: 18, value: 2, group: 53, category: 2, level: 'G'},\n        {day: 'Su', hour: 19, value: 10, group: 53, category: 2, level: 'I'},\n        {day: 'Su', hour: 20, value: 7, group: 53, category: 2, level: 'K'},\n        {day: 'Su', hour: 21, value: 0, group: 53, category: 2, level: 'I'},\n        {day: 'Su', hour: 22, value: 19, group: 53, category: 2, level: 'B'},\n        {day: 'Su', hour: 23, value: 9, group: 53, category: 2, level: 'H'},\n        {day: 'Su', hour: 24, value: 4, group: 53, category: 2, level: 'K'},\n\t];\n\n</script>\n"
  },
  {
    "path": "examples/historicalBar.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<svg id=\"test1\"></svg>\n\n<script>\n\n    nv.addGraph({\n        generate: function() {\n            var chart = nv.models.historicalBar();\n\n            d3.select(\"#test1\")\n                .datum(sinData())\n                .datum(sinData())\n                .transition()\n                .call(chart);\n\n            return chart;\n        },\n        callback: function(graph) {\n            graph.dispatch.on('elementMouseover', function(e) {\n                var offsetElement = document.getElementById(\"chart\"),\n                    left = e.pos[0],\n                    top = e.pos[1];\n                var content = '<p>' + e.point.y + '</p>';\n\n                nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's');\n            });\n\n            graph.dispatch.on('elementMouseout', function(e) {\n                nv.tooltip.cleanup();\n            });\n        }\n    });\n\n    //Simple test data generators\n    function sinAndCos() {\n        var sin = [],\n            cos = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10)});\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n        }\n\n        return [\n            {values: sin, key: \"Sine Wave\", color: \"#ff7f0e\"},\n            {values: cos, key: \"Cosine Wave\", color: \"#2ca02c\"}\n        ];\n    }\n\n    function sinData() {\n        var sin = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10)});\n        }\n\n        return [{\n            values: sin,\n            key: \"Sine Wave\",\n            color: \"#ff7f0e\"\n        }];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/historicalBarChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<svg id=\"test1\"></svg>\n\n<script>\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.historicalBarChart();\n        chart\n            .margin({left: 100, bottom: 100})\n            .useInteractiveGuideline(true)\n            .duration(250)\n            ;\n\n        // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        chart.xAxis\n            .axisLabel(\"Time (s)\")\n            .tickFormat(d3.format(',.1f'));\n\n        chart.yAxis\n            .axisLabel('Voltage (v)')\n            .tickFormat(d3.format(',.2f'));\n\n        chart.showXAxis(true);\n\n        d3.select('#test1')\n            .datum(sinData())\n            .transition()\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n        return chart;\n    });\n\n    //Simple test data generators\n    function sinAndCos() {\n        var sin = [],\n            cos = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10)});\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n        }\n\n        return [\n            {values: sin, key: \"Sine Wave\", color: \"#ff7f0e\"},\n            {values: cos, key: \"Cosine Wave\", color: \"#2ca02c\"}\n        ];\n    }\n\n    function sinData() {\n        var sin = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10) * Math.random() * 100});\n        }\n\n        return [{\n            values: sin,\n            key: \"Sine Wave\",\n            color: \"#ff7f0e\"\n        }];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>NVD3 Examples List</title>\n</head>\n<body>\n    <script src=\"http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></script>\n    <script type=\"text/javascript\">\n        window.onload = function() {\n            $('body').ready(function() {\n                $('li a').each(function(i, elem) {\n                    $(elem).click(function(evt) {\n                        $('#show').prop('src', $(evt.target).prop('href'));\n                        evt.stopPropagation();\n                        evt.preventDefault();\n                        $('li').removeClass('selected');\n                        $(evt.target).parents('li').addClass('selected');\n                        return false;\n                    });\n                });\n            });\n        }\n    </script>\n    <style>\n        body {\n            font-family: Helvetica;\n            /* IE10 Consumer Preview */\n            background-image: -ms-radial-gradient(left top, circle farthest-corner, #FFFFFF 0%, #DEE2FF 100%);\n\n            /* Mozilla Firefox */\n            background-image: -moz-radial-gradient(left top, circle farthest-corner, #FFFFFF 0%, #DEE2FF 100%);\n\n            /* Opera */\n            background-image: -o-radial-gradient(left top, circle farthest-corner, #FFFFFF 0%, #DEE2FF 100%);\n\n            /* Webkit (Safari/Chrome 10) */\n            background-image: -webkit-gradient(radial, left top, 0, left top, 1012, color-stop(0, #FFFFFF), color-stop(1, #DEE2FF));\n\n            /* Webkit (Chrome 11+) */\n            background-image: -webkit-radial-gradient(left top, circle farthest-corner, #FFFFFF 0%, #DEE2FF 100%);\n\n            /* W3C Markup, IE10 Release Preview */\n            background-image: radial-gradient(circle farthest-corner at left top, #FFFFFF 0%, #DEE2FF 100%);\n        }\n\n        ul {\n            list-style: none;\n            float: left;\n            margin-right: 5px;\n            border-right: solid 1px #ccc;\n            padding: 5px;\n        }\n\n        li {\n            padding: 4px;\n            min-width: 100px;\n\n        }\n        li:hover {\n            background-color: #ccc;\n        }\n        li.selected {\n            padding: 3px;\n            background-color: #FF9900;\n            border: 1px solid #999;\n        }\n\n        a {\n            text-decoration: none;\n            display:block;\n            font-size: 12px;\n            font-family: arial;\n            outline: none;\n        }\n        table { width: 100%; }\n        td { vertical-align: top; }\n        html, body, div { margin: 0; padding: 0}\n        body { padding: 20px; }\n\n        iframe {\n            width: 100%;\n            height: 500px;\n            border: 0px;\n        }\n        #show_wrapper {\n            border: 1px solid #666;\n            min-width: 800px;\n            float: left;\n        }\n\n    </style>\n\n    <h2>NVD3 Examples List</h2>\n        <ul>\n            <li><a href=\"bullet.html\">Bullet</a>\n            <li><a href=\"bulletChart.html\">BulletChart</a>\n            <li><a href=\"crossfilter.html\">Crossfilter</a>\n            <li><a href=\"crossfilterWithDimentions.html\">CrossfilterWithDimentions</a>\n            <li><a href=\"crossfilterWithTables.html\">CrossfilterWithTables</a>\n            <li><a href=\"cumulativeLineChart.html\">CumulativeLineChart</a>\n            <li><a href=\"discreteBarChart.html\">DiscreteBarChart</a>\n            <li><a href=\"historicalBar.html\">HistoricalBar</a>\n            <li><a href=\"historicalBarChart.html\">HistoricalBarChart</a>\n            <li><a href=\"horizon.html\">Horizon</a>\n            <li><a href=\"indentedtree.html\">Indentedtree</a>\n            <li><a href=\"legend.html\">Legend</a>\n            <li><a href=\"furiousLegend.html\">Furious Legend</a>\n            <li><a href=\"line.html\">Line</a>\n            <li><a href=\"lineChart.html\">LineChart</a>\n            <li><a href=\"lineChartSVGResize.html\">LineChartSVGResize</a>\n            <li><a href=\"linePlusBarChart.html\">LinePlusBarChart</a>\n            <li><a href=\"linePlusBarWithFocusChart.html\">LinePlusBarWithFocusChart</a>\n            <li><a href=\"lineWithFisheyeChart.html\">LineWithFisheyeChart</a>\n            <li><a href=\"lineWithFocusChart.html\">LineWithFocusChart</a>\n            <li><a href=\"sankeyChart.html\">SankeyChart</a>\n        </ul>\n        <ul>\n            <li><a href=\"multiBar.html\">MultiBar</a>\n            <li><a href=\"multiBarChart.html\">MultiBarChart</a>\n            <li><a href=\"multiBarHorizontalChart.html\">MultiBarHorizontalChart</a>\n            <li><a href=\"multiChart.html\">MultiChart</a>\n            <li><a href=\"parallelCoordinates.html\">ParallelCoordinates</a>\n            <li><a href=\"pie.html\">Pie</a>\n            <li><a href=\"pieChart.html\">PieChart</a>\n            <li><a href=\"scatter.html\">Scatter</a>\n            <li><a href=\"scatterChart.html\">ScatterChart</a>\n            <li><a href=\"scatterPlusLineChart.html\">ScatterPlusLineChart</a>\n            <li><a href=\"sparkline.html\">Sparkline</a>\n            <li><a href=\"sparklinePlus.html\">SparklinePlus</a>\n            <li><a href=\"stackedArea.html\">StackedArea</a>\n            <li><a href=\"stackedAreaChart.html\">StackedAreaChart</a>\n        </ul>\n\n        <ul>\n            <strong>Test pages</strong>\n            <li><a href=\"../test/lineChartTest.html\">Line Chart</a></li>\n            <li><a href=\"../test/pieChartTest.html\">Pie Chart</a></li>\n            <li><a href=\"../test/ScatterChartTest.html\">Scatter Chart</a></li>\n            <li><a href=\"../test/stackedAreaChartTest.html\">Stacked Area Chart</a></li>\n            <li><a href=\"../test/multiBarChartTest.html\">Multibar Chart</a></li>\n            <li><a href=\"../test/polylinearTest.html\">Polylinear Scale Line Chart</a></li>\n            <li><a href=\"../test/realTimeChartTest.html\">Real Time Chart</a></li>\n        </ul>\n\n        <div id=\"show_wrapper\"><iframe id=\"show\"></iframe></div>\n\n</body>\n</html>"
  },
  {
    "path": "examples/legend.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n<h3>Legend 1</h3>\n<button id=\"changeData\">Click to Change Legend</button>\n<svg id=\"test1\" class=\"nvd3\"></svg>\n\n<h3>Legend 2</h3>\n<p>Setting align(false)</p>\n<svg id=\"test2\" class=\"nvd3\"></svg>\n\n<h3>Legend 3</h3>\n<p>Setting legend padding distance</p>\n<svg id=\"test3\" class=\"nvd3\"></svg>\n\n<script>\n    var width = 500,\n        height = 20;\n\n    var legend = nv.models.legend();\n\n    d3.select('#test1')\n        .attr('width', width)\n        .attr('height', height)\n        .datum(sinAndCos());\n\n    var legend2 = nv.models.legend()\n        .align(false);\n\n    d3.select('#test2')\n        .attr('width', width)\n        .attr('height', height)\n        .datum(sinAndCos()).call(legend2);\n\n    var legend3 = nv.models.legend()\n        .width(900)\n        .padding(70);\n\n    d3.select('#test3')\n        .attr('width', 900)\n        .attr('height', 200)\n        .datum(sinAndCos()).call(legend3);\n\n    var update = function() {\n        d3.select('#test1').call(legend);\n    }\n\n    update();\n    legend.dispatch.on('stateChange', function(d) { \n        console.log(d);\n        update();\n    });\n\n    d3.select('#changeData').on('click', function() {\n        d3.select('#test1')\n        .datum(differentData())\n        .call(legend);\n    });\n\n    function sinAndCos() {\n        return [\n            {key: \"Sine Wave\"},\n            {key: \"A Very Long Label With Over Twenty Characters\"},\n            {key: \"A Very Long Series Label With Over Twenty Characters\"},\n            {key: \"A Very Long Series Label With Over Twenty Characters\"},\n            {key: \"Cosine Wave\"},\n            {key: \"Another test label\"}\n        ];\n    }\n\n    function differentData() {\n        return [\n            {key: \"Fixed Income\"},\n            {key: \"Derivatives\"},\n            {key: \"Credit Default Swaps\"},\n            {key: \"Equities\"},\n            {key: \"Bonds\"},\n            {key: \"Stocks\"},\n            {key: \"Apple\"}\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/lib/colorbrewer.js",
    "content": "// This product includes color specifications and designs developed by Cynthia Brewer (http://colorbrewer.org/).\nvar colorbrewer = {YlGn: {\n3: [\"#f7fcb9\",\"#addd8e\",\"#31a354\"],\n4: [\"#ffffcc\",\"#c2e699\",\"#78c679\",\"#238443\"],\n5: [\"#ffffcc\",\"#c2e699\",\"#78c679\",\"#31a354\",\"#006837\"],\n6: [\"#ffffcc\",\"#d9f0a3\",\"#addd8e\",\"#78c679\",\"#31a354\",\"#006837\"],\n7: [\"#ffffcc\",\"#d9f0a3\",\"#addd8e\",\"#78c679\",\"#41ab5d\",\"#238443\",\"#005a32\"],\n8: [\"#ffffe5\",\"#f7fcb9\",\"#d9f0a3\",\"#addd8e\",\"#78c679\",\"#41ab5d\",\"#238443\",\"#005a32\"],\n9: [\"#ffffe5\",\"#f7fcb9\",\"#d9f0a3\",\"#addd8e\",\"#78c679\",\"#41ab5d\",\"#238443\",\"#006837\",\"#004529\"]\n},YlGnBu: {\n3: [\"#edf8b1\",\"#7fcdbb\",\"#2c7fb8\"],\n4: [\"#ffffcc\",\"#a1dab4\",\"#41b6c4\",\"#225ea8\"],\n5: [\"#ffffcc\",\"#a1dab4\",\"#41b6c4\",\"#2c7fb8\",\"#253494\"],\n6: [\"#ffffcc\",\"#c7e9b4\",\"#7fcdbb\",\"#41b6c4\",\"#2c7fb8\",\"#253494\"],\n7: [\"#ffffcc\",\"#c7e9b4\",\"#7fcdbb\",\"#41b6c4\",\"#1d91c0\",\"#225ea8\",\"#0c2c84\"],\n8: [\"#ffffd9\",\"#edf8b1\",\"#c7e9b4\",\"#7fcdbb\",\"#41b6c4\",\"#1d91c0\",\"#225ea8\",\"#0c2c84\"],\n9: [\"#ffffd9\",\"#edf8b1\",\"#c7e9b4\",\"#7fcdbb\",\"#41b6c4\",\"#1d91c0\",\"#225ea8\",\"#253494\",\"#081d58\"]\n},GnBu: {\n3: [\"#e0f3db\",\"#a8ddb5\",\"#43a2ca\"],\n4: [\"#f0f9e8\",\"#bae4bc\",\"#7bccc4\",\"#2b8cbe\"],\n5: [\"#f0f9e8\",\"#bae4bc\",\"#7bccc4\",\"#43a2ca\",\"#0868ac\"],\n6: [\"#f0f9e8\",\"#ccebc5\",\"#a8ddb5\",\"#7bccc4\",\"#43a2ca\",\"#0868ac\"],\n7: [\"#f0f9e8\",\"#ccebc5\",\"#a8ddb5\",\"#7bccc4\",\"#4eb3d3\",\"#2b8cbe\",\"#08589e\"],\n8: [\"#f7fcf0\",\"#e0f3db\",\"#ccebc5\",\"#a8ddb5\",\"#7bccc4\",\"#4eb3d3\",\"#2b8cbe\",\"#08589e\"],\n9: [\"#f7fcf0\",\"#e0f3db\",\"#ccebc5\",\"#a8ddb5\",\"#7bccc4\",\"#4eb3d3\",\"#2b8cbe\",\"#0868ac\",\"#084081\"]\n},BuGn: {\n3: [\"#e5f5f9\",\"#99d8c9\",\"#2ca25f\"],\n4: [\"#edf8fb\",\"#b2e2e2\",\"#66c2a4\",\"#238b45\"],\n5: [\"#edf8fb\",\"#b2e2e2\",\"#66c2a4\",\"#2ca25f\",\"#006d2c\"],\n6: [\"#edf8fb\",\"#ccece6\",\"#99d8c9\",\"#66c2a4\",\"#2ca25f\",\"#006d2c\"],\n7: [\"#edf8fb\",\"#ccece6\",\"#99d8c9\",\"#66c2a4\",\"#41ae76\",\"#238b45\",\"#005824\"],\n8: [\"#f7fcfd\",\"#e5f5f9\",\"#ccece6\",\"#99d8c9\",\"#66c2a4\",\"#41ae76\",\"#238b45\",\"#005824\"],\n9: [\"#f7fcfd\",\"#e5f5f9\",\"#ccece6\",\"#99d8c9\",\"#66c2a4\",\"#41ae76\",\"#238b45\",\"#006d2c\",\"#00441b\"]\n},PuBuGn: {\n3: [\"#ece2f0\",\"#a6bddb\",\"#1c9099\"],\n4: [\"#f6eff7\",\"#bdc9e1\",\"#67a9cf\",\"#02818a\"],\n5: [\"#f6eff7\",\"#bdc9e1\",\"#67a9cf\",\"#1c9099\",\"#016c59\"],\n6: [\"#f6eff7\",\"#d0d1e6\",\"#a6bddb\",\"#67a9cf\",\"#1c9099\",\"#016c59\"],\n7: [\"#f6eff7\",\"#d0d1e6\",\"#a6bddb\",\"#67a9cf\",\"#3690c0\",\"#02818a\",\"#016450\"],\n8: [\"#fff7fb\",\"#ece2f0\",\"#d0d1e6\",\"#a6bddb\",\"#67a9cf\",\"#3690c0\",\"#02818a\",\"#016450\"],\n9: [\"#fff7fb\",\"#ece2f0\",\"#d0d1e6\",\"#a6bddb\",\"#67a9cf\",\"#3690c0\",\"#02818a\",\"#016c59\",\"#014636\"]\n},PuBu: {\n3: [\"#ece7f2\",\"#a6bddb\",\"#2b8cbe\"],\n4: [\"#f1eef6\",\"#bdc9e1\",\"#74a9cf\",\"#0570b0\"],\n5: [\"#f1eef6\",\"#bdc9e1\",\"#74a9cf\",\"#2b8cbe\",\"#045a8d\"],\n6: [\"#f1eef6\",\"#d0d1e6\",\"#a6bddb\",\"#74a9cf\",\"#2b8cbe\",\"#045a8d\"],\n7: [\"#f1eef6\",\"#d0d1e6\",\"#a6bddb\",\"#74a9cf\",\"#3690c0\",\"#0570b0\",\"#034e7b\"],\n8: [\"#fff7fb\",\"#ece7f2\",\"#d0d1e6\",\"#a6bddb\",\"#74a9cf\",\"#3690c0\",\"#0570b0\",\"#034e7b\"],\n9: [\"#fff7fb\",\"#ece7f2\",\"#d0d1e6\",\"#a6bddb\",\"#74a9cf\",\"#3690c0\",\"#0570b0\",\"#045a8d\",\"#023858\"]\n},BuPu: {\n3: [\"#e0ecf4\",\"#9ebcda\",\"#8856a7\"],\n4: [\"#edf8fb\",\"#b3cde3\",\"#8c96c6\",\"#88419d\"],\n5: [\"#edf8fb\",\"#b3cde3\",\"#8c96c6\",\"#8856a7\",\"#810f7c\"],\n6: [\"#edf8fb\",\"#bfd3e6\",\"#9ebcda\",\"#8c96c6\",\"#8856a7\",\"#810f7c\"],\n7: [\"#edf8fb\",\"#bfd3e6\",\"#9ebcda\",\"#8c96c6\",\"#8c6bb1\",\"#88419d\",\"#6e016b\"],\n8: [\"#f7fcfd\",\"#e0ecf4\",\"#bfd3e6\",\"#9ebcda\",\"#8c96c6\",\"#8c6bb1\",\"#88419d\",\"#6e016b\"],\n9: [\"#f7fcfd\",\"#e0ecf4\",\"#bfd3e6\",\"#9ebcda\",\"#8c96c6\",\"#8c6bb1\",\"#88419d\",\"#810f7c\",\"#4d004b\"]\n},RdPu: {\n3: [\"#fde0dd\",\"#fa9fb5\",\"#c51b8a\"],\n4: [\"#feebe2\",\"#fbb4b9\",\"#f768a1\",\"#ae017e\"],\n5: [\"#feebe2\",\"#fbb4b9\",\"#f768a1\",\"#c51b8a\",\"#7a0177\"],\n6: [\"#feebe2\",\"#fcc5c0\",\"#fa9fb5\",\"#f768a1\",\"#c51b8a\",\"#7a0177\"],\n7: [\"#feebe2\",\"#fcc5c0\",\"#fa9fb5\",\"#f768a1\",\"#dd3497\",\"#ae017e\",\"#7a0177\"],\n8: [\"#fff7f3\",\"#fde0dd\",\"#fcc5c0\",\"#fa9fb5\",\"#f768a1\",\"#dd3497\",\"#ae017e\",\"#7a0177\"],\n9: [\"#fff7f3\",\"#fde0dd\",\"#fcc5c0\",\"#fa9fb5\",\"#f768a1\",\"#dd3497\",\"#ae017e\",\"#7a0177\",\"#49006a\"]\n},PuRd: {\n3: [\"#e7e1ef\",\"#c994c7\",\"#dd1c77\"],\n4: [\"#f1eef6\",\"#d7b5d8\",\"#df65b0\",\"#ce1256\"],\n5: [\"#f1eef6\",\"#d7b5d8\",\"#df65b0\",\"#dd1c77\",\"#980043\"],\n6: [\"#f1eef6\",\"#d4b9da\",\"#c994c7\",\"#df65b0\",\"#dd1c77\",\"#980043\"],\n7: [\"#f1eef6\",\"#d4b9da\",\"#c994c7\",\"#df65b0\",\"#e7298a\",\"#ce1256\",\"#91003f\"],\n8: [\"#f7f4f9\",\"#e7e1ef\",\"#d4b9da\",\"#c994c7\",\"#df65b0\",\"#e7298a\",\"#ce1256\",\"#91003f\"],\n9: [\"#f7f4f9\",\"#e7e1ef\",\"#d4b9da\",\"#c994c7\",\"#df65b0\",\"#e7298a\",\"#ce1256\",\"#980043\",\"#67001f\"]\n},OrRd: {\n3: [\"#fee8c8\",\"#fdbb84\",\"#e34a33\"],\n4: [\"#fef0d9\",\"#fdcc8a\",\"#fc8d59\",\"#d7301f\"],\n5: [\"#fef0d9\",\"#fdcc8a\",\"#fc8d59\",\"#e34a33\",\"#b30000\"],\n6: [\"#fef0d9\",\"#fdd49e\",\"#fdbb84\",\"#fc8d59\",\"#e34a33\",\"#b30000\"],\n7: [\"#fef0d9\",\"#fdd49e\",\"#fdbb84\",\"#fc8d59\",\"#ef6548\",\"#d7301f\",\"#990000\"],\n8: [\"#fff7ec\",\"#fee8c8\",\"#fdd49e\",\"#fdbb84\",\"#fc8d59\",\"#ef6548\",\"#d7301f\",\"#990000\"],\n9: [\"#fff7ec\",\"#fee8c8\",\"#fdd49e\",\"#fdbb84\",\"#fc8d59\",\"#ef6548\",\"#d7301f\",\"#b30000\",\"#7f0000\"]\n},YlOrRd: {\n3: [\"#ffeda0\",\"#feb24c\",\"#f03b20\"],\n4: [\"#ffffb2\",\"#fecc5c\",\"#fd8d3c\",\"#e31a1c\"],\n5: [\"#ffffb2\",\"#fecc5c\",\"#fd8d3c\",\"#f03b20\",\"#bd0026\"],\n6: [\"#ffffb2\",\"#fed976\",\"#feb24c\",\"#fd8d3c\",\"#f03b20\",\"#bd0026\"],\n7: [\"#ffffb2\",\"#fed976\",\"#feb24c\",\"#fd8d3c\",\"#fc4e2a\",\"#e31a1c\",\"#b10026\"],\n8: [\"#ffffcc\",\"#ffeda0\",\"#fed976\",\"#feb24c\",\"#fd8d3c\",\"#fc4e2a\",\"#e31a1c\",\"#b10026\"],\n9: [\"#ffffcc\",\"#ffeda0\",\"#fed976\",\"#feb24c\",\"#fd8d3c\",\"#fc4e2a\",\"#e31a1c\",\"#bd0026\",\"#800026\"]\n},YlOrBr: {\n3: [\"#fff7bc\",\"#fec44f\",\"#d95f0e\"],\n4: [\"#ffffd4\",\"#fed98e\",\"#fe9929\",\"#cc4c02\"],\n5: [\"#ffffd4\",\"#fed98e\",\"#fe9929\",\"#d95f0e\",\"#993404\"],\n6: [\"#ffffd4\",\"#fee391\",\"#fec44f\",\"#fe9929\",\"#d95f0e\",\"#993404\"],\n7: [\"#ffffd4\",\"#fee391\",\"#fec44f\",\"#fe9929\",\"#ec7014\",\"#cc4c02\",\"#8c2d04\"],\n8: [\"#ffffe5\",\"#fff7bc\",\"#fee391\",\"#fec44f\",\"#fe9929\",\"#ec7014\",\"#cc4c02\",\"#8c2d04\"],\n9: [\"#ffffe5\",\"#fff7bc\",\"#fee391\",\"#fec44f\",\"#fe9929\",\"#ec7014\",\"#cc4c02\",\"#993404\",\"#662506\"]\n},Purples: {\n3: [\"#efedf5\",\"#bcbddc\",\"#756bb1\"],\n4: [\"#f2f0f7\",\"#cbc9e2\",\"#9e9ac8\",\"#6a51a3\"],\n5: [\"#f2f0f7\",\"#cbc9e2\",\"#9e9ac8\",\"#756bb1\",\"#54278f\"],\n6: [\"#f2f0f7\",\"#dadaeb\",\"#bcbddc\",\"#9e9ac8\",\"#756bb1\",\"#54278f\"],\n7: [\"#f2f0f7\",\"#dadaeb\",\"#bcbddc\",\"#9e9ac8\",\"#807dba\",\"#6a51a3\",\"#4a1486\"],\n8: [\"#fcfbfd\",\"#efedf5\",\"#dadaeb\",\"#bcbddc\",\"#9e9ac8\",\"#807dba\",\"#6a51a3\",\"#4a1486\"],\n9: [\"#fcfbfd\",\"#efedf5\",\"#dadaeb\",\"#bcbddc\",\"#9e9ac8\",\"#807dba\",\"#6a51a3\",\"#54278f\",\"#3f007d\"]\n},Blues: {\n3: [\"#deebf7\",\"#9ecae1\",\"#3182bd\"],\n4: [\"#eff3ff\",\"#bdd7e7\",\"#6baed6\",\"#2171b5\"],\n5: [\"#eff3ff\",\"#bdd7e7\",\"#6baed6\",\"#3182bd\",\"#08519c\"],\n6: [\"#eff3ff\",\"#c6dbef\",\"#9ecae1\",\"#6baed6\",\"#3182bd\",\"#08519c\"],\n7: [\"#eff3ff\",\"#c6dbef\",\"#9ecae1\",\"#6baed6\",\"#4292c6\",\"#2171b5\",\"#084594\"],\n8: [\"#f7fbff\",\"#deebf7\",\"#c6dbef\",\"#9ecae1\",\"#6baed6\",\"#4292c6\",\"#2171b5\",\"#084594\"],\n9: [\"#f7fbff\",\"#deebf7\",\"#c6dbef\",\"#9ecae1\",\"#6baed6\",\"#4292c6\",\"#2171b5\",\"#08519c\",\"#08306b\"]\n},Greens: {\n3: [\"#e5f5e0\",\"#a1d99b\",\"#31a354\"],\n4: [\"#edf8e9\",\"#bae4b3\",\"#74c476\",\"#238b45\"],\n5: [\"#edf8e9\",\"#bae4b3\",\"#74c476\",\"#31a354\",\"#006d2c\"],\n6: [\"#edf8e9\",\"#c7e9c0\",\"#a1d99b\",\"#74c476\",\"#31a354\",\"#006d2c\"],\n7: [\"#edf8e9\",\"#c7e9c0\",\"#a1d99b\",\"#74c476\",\"#41ab5d\",\"#238b45\",\"#005a32\"],\n8: [\"#f7fcf5\",\"#e5f5e0\",\"#c7e9c0\",\"#a1d99b\",\"#74c476\",\"#41ab5d\",\"#238b45\",\"#005a32\"],\n9: [\"#f7fcf5\",\"#e5f5e0\",\"#c7e9c0\",\"#a1d99b\",\"#74c476\",\"#41ab5d\",\"#238b45\",\"#006d2c\",\"#00441b\"]\n},Oranges: {\n3: [\"#fee6ce\",\"#fdae6b\",\"#e6550d\"],\n4: [\"#feedde\",\"#fdbe85\",\"#fd8d3c\",\"#d94701\"],\n5: [\"#feedde\",\"#fdbe85\",\"#fd8d3c\",\"#e6550d\",\"#a63603\"],\n6: [\"#feedde\",\"#fdd0a2\",\"#fdae6b\",\"#fd8d3c\",\"#e6550d\",\"#a63603\"],\n7: [\"#feedde\",\"#fdd0a2\",\"#fdae6b\",\"#fd8d3c\",\"#f16913\",\"#d94801\",\"#8c2d04\"],\n8: [\"#fff5eb\",\"#fee6ce\",\"#fdd0a2\",\"#fdae6b\",\"#fd8d3c\",\"#f16913\",\"#d94801\",\"#8c2d04\"],\n9: [\"#fff5eb\",\"#fee6ce\",\"#fdd0a2\",\"#fdae6b\",\"#fd8d3c\",\"#f16913\",\"#d94801\",\"#a63603\",\"#7f2704\"]\n},Reds: {\n3: [\"#fee0d2\",\"#fc9272\",\"#de2d26\"],\n4: [\"#fee5d9\",\"#fcae91\",\"#fb6a4a\",\"#cb181d\"],\n5: [\"#fee5d9\",\"#fcae91\",\"#fb6a4a\",\"#de2d26\",\"#a50f15\"],\n6: [\"#fee5d9\",\"#fcbba1\",\"#fc9272\",\"#fb6a4a\",\"#de2d26\",\"#a50f15\"],\n7: [\"#fee5d9\",\"#fcbba1\",\"#fc9272\",\"#fb6a4a\",\"#ef3b2c\",\"#cb181d\",\"#99000d\"],\n8: [\"#fff5f0\",\"#fee0d2\",\"#fcbba1\",\"#fc9272\",\"#fb6a4a\",\"#ef3b2c\",\"#cb181d\",\"#99000d\"],\n9: [\"#fff5f0\",\"#fee0d2\",\"#fcbba1\",\"#fc9272\",\"#fb6a4a\",\"#ef3b2c\",\"#cb181d\",\"#a50f15\",\"#67000d\"]\n},Greys: {\n3: [\"#f0f0f0\",\"#bdbdbd\",\"#636363\"],\n4: [\"#f7f7f7\",\"#cccccc\",\"#969696\",\"#525252\"],\n5: [\"#f7f7f7\",\"#cccccc\",\"#969696\",\"#636363\",\"#252525\"],\n6: [\"#f7f7f7\",\"#d9d9d9\",\"#bdbdbd\",\"#969696\",\"#636363\",\"#252525\"],\n7: [\"#f7f7f7\",\"#d9d9d9\",\"#bdbdbd\",\"#969696\",\"#737373\",\"#525252\",\"#252525\"],\n8: [\"#ffffff\",\"#f0f0f0\",\"#d9d9d9\",\"#bdbdbd\",\"#969696\",\"#737373\",\"#525252\",\"#252525\"],\n9: [\"#ffffff\",\"#f0f0f0\",\"#d9d9d9\",\"#bdbdbd\",\"#969696\",\"#737373\",\"#525252\",\"#252525\",\"#000000\"]\n},PuOr: {\n3: [\"#f1a340\",\"#f7f7f7\",\"#998ec3\"],\n4: [\"#e66101\",\"#fdb863\",\"#b2abd2\",\"#5e3c99\"],\n5: [\"#e66101\",\"#fdb863\",\"#f7f7f7\",\"#b2abd2\",\"#5e3c99\"],\n6: [\"#b35806\",\"#f1a340\",\"#fee0b6\",\"#d8daeb\",\"#998ec3\",\"#542788\"],\n7: [\"#b35806\",\"#f1a340\",\"#fee0b6\",\"#f7f7f7\",\"#d8daeb\",\"#998ec3\",\"#542788\"],\n8: [\"#b35806\",\"#e08214\",\"#fdb863\",\"#fee0b6\",\"#d8daeb\",\"#b2abd2\",\"#8073ac\",\"#542788\"],\n9: [\"#b35806\",\"#e08214\",\"#fdb863\",\"#fee0b6\",\"#f7f7f7\",\"#d8daeb\",\"#b2abd2\",\"#8073ac\",\"#542788\"],\n10: [\"#7f3b08\",\"#b35806\",\"#e08214\",\"#fdb863\",\"#fee0b6\",\"#d8daeb\",\"#b2abd2\",\"#8073ac\",\"#542788\",\"#2d004b\"],\n11: [\"#7f3b08\",\"#b35806\",\"#e08214\",\"#fdb863\",\"#fee0b6\",\"#f7f7f7\",\"#d8daeb\",\"#b2abd2\",\"#8073ac\",\"#542788\",\"#2d004b\"]\n},BrBG: {\n3: [\"#d8b365\",\"#f5f5f5\",\"#5ab4ac\"],\n4: [\"#a6611a\",\"#dfc27d\",\"#80cdc1\",\"#018571\"],\n5: [\"#a6611a\",\"#dfc27d\",\"#f5f5f5\",\"#80cdc1\",\"#018571\"],\n6: [\"#8c510a\",\"#d8b365\",\"#f6e8c3\",\"#c7eae5\",\"#5ab4ac\",\"#01665e\"],\n7: [\"#8c510a\",\"#d8b365\",\"#f6e8c3\",\"#f5f5f5\",\"#c7eae5\",\"#5ab4ac\",\"#01665e\"],\n8: [\"#8c510a\",\"#bf812d\",\"#dfc27d\",\"#f6e8c3\",\"#c7eae5\",\"#80cdc1\",\"#35978f\",\"#01665e\"],\n9: [\"#8c510a\",\"#bf812d\",\"#dfc27d\",\"#f6e8c3\",\"#f5f5f5\",\"#c7eae5\",\"#80cdc1\",\"#35978f\",\"#01665e\"],\n10: [\"#543005\",\"#8c510a\",\"#bf812d\",\"#dfc27d\",\"#f6e8c3\",\"#c7eae5\",\"#80cdc1\",\"#35978f\",\"#01665e\",\"#003c30\"],\n11: [\"#543005\",\"#8c510a\",\"#bf812d\",\"#dfc27d\",\"#f6e8c3\",\"#f5f5f5\",\"#c7eae5\",\"#80cdc1\",\"#35978f\",\"#01665e\",\"#003c30\"]\n},PRGn: {\n3: [\"#af8dc3\",\"#f7f7f7\",\"#7fbf7b\"],\n4: [\"#7b3294\",\"#c2a5cf\",\"#a6dba0\",\"#008837\"],\n5: [\"#7b3294\",\"#c2a5cf\",\"#f7f7f7\",\"#a6dba0\",\"#008837\"],\n6: [\"#762a83\",\"#af8dc3\",\"#e7d4e8\",\"#d9f0d3\",\"#7fbf7b\",\"#1b7837\"],\n7: [\"#762a83\",\"#af8dc3\",\"#e7d4e8\",\"#f7f7f7\",\"#d9f0d3\",\"#7fbf7b\",\"#1b7837\"],\n8: [\"#762a83\",\"#9970ab\",\"#c2a5cf\",\"#e7d4e8\",\"#d9f0d3\",\"#a6dba0\",\"#5aae61\",\"#1b7837\"],\n9: [\"#762a83\",\"#9970ab\",\"#c2a5cf\",\"#e7d4e8\",\"#f7f7f7\",\"#d9f0d3\",\"#a6dba0\",\"#5aae61\",\"#1b7837\"],\n10: [\"#40004b\",\"#762a83\",\"#9970ab\",\"#c2a5cf\",\"#e7d4e8\",\"#d9f0d3\",\"#a6dba0\",\"#5aae61\",\"#1b7837\",\"#00441b\"],\n11: [\"#40004b\",\"#762a83\",\"#9970ab\",\"#c2a5cf\",\"#e7d4e8\",\"#f7f7f7\",\"#d9f0d3\",\"#a6dba0\",\"#5aae61\",\"#1b7837\",\"#00441b\"]\n},PiYG: {\n3: [\"#e9a3c9\",\"#f7f7f7\",\"#a1d76a\"],\n4: [\"#d01c8b\",\"#f1b6da\",\"#b8e186\",\"#4dac26\"],\n5: [\"#d01c8b\",\"#f1b6da\",\"#f7f7f7\",\"#b8e186\",\"#4dac26\"],\n6: [\"#c51b7d\",\"#e9a3c9\",\"#fde0ef\",\"#e6f5d0\",\"#a1d76a\",\"#4d9221\"],\n7: [\"#c51b7d\",\"#e9a3c9\",\"#fde0ef\",\"#f7f7f7\",\"#e6f5d0\",\"#a1d76a\",\"#4d9221\"],\n8: [\"#c51b7d\",\"#de77ae\",\"#f1b6da\",\"#fde0ef\",\"#e6f5d0\",\"#b8e186\",\"#7fbc41\",\"#4d9221\"],\n9: [\"#c51b7d\",\"#de77ae\",\"#f1b6da\",\"#fde0ef\",\"#f7f7f7\",\"#e6f5d0\",\"#b8e186\",\"#7fbc41\",\"#4d9221\"],\n10: [\"#8e0152\",\"#c51b7d\",\"#de77ae\",\"#f1b6da\",\"#fde0ef\",\"#e6f5d0\",\"#b8e186\",\"#7fbc41\",\"#4d9221\",\"#276419\"],\n11: [\"#8e0152\",\"#c51b7d\",\"#de77ae\",\"#f1b6da\",\"#fde0ef\",\"#f7f7f7\",\"#e6f5d0\",\"#b8e186\",\"#7fbc41\",\"#4d9221\",\"#276419\"]\n},RdBu: {\n3: [\"#ef8a62\",\"#f7f7f7\",\"#67a9cf\"],\n4: [\"#ca0020\",\"#f4a582\",\"#92c5de\",\"#0571b0\"],\n5: [\"#ca0020\",\"#f4a582\",\"#f7f7f7\",\"#92c5de\",\"#0571b0\"],\n6: [\"#b2182b\",\"#ef8a62\",\"#fddbc7\",\"#d1e5f0\",\"#67a9cf\",\"#2166ac\"],\n7: [\"#b2182b\",\"#ef8a62\",\"#fddbc7\",\"#f7f7f7\",\"#d1e5f0\",\"#67a9cf\",\"#2166ac\"],\n8: [\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#d1e5f0\",\"#92c5de\",\"#4393c3\",\"#2166ac\"],\n9: [\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#f7f7f7\",\"#d1e5f0\",\"#92c5de\",\"#4393c3\",\"#2166ac\"],\n10: [\"#67001f\",\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#d1e5f0\",\"#92c5de\",\"#4393c3\",\"#2166ac\",\"#053061\"],\n11: [\"#67001f\",\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#f7f7f7\",\"#d1e5f0\",\"#92c5de\",\"#4393c3\",\"#2166ac\",\"#053061\"]\n},RdGy: {\n3: [\"#ef8a62\",\"#ffffff\",\"#999999\"],\n4: [\"#ca0020\",\"#f4a582\",\"#bababa\",\"#404040\"],\n5: [\"#ca0020\",\"#f4a582\",\"#ffffff\",\"#bababa\",\"#404040\"],\n6: [\"#b2182b\",\"#ef8a62\",\"#fddbc7\",\"#e0e0e0\",\"#999999\",\"#4d4d4d\"],\n7: [\"#b2182b\",\"#ef8a62\",\"#fddbc7\",\"#ffffff\",\"#e0e0e0\",\"#999999\",\"#4d4d4d\"],\n8: [\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#e0e0e0\",\"#bababa\",\"#878787\",\"#4d4d4d\"],\n9: [\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#ffffff\",\"#e0e0e0\",\"#bababa\",\"#878787\",\"#4d4d4d\"],\n10: [\"#67001f\",\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#e0e0e0\",\"#bababa\",\"#878787\",\"#4d4d4d\",\"#1a1a1a\"],\n11: [\"#67001f\",\"#b2182b\",\"#d6604d\",\"#f4a582\",\"#fddbc7\",\"#ffffff\",\"#e0e0e0\",\"#bababa\",\"#878787\",\"#4d4d4d\",\"#1a1a1a\"]\n},RdYlBu: {\n3: [\"#fc8d59\",\"#ffffbf\",\"#91bfdb\"],\n4: [\"#d7191c\",\"#fdae61\",\"#abd9e9\",\"#2c7bb6\"],\n5: [\"#d7191c\",\"#fdae61\",\"#ffffbf\",\"#abd9e9\",\"#2c7bb6\"],\n6: [\"#d73027\",\"#fc8d59\",\"#fee090\",\"#e0f3f8\",\"#91bfdb\",\"#4575b4\"],\n7: [\"#d73027\",\"#fc8d59\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#91bfdb\",\"#4575b4\"],\n8: [\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\"],\n9: [\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\"],\n10: [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"],\n11: [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"]\n},Spectral: {\n3: [\"#fc8d59\",\"#ffffbf\",\"#99d594\"],\n4: [\"#d7191c\",\"#fdae61\",\"#abdda4\",\"#2b83ba\"],\n5: [\"#d7191c\",\"#fdae61\",\"#ffffbf\",\"#abdda4\",\"#2b83ba\"],\n6: [\"#d53e4f\",\"#fc8d59\",\"#fee08b\",\"#e6f598\",\"#99d594\",\"#3288bd\"],\n7: [\"#d53e4f\",\"#fc8d59\",\"#fee08b\",\"#ffffbf\",\"#e6f598\",\"#99d594\",\"#3288bd\"],\n8: [\"#d53e4f\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#e6f598\",\"#abdda4\",\"#66c2a5\",\"#3288bd\"],\n9: [\"#d53e4f\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#ffffbf\",\"#e6f598\",\"#abdda4\",\"#66c2a5\",\"#3288bd\"],\n10: [\"#9e0142\",\"#d53e4f\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#e6f598\",\"#abdda4\",\"#66c2a5\",\"#3288bd\",\"#5e4fa2\"],\n11: [\"#9e0142\",\"#d53e4f\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#ffffbf\",\"#e6f598\",\"#abdda4\",\"#66c2a5\",\"#3288bd\",\"#5e4fa2\"]\n},RdYlGn: {\n3: [\"#fc8d59\",\"#ffffbf\",\"#91cf60\"],\n4: [\"#d7191c\",\"#fdae61\",\"#a6d96a\",\"#1a9641\"],\n5: [\"#d7191c\",\"#fdae61\",\"#ffffbf\",\"#a6d96a\",\"#1a9641\"],\n6: [\"#d73027\",\"#fc8d59\",\"#fee08b\",\"#d9ef8b\",\"#91cf60\",\"#1a9850\"],\n7: [\"#d73027\",\"#fc8d59\",\"#fee08b\",\"#ffffbf\",\"#d9ef8b\",\"#91cf60\",\"#1a9850\"],\n8: [\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#d9ef8b\",\"#a6d96a\",\"#66bd63\",\"#1a9850\"],\n9: [\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#ffffbf\",\"#d9ef8b\",\"#a6d96a\",\"#66bd63\",\"#1a9850\"],\n10: [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#d9ef8b\",\"#a6d96a\",\"#66bd63\",\"#1a9850\",\"#006837\"],\n11: [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee08b\",\"#ffffbf\",\"#d9ef8b\",\"#a6d96a\",\"#66bd63\",\"#1a9850\",\"#006837\"]\n},Accent: {\n3: [\"#7fc97f\",\"#beaed4\",\"#fdc086\"],\n4: [\"#7fc97f\",\"#beaed4\",\"#fdc086\",\"#ffff99\"],\n5: [\"#7fc97f\",\"#beaed4\",\"#fdc086\",\"#ffff99\",\"#386cb0\"],\n6: [\"#7fc97f\",\"#beaed4\",\"#fdc086\",\"#ffff99\",\"#386cb0\",\"#f0027f\"],\n7: [\"#7fc97f\",\"#beaed4\",\"#fdc086\",\"#ffff99\",\"#386cb0\",\"#f0027f\",\"#bf5b17\"],\n8: [\"#7fc97f\",\"#beaed4\",\"#fdc086\",\"#ffff99\",\"#386cb0\",\"#f0027f\",\"#bf5b17\",\"#666666\"]\n},Dark2: {\n3: [\"#1b9e77\",\"#d95f02\",\"#7570b3\"],\n4: [\"#1b9e77\",\"#d95f02\",\"#7570b3\",\"#e7298a\"],\n5: [\"#1b9e77\",\"#d95f02\",\"#7570b3\",\"#e7298a\",\"#66a61e\"],\n6: [\"#1b9e77\",\"#d95f02\",\"#7570b3\",\"#e7298a\",\"#66a61e\",\"#e6ab02\"],\n7: [\"#1b9e77\",\"#d95f02\",\"#7570b3\",\"#e7298a\",\"#66a61e\",\"#e6ab02\",\"#a6761d\"],\n8: [\"#1b9e77\",\"#d95f02\",\"#7570b3\",\"#e7298a\",\"#66a61e\",\"#e6ab02\",\"#a6761d\",\"#666666\"]\n},Paired: {\n3: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\"],\n4: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\"],\n5: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\"],\n6: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\"],\n7: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\"],\n8: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\",\"#ff7f00\"],\n9: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\",\"#ff7f00\",\"#cab2d6\"],\n10: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\",\"#ff7f00\",\"#cab2d6\",\"#6a3d9a\"],\n11: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\",\"#ff7f00\",\"#cab2d6\",\"#6a3d9a\",\"#ffff99\"],\n12: [\"#a6cee3\",\"#1f78b4\",\"#b2df8a\",\"#33a02c\",\"#fb9a99\",\"#e31a1c\",\"#fdbf6f\",\"#ff7f00\",\"#cab2d6\",\"#6a3d9a\",\"#ffff99\",\"#b15928\"]\n},Pastel1: {\n3: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\"],\n4: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\"],\n5: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\",\"#fed9a6\"],\n6: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\",\"#fed9a6\",\"#ffffcc\"],\n7: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\",\"#fed9a6\",\"#ffffcc\",\"#e5d8bd\"],\n8: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\",\"#fed9a6\",\"#ffffcc\",\"#e5d8bd\",\"#fddaec\"],\n9: [\"#fbb4ae\",\"#b3cde3\",\"#ccebc5\",\"#decbe4\",\"#fed9a6\",\"#ffffcc\",\"#e5d8bd\",\"#fddaec\",\"#f2f2f2\"]\n},Pastel2: {\n3: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\"],\n4: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\",\"#f4cae4\"],\n5: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\",\"#f4cae4\",\"#e6f5c9\"],\n6: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\",\"#f4cae4\",\"#e6f5c9\",\"#fff2ae\"],\n7: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\",\"#f4cae4\",\"#e6f5c9\",\"#fff2ae\",\"#f1e2cc\"],\n8: [\"#b3e2cd\",\"#fdcdac\",\"#cbd5e8\",\"#f4cae4\",\"#e6f5c9\",\"#fff2ae\",\"#f1e2cc\",\"#cccccc\"]\n},Set1: {\n3: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\"],\n4: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\"],\n5: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\",\"#ff7f00\"],\n6: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\",\"#ff7f00\",\"#ffff33\"],\n7: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\",\"#ff7f00\",\"#ffff33\",\"#a65628\"],\n8: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\",\"#ff7f00\",\"#ffff33\",\"#a65628\",\"#f781bf\"],\n9: [\"#e41a1c\",\"#377eb8\",\"#4daf4a\",\"#984ea3\",\"#ff7f00\",\"#ffff33\",\"#a65628\",\"#f781bf\",\"#999999\"]\n},Set2: {\n3: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\"],\n4: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\",\"#e78ac3\"],\n5: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\",\"#e78ac3\",\"#a6d854\"],\n6: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\",\"#e78ac3\",\"#a6d854\",\"#ffd92f\"],\n7: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\",\"#e78ac3\",\"#a6d854\",\"#ffd92f\",\"#e5c494\"],\n8: [\"#66c2a5\",\"#fc8d62\",\"#8da0cb\",\"#e78ac3\",\"#a6d854\",\"#ffd92f\",\"#e5c494\",\"#b3b3b3\"]\n},Set3: {\n3: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\"],\n4: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\"],\n5: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\"],\n6: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\"],\n7: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\"],\n8: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\",\"#fccde5\"],\n9: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\",\"#fccde5\",\"#d9d9d9\"],\n10: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\",\"#fccde5\",\"#d9d9d9\",\"#bc80bd\"],\n11: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\",\"#fccde5\",\"#d9d9d9\",\"#bc80bd\",\"#ccebc5\"],\n12: [\"#8dd3c7\",\"#ffffb3\",\"#bebada\",\"#fb8072\",\"#80b1d3\",\"#fdb462\",\"#b3de69\",\"#fccde5\",\"#d9d9d9\",\"#bc80bd\",\"#ccebc5\",\"#ffed6f\"]\n}};\n"
  },
  {
    "path": "examples/lib/stream_layers.js",
    "content": "\n/* Inspired by Lee Byron's test data generator. */\nfunction stream_layers(n, m, o) {\n  if (arguments.length < 3) o = 0;\n  function bump(a) {\n    var x = 1 / (.1 + Math.random()),\n        y = 2 * Math.random() - .5,\n        z = 10 / (.1 + Math.random());\n    for (var i = 0; i < m; i++) {\n      var w = (i / m - y) * z;\n      a[i] += x * Math.exp(-w * w);\n    }\n  }\n  return d3.range(n).map(function() {\n      var a = [], i;\n      for (i = 0; i < m; i++) a[i] = o + o * Math.random();\n      for (i = 0; i < 5; i++) bump(a);\n      return a.map(stream_index);\n    });\n}\n\n/* Another layer generator using gamma distributions. */\nfunction stream_waves(n, m) {\n  return d3.range(n).map(function(i) {\n    return d3.range(m).map(function(j) {\n        var x = 20 * j / m - i / 3;\n        return 2 * x * Math.exp(-.5 * x);\n      }).map(stream_index);\n    });\n}\n\nfunction stream_index(d, i) {\n  return {x: i, y: Math.max(0, d)};\n}\n\n"
  },
  {
    "path": "examples/line.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<svg id=\"test1\"></svg>\n\n<script>\n\n    nv.addGraph({\n        generate: function() {\n            var width = nv.utils.windowSize().width - 40,\n                height = nv.utils.windowSize().height - 40;\n\n            var chart = nv.models.line()\n                .width(width)\n                .height(height)\n                .margin({top: 20, right: 20, bottom: 20, left: 20});\n\n            chart.dispatch.on('renderEnd', function(){\n                console.log('render complete');\n            });\n\n            d3.select('#test1')\n                .attr('width', width)\n                .attr('height', height)\n                .datum(sinAndCos())\n                .call(chart);\n\n            return chart;\n        },\n        callback: function(graph) {\n            window.onresize = function() {\n                var width = nv.utils.windowSize().width - 40,\n                    height = nv.utils.windowSize().height - 40,\n                    margin = graph.margin();\n\n                if (width < margin.left + margin.right + 20)\n                    width = margin.left + margin.right + 20;\n\n                if (height < margin.top + margin.bottom + 20)\n                    height = margin.top + margin.bottom + 20;\n\n                graph.width(width).height(height);\n\n                d3.select('#test1')\n                    .attr('width', width)\n                    .attr('height', height)\n                    .call(graph);\n            };\n        }\n    });\n\n    function sinAndCos() {\n        var sin = [],\n            cos = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10)});\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n        }\n\n        return [\n            {\n                values: sin,\n                key: \"Sine Wave\",\n                color: \"#ff7f0e\"\n            },\n            {\n                values: cos,\n                key: \"Cosine Wave\",\n                color: \"#2ca02c\",\n                strokeWidth: 3\n            }\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/lineChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n        .dashed {\n            stroke-dasharray: 5,5;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n<div style=\"position:absolute; top: 0; left: 0;\">\n    <button onclick=\"randomizeFillOpacity();\">Randomize fill opacity</button>\n    <button onclick=\"expandLegend();\">Expand/Contract Legend</button>\n    <button onclick=\"toggleLegend();\">Toggle Legend Top/Bottom</button>\n\n    <script>\n        var expandLegend = function() {\n            var exp = chart.legend.expanded();\n            chart.legend.expanded(!exp);\n            chart.update();\n        }\n    </script>\n</div>\n<div id=\"chart1\"></div>\n\n<script>\n    // Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required\n    var chart;\n    var data;\n    var legendPosition = \"top\";\n\n    var randomizeFillOpacity = function() {\n        var rand = Math.random(0,1);\n        for (var i = 0; i < 100; i++) { // modify sine amplitude\n            data[4].values[i].y = Math.sin(i/(5 + rand)) * .4 * rand - .25;\n        }\n        data[4].fillOpacity = rand;\n        chart.update();\n    };\n\n    var toggleLegend = function() {\n        if (legendPosition == \"top\") {\n            legendPosition = \"bottom\";\n        } else {\n            legendPosition = \"top\";\n        }\n        chart.legendPosition(legendPosition);\n        chart.update();\n    };\n\n    nv.addGraph(function() {\n        chart = nv.models.lineChart()\n            .options({\n                duration: 300,\n                useInteractiveGuideline: true\n            })\n        ;\n\n        // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        chart.xAxis\n            .axisLabel(\"Time (s)\")\n            .tickFormat(d3.format(',.1f'))\n            .staggerLabels(true)\n        ;\n\n        chart.yAxis\n            .axisLabel('Voltage (v)')\n            .tickFormat(function(d) {\n                if (d == null) {\n                    return 'N/A';\n                }\n                return d3.format(',.2f')(d);\n            })\n        ;\n\n        data = sinAndCos();\n\n        d3.select('#chart1').append('svg')\n            .datum(data)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function sinAndCos() {\n        var sin = [],\n            sin2 = [],\n            cos = [],\n            rand = [],\n            rand2 = []\n            ;\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works\n            sin2.push({x: i, y: Math.sin(i/5) * 0.4 - 0.25});\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n            rand.push({x:i, y: Math.random() / 10});\n            rand2.push({x: i, y: Math.cos(i/10) + Math.random() / 10 })\n        }\n\n        return [\n            {\n                area: true,\n                values: sin,\n                key: \"Sine Wave\",\n                color: \"#ff7f0e\",\n                strokeWidth: 4,\n                classed: 'dashed'\n            },\n            {\n                values: cos,\n                key: \"Cosine Wave\",\n                color: \"#2ca02c\"\n            },\n            {\n                values: rand,\n                key: \"Random Points\",\n                color: \"#2222ff\"\n            },\n            {\n                values: rand2,\n                key: \"Random Cosine\",\n                color: \"#667711\",\n                strokeWidth: 3.5\n            },\n            {\n                area: true,\n                values: sin2,\n                key: \"Fill opacity\",\n                color: \"#EF9CFB\",\n                fillOpacity: .1\n            }\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/lineChartLogScale.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n        .dashed {\n            stroke-dasharray: 5,5;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n<div id=\"chart1\"></div>\n\n<script>\n    // Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required\n    var chart;\n    var data;\n\n  \n    nv.addGraph(function() {\n        chart = nv.models.lineChart()\n            .x(function (d) { return d.x; })\n            .options({\n                showLegend: true,\n                showYAxis: true,\n                showXAxis: true,\n                useInteractiveGuideline: true\n            });\n\n        data = GenerateData();\n        \n        chart.xAxis\n            .axisLabel(\"x axis\")\n            .tickFormat(d3.format('0.2f'));\n\n        chart.yScale( d3.scale.log());\n        chart.yAxis\n            .axisLabel(\"Log axis\")\n            .tickFormat( d3.format('.4e'));\n\n        d3.select('#chart1').append('svg')\n            .datum(data)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function GenerateData() {\n        var sin = [],\n            sin2 = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.abs(i % 10 == 5 ? null : Math.sin(i/10) )}); //the nulls are to show how defined works\n            sin2.push({x: i, y: Math.abs(Math.sin(i/5) * 0.4 - 0.25)});\n        }\n\n        return [\n            {\n                area: true,\n                values: sin,\n                key: \"l1\",\n                color: \"#ff7f0e\",\n                strokeWidth: 4,\n                classed: 'dashed'\n            },\n            {\n                values: sin2,\n                key: \"l2\",\n                color: \"#2ca02c\"\n            }\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/lineChartSVGResize.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n        #chartZoom {\n            position: absolute;\n            top: 0;\n            left: 0;\n        }\n    </style>\n</head>\n<body>\n<div id=\"chartZoom\">\n    <a href=\"#\" id=\"zoomIn\">Zoom In</a> <a href=\"#\" id=\"zoomOut\">Zoom Out</a>\n</div>\n\n<div id=\"chart1\" class='with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    nv.addGraph(function() {\n        var chart = nv.models.lineChart();\n        var fitScreen = false;\n        var width = 600;\n        var height = 300;\n        var zoom = 1;\n\n        chart.useInteractiveGuideline(true);\n        chart.xAxis\n            .tickFormat(d3.format(',r'));\n\n        chart.lines.dispatch.on(\"elementClick\", function(evt) {\n            console.log(evt);\n        });\n\n        chart.yAxis\n            .axisLabel('Voltage (v)')\n            .tickFormat(d3.format(',.2f'));\n\n        d3.select('#chart1 svg')\n            .attr('perserveAspectRatio', 'xMinYMid')\n            .attr('width', width)\n            .attr('height', height)\n            .datum(sinAndCos());\n\n        setChartViewBox();\n        resizeChart();\n\n        nv.utils.windowResize(resizeChart);\n\n        d3.select('#zoomIn').on('click', zoomIn);\n        d3.select('#zoomOut').on('click', zoomOut);\n\n\n        function setChartViewBox() {\n            var w = width * zoom,\n                h = height * zoom;\n\n            chart\n                .width(w)\n                .height(h);\n\n            d3.select('#chart1 svg')\n                .attr('viewBox', '0 0 ' + w + ' ' + h)\n                .transition().duration(500)\n                .call(chart);\n        }\n\n        function zoomOut() {\n            zoom += .25;\n            setChartViewBox();\n        }\n\n        function zoomIn() {\n            if (zoom <= .5) return;\n            zoom -= .25;\n            setChartViewBox();\n        }\n\n        // This resize simply sets the SVG's dimensions, without a need to recall the chart code\n        // Resizing because of the viewbox and perserveAspectRatio settings\n        // This scales the interior of the chart unlike the above\n        function resizeChart() {\n            var container = d3.select('#chart1');\n            var svg = container.select('svg');\n\n            if (fitScreen) {\n                // resize based on container's width AND HEIGHT\n                var windowSize = nv.utils.windowSize();\n                svg.attr(\"width\", windowSize.width);\n                svg.attr(\"height\", windowSize.height);\n            } else {\n                // resize based on container's width\n                var aspect = chart.width() / chart.height();\n                var targetWidth = parseInt(container.style('width'));\n                svg.attr(\"width\", targetWidth);\n                svg.attr(\"height\", Math.round(targetWidth / aspect));\n            }\n        }\n        return chart;\n    });\n\n    function sinAndCos() {\n        var sin = [],\n            cos = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10) });\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n        }\n\n        return [\n            {\n                values: sin,\n                key: \"Sine Wave\",\n                color: \"#ff7f0e\"\n            },\n            {\n                values: cos,\n                key: \"Cosine Wave\",\n                color: \"#2ca02c\"\n            }\n        ];\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/linePlusBarChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n        button {\n            margin: 2px;\n            margin-left: 80px;\n        }\n    </style>\n</head>\n<body>\n<div style=\"position:absolute; top: 0; left: 0;\">\n    <button onclick=\"chart.switchYAxisOrder(!chart.switchYAxisOrder()); chart.update();\">toggle axis</button>\n    <button onclick=\"chart.focusEnable(!chart.focusEnable()); chart.update();\">toggle focus</button>\n    <span style=\"color: #C60;\">&lt;-- turn focus on or off!</span>\n</div>\n<div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg> </svg>\n</div>\n\n<script>\n\n    var testdata = [\n        {\n            \"key\" : \"Quantity\" ,\n            \"bar\": true,\n            \"values\" : [ [ 1136005200000 , 1271000.0] , [ 1138683600000 , 1271000.0] , [ 1141102800000 , 1271000.0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 3899486.0] , [ 1162270800000 , 3899486.0] , [ 1164862800000 , 3899486.0] , [ 1167541200000 , 3564700.0] , [ 1170219600000 , 3564700.0] , [ 1172638800000 , 3564700.0] , [ 1175313600000 , 2648493.0] , [ 1177905600000 , 2648493.0] , [ 1180584000000 , 2648493.0] , [ 1183176000000 , 2522993.0] , [ 1185854400000 , 2522993.0] , [ 1188532800000 , 2522993.0] , [ 1191124800000 , 2906501.0] , [ 1193803200000 , 2906501.0] , [ 1196398800000 , 2906501.0] , [ 1199077200000 , 2206761.0] , [ 1201755600000 , 2206761.0] , [ 1204261200000 , 2206761.0] , [ 1206936000000 , 2287726.0] , [ 1209528000000 , 2287726.0] , [ 1212206400000 , 2287726.0] , [ 1214798400000 , 2732646.0] , [ 1217476800000 , 2732646.0] , [ 1220155200000 , 2732646.0] , [ 1222747200000 , 2599196.0] , [ 1225425600000 , 2599196.0] , [ 1228021200000 , 2599196.0] , [ 1230699600000 , 1924387.0] , [ 1233378000000 , 1924387.0] , [ 1235797200000 , 1924387.0] , [ 1238472000000 , 1756311.0] , [ 1241064000000 , 1756311.0] , [ 1243742400000 , 1756311.0] , [ 1246334400000 , 1743470.0] , [ 1249012800000 , 1743470.0] , [ 1251691200000 , 1743470.0] , [ 1254283200000 , 1519010.0] , [ 1256961600000 , 1519010.0] , [ 1259557200000 , 1519010.0] , [ 1262235600000 , 1591444.0] , [ 1264914000000 , 1591444.0] , [ 1267333200000 , 1591444.0] , [ 1270008000000 , 1543784.0] , [ 1272600000000 , 1543784.0] , [ 1275278400000 , 1543784.0] , [ 1277870400000 , 1309915.0] , [ 1280548800000 , 1309915.0] , [ 1283227200000 , 1309915.0] , [ 1285819200000 , 1331875.0] , [ 1288497600000 , 1331875.0] , [ 1291093200000 , 1331875.0] , [ 1293771600000 , 1331875.0] , [ 1296450000000 , 1154695.0] , [ 1298869200000 , 1154695.0] , [ 1301544000000 , 1194025.0] , [ 1304136000000 , 1194025.0] , [ 1306814400000 , 1194025.0] , [ 1309406400000 , 1194025.0] , [ 1312084800000 , 1194025.0] , [ 1314763200000 , 1244525.0] , [ 1317355200000 , 475000.0] , [ 1320033600000 , 475000.0] , [ 1322629200000 , 475000.0] , [ 1325307600000 , 690033.0] , [ 1327986000000 , 690033.0] , [ 1330491600000 , 690033.0] , [ 1333166400000 , 514733.0] , [ 1335758400000 , 514733.0]]\n        },\n        {\n            \"key\" : \"Price\" ,\n            \"values\" : [ [ 1136005200000 , 71.89] , [ 1138683600000 , 75.51] , [ 1141102800000 , 68.49] , [ 1143781200000 , 62.72] , [ 1146369600000 , 70.39] , [ 1149048000000 , 59.77] , [ 1151640000000 , 57.27] , [ 1154318400000 , 67.96] , [ 1156996800000 , 67.85] , [ 1159588800000 , 76.98] , [ 1162270800000 , 81.08] , [ 1164862800000 , 91.66] , [ 1167541200000 , 84.84] , [ 1170219600000 , 85.73] , [ 1172638800000 , 84.61] , [ 1175313600000 , 92.91] , [ 1177905600000 , 99.8] , [ 1180584000000 , 121.191] , [ 1183176000000 , 122.04] , [ 1185854400000 , 131.76] , [ 1188532800000 , 138.48] , [ 1191124800000 , 153.47] , [ 1193803200000 , 189.95] , [ 1196398800000 , 182.22] , [ 1199077200000 , 198.08] , [ 1201755600000 , 135.36] , [ 1204261200000 , 125.02] , [ 1206936000000 , 143.5] , [ 1209528000000 , 173.95] , [ 1212206400000 , 188.75] , [ 1214798400000 , 167.44] , [ 1217476800000 , 158.95] , [ 1220155200000 , 169.53] , [ 1222747200000 , 113.66] , [ 1225425600000 , 107.59] , [ 1228021200000 , 92.67] , [ 1230699600000 , 85.35] , [ 1233378000000 , 90.13] , [ 1235797200000 , 89.31] , [ 1238472000000 , 105.12] , [ 1241064000000 , 125.83] , [ 1243742400000 , 135.81] , [ 1246334400000 , 142.43] , [ 1249012800000 , 163.39] , [ 1251691200000 , 168.21] , [ 1254283200000 , 185.35] , [ 1256961600000 , 188.5] , [ 1259557200000 , 199.91] , [ 1262235600000 , 210.732] , [ 1264914000000 , 192.063] , [ 1267333200000 , 204.62] , [ 1270008000000 , 235.0] , [ 1272600000000 , 261.09] , [ 1275278400000 , 256.88] , [ 1277870400000 , 251.53] , [ 1280548800000 , 257.25] , [ 1283227200000 , 243.1] , [ 1285819200000 , 283.75] , [ 1288497600000 , 300.98] , [ 1291093200000 , 311.15] , [ 1293771600000 , 322.56] , [ 1296450000000 , 339.32] , [ 1298869200000 , 353.21] , [ 1301544000000 , 348.5075] , [ 1304136000000 , 350.13] , [ 1306814400000 , 347.83] , [ 1309406400000 , 335.67] , [ 1312084800000 , 390.48] , [ 1314763200000 , 384.83] , [ 1317355200000 , 381.32] , [ 1320033600000 , 404.78] , [ 1322629200000 , 382.2] , [ 1325307600000 , 405.0] , [ 1327986000000 , 456.48] , [ 1330491600000 , 542.44] , [ 1333166400000 , 599.55] , [ 1335758400000 , 583.98] ]\n        }\n    ].map(function(series) {\n            series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });\n            return series;\n        });\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.linePlusBarChart()\n            .margin({top: 50, right: 80, bottom: 30, left: 80})\n            .legendRightAxisHint(' [Using Right Axis]')\n            .color(d3.scale.category10().range());\n\n        chart.xAxis.tickFormat(function(d) {\n            return d3.time.format('%x')(new Date(d))\n        }).showMaxMin(false);\n\n        chart.y2Axis.tickFormat(function(d) { return '$' + d3.format(',f')(d) });\n        chart.bars.forceY([0]).padData(false);\n\n        chart.x2Axis.tickFormat(function(d) {\n            return d3.time.format('%x')(new Date(d))\n        }).showMaxMin(false);\n\n        d3.select('#chart1 svg')\n            .datum(testdata)\n            .transition().duration(500).call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n        return chart;\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/lineWithFocusChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    nv.addGraph(function() {\n        var chart = nv.models.lineWithFocusChart();\n\n        chart.brushExtent([50,70]);\n\n        chart.xAxis.tickFormat(d3.format(',f')).axisLabel(\"Stream - 3,128,.1\");\n        chart.x2Axis.tickFormat(d3.format(',f'));\n\n        chart.yTickFormat(d3.format(',.2f'));\n\n        chart.useInteractiveGuideline(true);\n\n        d3.select('#chart svg')\n            .datum(testData())\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function testData() {\n        return stream_layers(3,128,.1).map(function(data, i) {\n            return {\n                key: 'Stream' + i,\n                area: i === 1,\n                values: data\n            };\n        });\n    }\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/lineWithFocusChart_x2AxisLabel.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    nv.addGraph(function() {\n        var chart = nv.models.lineWithFocusChart();\n\n        chart.brushExtent([50,70]);\n\n        chart.xAxis.tickFormat(d3.format(',f'));\n        chart.focusHeight(50 + 20);\n        chart.focusMargin({ \"bottom\": 20 + 20 });\n        chart.x2Axis.tickFormat(d3.format(',f')).axisLabel(\"Stream - 3,128,.1\");\n        chart.yAxis.tickFormat(d3.format(',.2f'));\n        chart.y2Axis.tickFormat(d3.format(',.2f'));\n        chart.useInteractiveGuideline(true);\n\n        d3.select('#chart svg')\n            .datum(testData())\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function testData() {\n        return stream_layers(3,128,.1).map(function(data, i) {\n            return {\n                key: 'Stream' + i,\n                area: i === 1,\n                values: data\n            };\n        });\n    }\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/monitoringChart.html",
    "content": "﻿<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n        <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n        <script src=\"../build/nv.d3.js\"></script>\n        <script src=\"lib/stream_layers.js\"></script>\n        <style>\n            text\n            {\n                font: 12px sans-serif;\n            }\n        \n            svg\n            {\n                display: block;\n                float: left;\n                height: 350px !important;\n                width: 350px !important;\n            }\n        \n            html, body\n            {\n                margin: 0px;\n                padding: 0px;\n                height: 100%;\n                width: 100%;\n            }\n        \n            .nvd3.nv-pie.nv-chart-donut2 .nv-pie-title\n            {\n                fill: gray;\n            }\n        \n            .nvd3.nv-pie.nv-chart-donut1 .nv-pie-title\n            {\n                opacity: 0.4;\n                fill: green;\n            }\n        </style>\n    </head>\n    \n    <body class='with-3d-shadow with-transitions'>\n    <svg id=\"test1\" class=\"mypiechart\"></svg>\n    <svg id=\"test2\" class=\"mypiechart\"></svg>\n    <svg id=\"test3\" class=\"mypiechart\"></svg>\n    <script>\n\n        var testdata1 = [\n        { key: \"Updated\", y: 0 },\n        { key: \"Pending\", y: 100 }\n    ];\n\n        var arcRadius1 = [\n\t\t{ inner: 0.6, outer: 1 },\n\t\t{ inner: 0.65, outer: 0.95 }\n\t];\n\n        var colors = [\"green\", \"gray\"];\n\n        var testdata2 = [\n        { key: \"One\", y: 1 },\n        { key: \"Two\", y: 1 },\n        { key: \"Three\", y: 1 },\n        { key: \"Four\", y: 1 },\n        { key: \"Five\", y: 1 },\n        { key: \"Six\", y: 1 },\n        { key: \"Seven\", y: 1 }\n    ];\n\n        var arcRadius2 = [\n\t\t{ inner: 0.9, outer: 1 },\n\t\t{ inner: 0.8, outer: 1 },\n\t\t{ inner: 0.7, outer: 1 },\n\t\t{ inner: 0.6, outer: 1 },\n\t\t{ inner: 0.5, outer: 1 },\n\t\t{ inner: 0.4, outer: 1 },\n\t\t{ inner: 0.3, outer: 1 }\n\t];\n\n        var testdata3 = [\n        { key: \"Updated\", y: 80 },\n        { key: \"Pending\", y: 20 }\n    ];\n\n        var arcRadius3 = [\n\t\t{ inner: 0, outer: 1 },\n\t\t{ inner: 0, outer: 0.8 }\n\t];\n\n        var height = 350;\n        var width = 350;\n\n        nv.addGraph(function () {\n            var chart = nv.models.pieChart()\n            .x(function (d) { return d.key })\n            .y(function (d) { return d.y })\n            .donut(true)\n\t\t\t.showLabels(false)\n\t\t\t.color(colors)\n            .width(width)\n            .height(height)\n\t\t\t.growOnHover(false)\n\t\t\t.arcsRadius(arcRadius1)\n            .id('donut1'); // allow custom CSS for this one svg\n\n            chart.title(\"0%\");\n\n            d3.select(\"#test1\")\n            .datum(testdata1)\n            .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n            // update chart data values randomly\n            setInterval(function () {\n                if (testdata1[0].y < 100) {\n                    testdata1[0].y = testdata1[0].y + 1;\n                    testdata1[1].y = testdata1[1].y - 1;\n                }\n                else {\n                    testdata1[0].y = 0;\n                    testdata1[1].y = 100;\n                }\n                chart.title(testdata1[0].y + \"%\");\n                chart.update();\n            }, 4000);\n\n            return chart;\n\n        });\n\n        nv.addGraph(function () {\n            var chart = nv.models.pieChart()\n            .x(function (d) { return d.key })\n            .y(function (d) { return d.y })\n            .donut(true)\n            .width(width)\n            .height(height)\n\t\t\t.arcsRadius(arcRadius2)\n\t\t\t.labelsOutside(true)\n\t\t\t.labelSunbeamLayout(true)\n            .id('donut2'); // allow custom CSS for this one svg\n\n            d3.select(\"#test2\")\n            .datum(testdata2)\n            .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n            return chart;\n\n        });\n\n        nv.addGraph(function () {\n            var chart = nv.models.pieChart()\n            .x(function (d) { return d.key })\n            .y(function (d) { return d.y })\n            .donut(true)\n\t\t\t.showLabels(true)\n            .width(width)\n            .height(height)\n\t\t\t.arcsRadius(arcRadius3)\n\t\t\t.labelsOutside(true)\n            .id('donut3'); // allow custom CSS for this one svg\n\n            d3.select(\"#test3\")\n            .datum(testdata3)\n            .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n            return chart;\n\n        });\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/multiBarChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    var test_data = stream_layers(3,10+Math.random()*100,.1).map(function(data, i) {\n        return {\n            key: 'Stream' + i,\n            values: data\n        };\n    });\n\n    console.log('td',test_data);\n\n    var negative_test_data = new d3.range(0,3).map(function(d,i) {\n        return {\n            key: 'Stream' + i,\n            values: new d3.range(0,11).map( function(f,j) {\n                return {\n                    y: 10 + Math.random()*100 * (Math.floor(Math.random()*100)%2 ? 1 : -1),\n                    x: j\n                }\n            })\n        };\n    });\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.multiBarChart()\n            .barColor(d3.scale.category20().range())\n            .duration(300)\n            .margin({bottom: 100, left: 70})\n            .rotateLabels(45)\n            .groupSpacing(0.1)\n        ;\n\n        chart.reduceXTicks(false).staggerLabels(true);\n\n        chart.xAxis\n            .axisLabel(\"ID of Furry Cat Households\")\n            .axisLabelDistance(35)\n            .showMaxMin(false)\n            .tickFormat(d3.format(',.6f'))\n        ;\n\n        chart.yAxis\n            .axisLabel(\"Change in Furry Cat Population\")\n            .axisLabelDistance(-5)\n            .tickFormat(d3.format(',.01f'))\n        ;\n\n        chart.dispatch.on('renderEnd', function(){\n            nv.log('Render Complete');\n        });\n\n        d3.select('#chart1 svg')\n            .datum(negative_test_data)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        chart.dispatch.on('stateChange', function(e) {\n            nv.log('New State:', JSON.stringify(e));\n        });\n        chart.state.dispatch.on('change', function(state){\n            nv.log('state', JSON.stringify(state));\n        });\n\n        return chart;\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/multiBarChart2.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #test1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"test1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    //var test_data = stream_layers(3,128,.1).map(function(data, i) {\n    var test_data = stream_layers(3,128,.1).map(function(data, i) {\n        return {\n            key: (i == 1) ? 'Non-stackable Stream' + i: 'Stream' + i,\n            nonStackable: (i == 1),\n            values: data\n        };\n    });\n    nv.addGraph({\n        generate: function() {\n            var width = nv.utils.windowSize().width,\n                height = nv.utils.windowSize().height;\n\n            var chart = nv.models.multiBarChart()\n                .width(width)\n                .height(height)\n                .stacked(true)\n                ;\n\n            chart.dispatch.on('renderEnd', function(){\n                console.log('Render Complete');\n            });\n\n            var svg = d3.select('#test1 svg').datum(test_data);\n            console.log('calling chart');\n            svg.transition().duration(0).call(chart);\n\n            return chart;\n        },\n        callback: function(graph) {\n            nv.utils.windowResize(function() {\n                var width = nv.utils.windowSize().width;\n                var height = nv.utils.windowSize().height;\n                graph.width(width).height(height);\n\n                d3.select('#test1 svg')\n                    .attr('width', width)\n                    .attr('height', height)\n                    .transition().duration(0)\n                    .call(graph);\n\n            });\n        }\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/multiBarHorizontalChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    var long_short_data = [\n        {\n            key: 'Series1',\n            values: [\n                {\n                    \"label\" : \"Group A\" ,\n                    \"value\" : -1.8746444827653\n                } ,\n                {\n                    \"label\" : \"Group B\" ,\n                    \"value\" : -8.0961543492239\n                } ,\n                {\n                    \"label\" : \"Group C\" ,\n                    \"value\" : -0.57072943117674\n                } ,\n                {\n                    \"label\" : \"Group D\" ,\n                    \"value\" : -2.4174010336624\n                } ,\n                {\n                    \"label\" : \"Group E\" ,\n                    \"value\" : -0.72009071426284\n                } ,\n                {\n                    \"label\" : \"Group F\" ,\n                    \"value\" : -2.77154485523777\n                } ,\n                {\n                    \"label\" : \"Group G\" ,\n                    \"value\" : -9.90152097798131\n                } ,\n                {\n                    \"label\" : \"Group H\" ,\n                    \"value\" : 14.91445417330854\n                } ,\n                {\n                    \"label\" : \"Group I\" ,\n                    \"value\" : -3.055746319141851\n                }\n            ]\n        },\n        {\n            key: 'Series2',\n            values: [\n                {\n                    \"label\" : \"Group A\" ,\n                    \"value\" : 25.307646510375\n                } ,\n                {\n                    \"label\" : \"Group B\" ,\n                    \"value\" : 16.756779544553\n                } ,\n                {\n                    \"label\" : \"Group C\" ,\n                    \"value\" : 18.451534877007\n                } ,\n                {\n                    \"label\" : \"Group D\" ,\n                    \"value\" : 8.6142352811805\n                } ,\n                {\n                    \"label\" : \"Group E\" ,\n                    \"value\" : 7.8082472075876\n                } ,\n                {\n                    \"label\" : \"Group F\" ,\n                    \"value\" : 5.259101026956\n                } ,\n                {\n                    \"label\" : \"Group G\" ,\n                    \"value\" : 7.0947953487127\n                } ,\n                {\n                    \"label\" : \"Group H\" ,\n                    \"value\" : 8\n                } ,\n                {\n                    \"label\" : \"Group I\" ,\n                    \"value\" : 21\n                }\n            ]\n        },\n        {\n            key: 'Series3',\n            values: [\n                {\n                    \"label\" : \"Group A\" ,\n                    \"value\" : -14.307646510375\n                } ,\n                {\n                    \"label\" : \"Group B\" ,\n                    \"value\" : 16.756779544553\n                } ,\n                {\n                    \"label\" : \"Group C\" ,\n                    \"value\" : -18.451534877007\n                } ,\n                {\n                    \"label\" : \"Group D\" ,\n                    \"value\" : 8.6142352811805\n                } ,\n                {\n                    \"label\" : \"Group E\" ,\n                    \"value\" : -7.8082472075876\n                } ,\n                {\n                    \"label\" : \"Group F\" ,\n                    \"value\" : 15.259101026956\n                } ,\n                {\n                    \"label\" : \"Group G\" ,\n                    \"value\" : -0.30947953487127\n                } ,\n                {\n                    \"label\" : \"Group H\" ,\n                    \"value\" : 0\n                } ,\n                {\n                    \"label\" : \"Group I\" ,\n                    \"value\" : 0\n                }\n            ]\n        }\n    ];\n\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.multiBarHorizontalChart()\n            .x(function(d) { return d.label })\n            .y(function(d) { return d.value })\n            .yErr(function(d) { return [-Math.abs(d.value * Math.random() * 0.3), Math.abs(d.value * Math.random() * 0.3)] })\n            .barColor(d3.scale.category20().range())\n            .duration(250)\n            .showControls(true)\n            .showLegend(true)\n            .legendPosition(\"bottom\")\n            .controlsPosition(\"bottom\")\n            .margin({left: 100})\n            .stacked(true);\n\n        chart.yAxis.tickFormat(d3.format(',.2f'));\n\n        chart.yAxis.axisLabel('Y Axis');\n        chart.xAxis.axisLabel('X Axis').axisLabelDistance(20);\n\n        d3.select('#chart1 svg')\n            .datum(long_short_data)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n        chart.state.dispatch.on('change', function(state){\n            nv.log('state', JSON.stringify(state));\n        });\n        return chart;\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/multiChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<div id=\"chart1\" >\n    <svg> </svg>\n</div>\n\n<script>\n\n    var testdata = stream_layers(9,10+Math.random()*100,.1).map(function(data, i) {\n        return {\n            key: 'Stream' + i,\n            values: data.map(function(a){a.y = a.y * (i <= 1 ? -1 : 1); return a})\n        };\n    });\n\n    testdata[0].type = \"area\";\n    testdata[0].yAxis = 1;\n    testdata[1].type = \"area\";\n    testdata[1].yAxis = 1;\n    testdata[2].type = \"line\";\n    testdata[2].yAxis = 1;\n    testdata[3].type = \"line\";\n    testdata[3].yAxis = 2;\n    testdata[4].type = \"scatter\";\n    testdata[4].yAxis = 1;\n    testdata[5].type = \"scatter\";\n    testdata[5].yAxis = 2;\n    testdata[6].type = \"bar\";\n    testdata[6].yAxis = 2;\n    testdata[7].type = \"bar\";\n    testdata[7].yAxis = 2;\n    testdata[8].type = \"bar\";\n    testdata[8].yAxis = 2;\n\n    nv.addGraph(function() {\n        var chart = nv.models.multiChart()\n            .margin({top: 30, right: 60, bottom: 50, left: 70})\n            .color(d3.scale.category10().range());\n\n        chart.xAxis.tickFormat(d3.format(',f'));\n        chart.yAxis1.tickFormat(d3.format(',.1f'));\n        chart.yAxis2.tickFormat(d3.format(',.1f'));\n\n        d3.select('#chart1 svg')\n            .datum(testdata)\n            .transition().duration(500).call(chart);\n\n        return chart;\n    });\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/ohlc.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    var data = [{values: [\n        {\"date\": 15707, \"open\": 145.11, \"high\": 146.15, \"low\": 144.73, \"close\": 146.06, \"volume\": 192059000, \"adjusted\": 144.65},\n        {\"date\": 15708, \"open\": 145.99, \"high\": 146.37, \"low\": 145.34, \"close\": 145.73, \"volume\": 144761800, \"adjusted\": 144.32},\n        {\"date\": 15709, \"open\": 145.97, \"high\": 146.61, \"low\": 145.67, \"close\": 146.37, \"volume\": 116817700, \"adjusted\": 144.95},\n        {\"date\": 15712, \"open\": 145.85, \"high\": 146.11, \"low\": 145.43, \"close\": 145.97, \"volume\": 110002500, \"adjusted\": 144.56},\n        {\"date\": 15713, \"open\": 145.71, \"high\": 145.91, \"low\": 144.98, \"close\": 145.55, \"volume\": 121265100, \"adjusted\": 144.14},\n        {\"date\": 15714, \"open\": 145.87, \"high\": 146.32, \"low\": 145.64, \"close\": 145.92, \"volume\": 90745600, \"adjusted\": 144.51},\n        {\"date\": 15715, \"open\": 146.73, \"high\": 147.09, \"low\": 145.97, \"close\": 147.08, \"volume\": 130735400, \"adjusted\": 145.66},\n        {\"date\": 15716, \"open\": 147.04, \"high\": 147.15, \"low\": 146.61, \"close\": 147.07, \"volume\": 113917300, \"adjusted\": 145.65},\n        {\"date\": 15719, \"open\": 146.89, \"high\": 147.07, \"low\": 146.43, \"close\": 146.97, \"volume\": 89567200, \"adjusted\": 145.55},\n        {\"date\": 15720, \"open\": 146.29, \"high\": 147.21, \"low\": 146.2, \"close\": 147.07, \"volume\": 93172600, \"adjusted\": 145.65},\n        {\"date\": 15721, \"open\": 146.77, \"high\": 147.28, \"low\": 146.61, \"close\": 147.05, \"volume\": 104849500, \"adjusted\": 145.63},\n        {\"date\": 15722, \"open\": 147.7, \"high\": 148.42, \"low\": 147.15, \"close\": 148, \"volume\": 133833500, \"adjusted\": 146.57},\n        {\"date\": 15723, \"open\": 147.97, \"high\": 148.49, \"low\": 147.43, \"close\": 148.33, \"volume\": 169906000, \"adjusted\": 146.9},\n        {\"date\": 15727, \"open\": 148.33, \"high\": 149.13, \"low\": 147.98, \"close\": 149.13, \"volume\": 111797300, \"adjusted\": 147.69},\n        {\"date\": 15728, \"open\": 149.13, \"high\": 149.5, \"low\": 148.86, \"close\": 149.37, \"volume\": 104596100, \"adjusted\": 147.93},\n        {\"date\": 15729, \"open\": 149.15, \"high\": 150.14, \"low\": 149.01, \"close\": 149.41, \"volume\": 146426400, \"adjusted\": 147.97},\n        {\"date\": 15730, \"open\": 149.88, \"high\": 150.25, \"low\": 149.37, \"close\": 150.25, \"volume\": 147211600, \"adjusted\": 148.8},\n        {\"date\": 15733, \"open\": 150.29, \"high\": 150.33, \"low\": 149.51, \"close\": 150.07, \"volume\": 113357700, \"adjusted\": 148.62},\n        {\"date\": 15734, \"open\": 149.77, \"high\": 150.85, \"low\": 149.67, \"close\": 150.66, \"volume\": 105694400, \"adjusted\": 149.2},\n        {\"date\": 15735, \"open\": 150.64, \"high\": 150.94, \"low\": 149.93, \"close\": 150.07, \"volume\": 137447700, \"adjusted\": 148.62},\n        {\"date\": 15736, \"open\": 149.89, \"high\": 150.38, \"low\": 149.6, \"close\": 149.7, \"volume\": 108975800, \"adjusted\": 148.25},\n        {\"date\": 15737, \"open\": 150.65, \"high\": 151.42, \"low\": 150.39, \"close\": 151.24, \"volume\": 131173000, \"adjusted\": 149.78},\n        {\"date\": 15740, \"open\": 150.32, \"high\": 151.27, \"low\": 149.43, \"close\": 149.54, \"volume\": 159073600, \"adjusted\": 148.09},\n        {\"date\": 15741, \"open\": 150.35, \"high\": 151.48, \"low\": 150.29, \"close\": 151.05, \"volume\": 113912400, \"adjusted\": 149.59},\n        {\"date\": 15742, \"open\": 150.52, \"high\": 151.26, \"low\": 150.41, \"close\": 151.16, \"volume\": 138762800, \"adjusted\": 149.7},\n        {\"date\": 15743, \"open\": 151.21, \"high\": 151.35, \"low\": 149.86, \"close\": 150.96, \"volume\": 162490000, \"adjusted\": 149.5},\n        {\"date\": 15744, \"open\": 151.22, \"high\": 151.89, \"low\": 151.22, \"close\": 151.8, \"volume\": 103133700, \"adjusted\": 150.33},\n        {\"date\": 15747, \"open\": 151.74, \"high\": 151.9, \"low\": 151.39, \"close\": 151.77, \"volume\": 73775000, \"adjusted\": 150.3},\n        {\"date\": 15748, \"open\": 151.78, \"high\": 152.3, \"low\": 151.61, \"close\": 152.02, \"volume\": 65392700, \"adjusted\": 150.55},\n        {\"date\": 15749, \"open\": 152.33, \"high\": 152.61, \"low\": 151.72, \"close\": 152.15, \"volume\": 82322600, \"adjusted\": 150.68},\n        {\"date\": 15750, \"open\": 151.69, \"high\": 152.47, \"low\": 151.52, \"close\": 152.29, \"volume\": 80834300, \"adjusted\": 150.82},\n        {\"date\": 15751, \"open\": 152.43, \"high\": 152.59, \"low\": 151.55, \"close\": 152.11, \"volume\": 215226500, \"adjusted\": 150.64},\n        {\"date\": 15755, \"open\": 152.37, \"high\": 153.28, \"low\": 152.16, \"close\": 153.25, \"volume\": 95105400, \"adjusted\": 151.77},\n        {\"date\": 15756, \"open\": 153.14, \"high\": 153.19, \"low\": 151.26, \"close\": 151.34, \"volume\": 160574800, \"adjusted\": 149.88},\n        {\"date\": 15757, \"open\": 150.96, \"high\": 151.42, \"low\": 149.94, \"close\": 150.42, \"volume\": 183257000, \"adjusted\": 148.97},\n        {\"date\": 15758, \"open\": 151.15, \"high\": 151.89, \"low\": 150.49, \"close\": 151.89, \"volume\": 106356600, \"adjusted\": 150.42},\n        {\"date\": 15761, \"open\": 152.63, \"high\": 152.86, \"low\": 149, \"close\": 149, \"volume\": 245824800, \"adjusted\": 147.56},\n        {\"date\": 15762, \"open\": 149.72, \"high\": 150.2, \"low\": 148.73, \"close\": 150.02, \"volume\": 186596200, \"adjusted\": 148.57},\n        {\"date\": 15763, \"open\": 149.89, \"high\": 152.33, \"low\": 149.76, \"close\": 151.91, \"volume\": 150781900, \"adjusted\": 150.44},\n        {\"date\": 15764, \"open\": 151.9, \"high\": 152.87, \"low\": 151.41, \"close\": 151.61, \"volume\": 126866000, \"adjusted\": 150.14},\n        {\"date\": 15765, \"open\": 151.09, \"high\": 152.34, \"low\": 150.41, \"close\": 152.11, \"volume\": 170634800, \"adjusted\": 150.64},\n        {\"date\": 15768, \"open\": 151.76, \"high\": 152.92, \"low\": 151.52, \"close\": 152.92, \"volume\": 99010200, \"adjusted\": 151.44},\n        {\"date\": 15769, \"open\": 153.66, \"high\": 154.7, \"low\": 153.64, \"close\": 154.29, \"volume\": 121431900, \"adjusted\": 152.8},\n        {\"date\": 15770, \"open\": 154.84, \"high\": 154.92, \"low\": 154.16, \"close\": 154.5, \"volume\": 94469900, \"adjusted\": 153.01},\n        {\"date\": 15771, \"open\": 154.7, \"high\": 154.98, \"low\": 154.52, \"close\": 154.78, \"volume\": 86101400, \"adjusted\": 153.28},\n        {\"date\": 15772, \"open\": 155.46, \"high\": 155.65, \"low\": 154.66, \"close\": 155.44, \"volume\": 123477800, \"adjusted\": 153.94},\n        {\"date\": 15775, \"open\": 155.32, \"high\": 156.04, \"low\": 155.13, \"close\": 156.03, \"volume\": 83746800, \"adjusted\": 154.52},\n        {\"date\": 15776, \"open\": 155.92, \"high\": 156.1, \"low\": 155.21, \"close\": 155.68, \"volume\": 105755800, \"adjusted\": 154.17},\n        {\"date\": 15777, \"open\": 155.76, \"high\": 156.12, \"low\": 155.23, \"close\": 155.9, \"volume\": 92550900, \"adjusted\": 154.39},\n        {\"date\": 15778, \"open\": 156.31, \"high\": 156.8, \"low\": 155.91, \"close\": 156.73, \"volume\": 126329900, \"adjusted\": 155.21},\n        {\"date\": 15779, \"open\": 155.85, \"high\": 156.04, \"low\": 155.31, \"close\": 155.83, \"volume\": 138601100, \"adjusted\": 155.01},\n        {\"date\": 15782, \"open\": 154.34, \"high\": 155.64, \"low\": 154.2, \"close\": 154.97, \"volume\": 126704300, \"adjusted\": 154.15},\n        {\"date\": 15783, \"open\": 155.3, \"high\": 155.51, \"low\": 153.59, \"close\": 154.61, \"volume\": 167567300, \"adjusted\": 153.8},\n        {\"date\": 15784, \"open\": 155.52, \"high\": 155.95, \"low\": 155.26, \"close\": 155.69, \"volume\": 113759300, \"adjusted\": 154.87},\n        {\"date\": 15785, \"open\": 154.76, \"high\": 155.64, \"low\": 154.1, \"close\": 154.36, \"volume\": 128605000, \"adjusted\": 153.55},\n        {\"date\": 15786, \"open\": 154.85, \"high\": 155.6, \"low\": 154.73, \"close\": 155.6, \"volume\": 111163600, \"adjusted\": 154.78},\n        {\"date\": 15789, \"open\": 156.01, \"high\": 156.27, \"low\": 154.35, \"close\": 154.95, \"volume\": 151322300, \"adjusted\": 154.13},\n        {\"date\": 15790, \"open\": 155.59, \"high\": 156.23, \"low\": 155.42, \"close\": 156.19, \"volume\": 86856600, \"adjusted\": 155.37},\n        {\"date\": 15791, \"open\": 155.26, \"high\": 156.24, \"low\": 155, \"close\": 156.19, \"volume\": 99950600, \"adjusted\": 155.37},\n        {\"date\": 15792, \"open\": 156.09, \"high\": 156.85, \"low\": 155.75, \"close\": 156.67, \"volume\": 102932800, \"adjusted\": 155.85},\n        {\"date\": 15796, \"open\": 156.59, \"high\": 156.91, \"low\": 155.67, \"close\": 156.05, \"volume\": 99194100, \"adjusted\": 155.23},\n        {\"date\": 15797, \"open\": 156.61, \"high\": 157.21, \"low\": 156.37, \"close\": 156.82, \"volume\": 101504300, \"adjusted\": 155.99},\n        {\"date\": 15798, \"open\": 156.91, \"high\": 157.03, \"low\": 154.82, \"close\": 155.23, \"volume\": 154167400, \"adjusted\": 154.41},\n        {\"date\": 15799, \"open\": 155.43, \"high\": 156.17, \"low\": 155.09, \"close\": 155.86, \"volume\": 131885000, \"adjusted\": 155.04},\n        {\"date\": 15800, \"open\": 153.95, \"high\": 155.35, \"low\": 153.77, \"close\": 155.16, \"volume\": 159666000, \"adjusted\": 154.34},\n        {\"date\": 15803, \"open\": 155.27, \"high\": 156.22, \"low\": 154.75, \"close\": 156.21, \"volume\": 86571200, \"adjusted\": 155.39},\n        {\"date\": 15804, \"open\": 156.5, \"high\": 157.32, \"low\": 155.98, \"close\": 156.75, \"volume\": 101922200, \"adjusted\": 155.92},\n        {\"date\": 15805, \"open\": 157.17, \"high\": 158.87, \"low\": 157.13, \"close\": 158.67, \"volume\": 135711100, \"adjusted\": 157.83},\n        {\"date\": 15806, \"open\": 158.7, \"high\": 159.71, \"low\": 158.54, \"close\": 159.19, \"volume\": 110142500, \"adjusted\": 158.35},\n        {\"date\": 15807, \"open\": 158.68, \"high\": 159.04, \"low\": 157.92, \"close\": 158.8, \"volume\": 116359900, \"adjusted\": 157.96},\n        {\"date\": 15810, \"open\": 158, \"high\": 158.13, \"low\": 155.1, \"close\": 155.12, \"volume\": 217259000, \"adjusted\": 154.3},\n        {\"date\": 15811, \"open\": 156.29, \"high\": 157.49, \"low\": 155.91, \"close\": 157.41, \"volume\": 147507800, \"adjusted\": 156.58},\n        {\"date\": 15812, \"open\": 156.29, \"high\": 156.32, \"low\": 154.28, \"close\": 155.11, \"volume\": 226834800, \"adjusted\": 154.29},\n        {\"date\": 15813, \"open\": 155.37, \"high\": 155.41, \"low\": 153.55, \"close\": 154.14, \"volume\": 167583200, \"adjusted\": 153.33},\n        {\"date\": 15814, \"open\": 154.5, \"high\": 155.55, \"low\": 154.12, \"close\": 155.48, \"volume\": 149687600, \"adjusted\": 154.66},\n        {\"date\": 15817, \"open\": 155.78, \"high\": 156.54, \"low\": 154.75, \"close\": 156.17, \"volume\": 106553500, \"adjusted\": 155.35},\n        {\"date\": 15818, \"open\": 156.95, \"high\": 157.93, \"low\": 156.17, \"close\": 157.78, \"volume\": 166141300, \"adjusted\": 156.95},\n        {\"date\": 15819, \"open\": 157.83, \"high\": 158.3, \"low\": 157.54, \"close\": 157.88, \"volume\": 96781200, \"adjusted\": 157.05},\n        {\"date\": 15820, \"open\": 158.34, \"high\": 159.27, \"low\": 158.1, \"close\": 158.52, \"volume\": 131060600, \"adjusted\": 157.69},\n        {\"date\": 15821, \"open\": 158.33, \"high\": 158.6, \"low\": 157.73, \"close\": 158.24, \"volume\": 95918800, \"adjusted\": 157.41},\n        {\"date\": 15824, \"open\": 158.67, \"high\": 159.65, \"low\": 158.42, \"close\": 159.3, \"volume\": 88572800, \"adjusted\": 158.46},\n        {\"date\": 15825, \"open\": 159.27, \"high\": 159.72, \"low\": 158.61, \"close\": 159.68, \"volume\": 116010700, \"adjusted\": 158.84},\n        {\"date\": 15826, \"open\": 159.33, \"high\": 159.41, \"low\": 158.1, \"close\": 158.28, \"volume\": 138874200, \"adjusted\": 157.45},\n        {\"date\": 15827, \"open\": 158.68, \"high\": 159.89, \"low\": 158.53, \"close\": 159.75, \"volume\": 96407600, \"adjusted\": 158.91},\n        {\"date\": 15828, \"open\": 161.14, \"high\": 161.88, \"low\": 159.78, \"close\": 161.37, \"volume\": 144202300, \"adjusted\": 160.52},\n        {\"date\": 15831, \"open\": 161.49, \"high\": 162.01, \"low\": 161.42, \"close\": 161.78, \"volume\": 66882100, \"adjusted\": 160.93},\n        {\"date\": 15832, \"open\": 162.13, \"high\": 162.65, \"low\": 161.67, \"close\": 162.6, \"volume\": 90359200, \"adjusted\": 161.74},\n        {\"date\": 15833, \"open\": 162.42, \"high\": 163.39, \"low\": 162.33, \"close\": 163.34, \"volume\": 97419200, \"adjusted\": 162.48},\n        {\"date\": 15834, \"open\": 163.27, \"high\": 163.7, \"low\": 162.47, \"close\": 162.88, \"volume\": 106738600, \"adjusted\": 162.02},\n        {\"date\": 15835, \"open\": 162.99, \"high\": 163.55, \"low\": 162.51, \"close\": 163.41, \"volume\": 103203000, \"adjusted\": 162.55},\n        {\"date\": 15838, \"open\": 163.2, \"high\": 163.81, \"low\": 162.82, \"close\": 163.54, \"volume\": 81843200, \"adjusted\": 162.68},\n        {\"date\": 15839, \"open\": 163.67, \"high\": 165.35, \"low\": 163.67, \"close\": 165.23, \"volume\": 119000900, \"adjusted\": 164.36},\n        {\"date\": 15840, \"open\": 164.96, \"high\": 166.45, \"low\": 164.91, \"close\": 166.12, \"volume\": 120718500, \"adjusted\": 165.25},\n        {\"date\": 15841, \"open\": 165.78, \"high\": 166.36, \"low\": 165.09, \"close\": 165.34, \"volume\": 109913600, \"adjusted\": 164.47},\n        {\"date\": 15842, \"open\": 165.95, \"high\": 167.04, \"low\": 165.73, \"close\": 166.94, \"volume\": 129801000, \"adjusted\": 166.06},\n        {\"date\": 15845, \"open\": 166.78, \"high\": 167.58, \"low\": 166.61, \"close\": 166.93, \"volume\": 85071200, \"adjusted\": 166.05},\n        {\"date\": 15846, \"open\": 167.08, \"high\": 167.8, \"low\": 166.5, \"close\": 167.17, \"volume\": 95804200, \"adjusted\": 166.29},\n        {\"date\": 15847, \"open\": 167.34, \"high\": 169.07, \"low\": 165.17, \"close\": 165.93, \"volume\": 244031800, \"adjusted\": 165.06},\n        {\"date\": 15848, \"open\": 164.16, \"high\": 165.91, \"low\": 163.94, \"close\": 165.45, \"volume\": 211064400, \"adjusted\": 164.58},\n        {\"date\": 15849, \"open\": 164.47, \"high\": 165.38, \"low\": 163.98, \"close\": 165.31, \"volume\": 151573900, \"adjusted\": 164.44},\n        {\"date\": 15853, \"open\": 167.04, \"high\": 167.78, \"low\": 165.81, \"close\": 166.3, \"volume\": 143679800, \"adjusted\": 165.42},\n        {\"date\": 15854, \"open\": 165.42, \"high\": 165.8, \"low\": 164.34, \"close\": 165.22, \"volume\": 160363400, \"adjusted\": 164.35},\n        {\"date\": 15855, \"open\": 165.35, \"high\": 166.59, \"low\": 165.22, \"close\": 165.83, \"volume\": 107793800, \"adjusted\": 164.96},\n        {\"date\": 15856, \"open\": 165.37, \"high\": 166.31, \"low\": 163.13, \"close\": 163.45, \"volume\": 176850100, \"adjusted\": 162.59},\n        {\"date\": 15859, \"open\": 163.83, \"high\": 164.46, \"low\": 162.66, \"close\": 164.35, \"volume\": 168390700, \"adjusted\": 163.48},\n        {\"date\": 15860, \"open\": 164.44, \"high\": 165.1, \"low\": 162.73, \"close\": 163.56, \"volume\": 157631500, \"adjusted\": 162.7},\n        {\"date\": 15861, \"open\": 163.09, \"high\": 163.42, \"low\": 161.13, \"close\": 161.27, \"volume\": 211737800, \"adjusted\": 160.42},\n        {\"date\": 15862, \"open\": 161.2, \"high\": 162.74, \"low\": 160.25, \"close\": 162.73, \"volume\": 200225500, \"adjusted\": 161.87},\n        {\"date\": 15863, \"open\": 163.85, \"high\": 164.95, \"low\": 163.14, \"close\": 164.8, \"volume\": 188337800, \"adjusted\": 163.93},\n        {\"date\": 15866, \"open\": 165.31, \"high\": 165.4, \"low\": 164.37, \"close\": 164.8, \"volume\": 105667100, \"adjusted\": 163.93},\n        {\"date\": 15867, \"open\": 163.3, \"high\": 164.54, \"low\": 162.74, \"close\": 163.1, \"volume\": 159505400, \"adjusted\": 162.24},\n        {\"date\": 15868, \"open\": 164.22, \"high\": 164.39, \"low\": 161.6, \"close\": 161.75, \"volume\": 177361500, \"adjusted\": 160.9},\n        {\"date\": 15869, \"open\": 161.66, \"high\": 164.5, \"low\": 161.3, \"close\": 164.21, \"volume\": 163587800, \"adjusted\": 163.35},\n        {\"date\": 15870, \"open\": 164.03, \"high\": 164.67, \"low\": 162.91, \"close\": 163.18, \"volume\": 141197500, \"adjusted\": 162.32},\n        {\"date\": 15873, \"open\": 164.29, \"high\": 165.22, \"low\": 163.22, \"close\": 164.44, \"volume\": 136295600, \"adjusted\": 163.57},\n        {\"date\": 15874, \"open\": 164.53, \"high\": 165.99, \"low\": 164.52, \"close\": 165.74, \"volume\": 114695600, \"adjusted\": 164.87},\n        {\"date\": 15875, \"open\": 165.6, \"high\": 165.89, \"low\": 163.38, \"close\": 163.45, \"volume\": 206149500, \"adjusted\": 162.59},\n        {\"date\": 15876, \"open\": 161.86, \"high\": 163.47, \"low\": 158.98, \"close\": 159.4, \"volume\": 321255900, \"adjusted\": 158.56},\n        {\"date\": 15877, \"open\": 159.64, \"high\": 159.76, \"low\": 157.47, \"close\": 159.07, \"volume\": 271956800, \"adjusted\": 159.07},\n        {\"date\": 15880, \"open\": 157.41, \"high\": 158.43, \"low\": 155.73, \"close\": 157.06, \"volume\": 222329000, \"adjusted\": 157.06},\n        {\"date\": 15881, \"open\": 158.48, \"high\": 160.1, \"low\": 157.42, \"close\": 158.57, \"volume\": 162262200, \"adjusted\": 158.57},\n        {\"date\": 15882, \"open\": 159.87, \"high\": 160.5, \"low\": 159.25, \"close\": 160.14, \"volume\": 134848000, \"adjusted\": 160.14},\n        {\"date\": 15883, \"open\": 161.1, \"high\": 161.82, \"low\": 160.95, \"close\": 161.08, \"volume\": 129483700, \"adjusted\": 161.08},\n        {\"date\": 15884, \"open\": 160.63, \"high\": 161.4, \"low\": 159.86, \"close\": 160.42, \"volume\": 160402900, \"adjusted\": 160.42},\n        {\"date\": 15887, \"open\": 161.26, \"high\": 162.48, \"low\": 161.08, \"close\": 161.36, \"volume\": 131954800, \"adjusted\": 161.36},\n        {\"date\": 15888, \"open\": 161.12, \"high\": 162.3, \"low\": 160.5, \"close\": 161.21, \"volume\": 154863700, \"adjusted\": 161.21},\n        {\"date\": 15889, \"open\": 160.48, \"high\": 161.77, \"low\": 160.22, \"close\": 161.28, \"volume\": 75216400, \"adjusted\": 161.28},\n        {\"date\": 15891, \"open\": 162.47, \"high\": 163.08, \"low\": 161.3, \"close\": 163.02, \"volume\": 122416900, \"adjusted\": 163.02},\n        {\"date\": 15894, \"open\": 163.86, \"high\": 164.39, \"low\": 163.08, \"close\": 163.95, \"volume\": 108092500, \"adjusted\": 163.95},\n        {\"date\": 15895, \"open\": 164.98, \"high\": 165.33, \"low\": 164.27, \"close\": 165.13, \"volume\": 119298000, \"adjusted\": 165.13},\n        {\"date\": 15896, \"open\": 164.97, \"high\": 165.75, \"low\": 164.63, \"close\": 165.19, \"volume\": 121410100, \"adjusted\": 165.19},\n        {\"date\": 15897, \"open\": 167.11, \"high\": 167.61, \"low\": 165.18, \"close\": 167.44, \"volume\": 135592200, \"adjusted\": 167.44},\n        {\"date\": 15898, \"open\": 167.39, \"high\": 167.93, \"low\": 167.13, \"close\": 167.51, \"volume\": 104212700, \"adjusted\": 167.51},\n        {\"date\": 15901, \"open\": 167.97, \"high\": 168.39, \"low\": 167.68, \"close\": 168.15, \"volume\": 69450600, \"adjusted\": 168.15},\n        {\"date\": 15902, \"open\": 168.26, \"high\": 168.36, \"low\": 167.07, \"close\": 167.52, \"volume\": 88702100, \"adjusted\": 167.52},\n        {\"date\": 15903, \"open\": 168.16, \"high\": 168.48, \"low\": 167.73, \"close\": 167.95, \"volume\": 92873900, \"adjusted\": 167.95},\n        {\"date\": 15904, \"open\": 168.31, \"high\": 169.27, \"low\": 168.2, \"close\": 168.87, \"volume\": 103620100, \"adjusted\": 168.87},\n        {\"date\": 15905, \"open\": 168.52, \"high\": 169.23, \"low\": 168.31, \"close\": 169.17, \"volume\": 103831700, \"adjusted\": 169.17},\n        {\"date\": 15908, \"open\": 169.41, \"high\": 169.74, \"low\": 169.01, \"close\": 169.5, \"volume\": 79428600, \"adjusted\": 169.5},\n        {\"date\": 15909, \"open\": 169.8, \"high\": 169.83, \"low\": 169.05, \"close\": 169.14, \"volume\": 80829700, \"adjusted\": 169.14},\n        {\"date\": 15910, \"open\": 169.79, \"high\": 169.86, \"low\": 168.18, \"close\": 168.52, \"volume\": 112914000, \"adjusted\": 168.52},\n        {\"date\": 15911, \"open\": 168.22, \"high\": 169.08, \"low\": 167.94, \"close\": 168.93, \"volume\": 111088600, \"adjusted\": 168.93},\n        {\"date\": 15912, \"open\": 168.22, \"high\": 169.16, \"low\": 167.52, \"close\": 169.11, \"volume\": 107814600, \"adjusted\": 169.11},\n        {\"date\": 15915, \"open\": 168.68, \"high\": 169.06, \"low\": 168.11, \"close\": 168.59, \"volume\": 79695000, \"adjusted\": 168.59},\n        {\"date\": 15916, \"open\": 169.1, \"high\": 169.28, \"low\": 168.19, \"close\": 168.59, \"volume\": 85209600, \"adjusted\": 168.59},\n        {\"date\": 15917, \"open\": 168.94, \"high\": 169.85, \"low\": 168.49, \"close\": 168.71, \"volume\": 142388700, \"adjusted\": 168.71},\n        {\"date\": 15918, \"open\": 169.99, \"high\": 170.81, \"low\": 169.9, \"close\": 170.66, \"volume\": 110438400, \"adjusted\": 170.66},\n        {\"date\": 15919, \"open\": 170.28, \"high\": 170.97, \"low\": 170.05, \"close\": 170.95, \"volume\": 91116700, \"adjusted\": 170.95},\n        {\"date\": 15922, \"open\": 170.57, \"high\": 170.96, \"low\": 170.35, \"close\": 170.7, \"volume\": 54072700, \"adjusted\": 170.7},\n        {\"date\": 15923, \"open\": 170.37, \"high\": 170.74, \"low\": 169.35, \"close\": 169.73, \"volume\": 87495000, \"adjusted\": 169.73},\n        {\"date\": 15924, \"open\": 169.19, \"high\": 169.43, \"low\": 168.55, \"close\": 169.18, \"volume\": 84854700, \"adjusted\": 169.18},\n        {\"date\": 15925, \"open\": 169.98, \"high\": 170.18, \"low\": 168.93, \"close\": 169.8, \"volume\": 102181300, \"adjusted\": 169.8},\n        {\"date\": 15926, \"open\": 169.58, \"high\": 170.1, \"low\": 168.72, \"close\": 169.31, \"volume\": 91757700, \"adjusted\": 169.31},\n        {\"date\": 15929, \"open\": 168.46, \"high\": 169.31, \"low\": 168.38, \"close\": 169.11, \"volume\": 68593300, \"adjusted\": 169.11},\n        {\"date\": 15930, \"open\": 169.41, \"high\": 169.9, \"low\": 168.41, \"close\": 169.61, \"volume\": 80806000, \"adjusted\": 169.61},\n        {\"date\": 15931, \"open\": 169.53, \"high\": 169.8, \"low\": 168.7, \"close\": 168.74, \"volume\": 79829200, \"adjusted\": 168.74},\n        {\"date\": 15932, \"open\": 167.41, \"high\": 167.43, \"low\": 166.09, \"close\": 166.38, \"volume\": 152931800, \"adjusted\": 166.38},\n        {\"date\": 15933, \"open\": 166.06, \"high\": 166.63, \"low\": 165.5, \"close\": 165.83, \"volume\": 130868200, \"adjusted\": 165.83},\n        {\"date\": 15936, \"open\": 165.64, \"high\": 166.21, \"low\": 164.76, \"close\": 164.77, \"volume\": 96437600, \"adjusted\": 164.77},\n        {\"date\": 15937, \"open\": 165.04, \"high\": 166.2, \"low\": 164.86, \"close\": 165.58, \"volume\": 89294400, \"adjusted\": 165.58},\n        {\"date\": 15938, \"open\": 165.12, \"high\": 166.03, \"low\": 164.19, \"close\": 164.56, \"volume\": 159530500, \"adjusted\": 164.56},\n        {\"date\": 15939, \"open\": 164.9, \"high\": 166.3, \"low\": 164.89, \"close\": 166.06, \"volume\": 101471400, \"adjusted\": 166.06},\n        {\"date\": 15940, \"open\": 166.55, \"high\": 166.83, \"low\": 165.77, \"close\": 166.62, \"volume\": 90888900, \"adjusted\": 166.62},\n        {\"date\": 15943, \"open\": 166.79, \"high\": 167.3, \"low\": 165.89, \"close\": 166, \"volume\": 89702100, \"adjusted\": 166},\n        {\"date\": 15944, \"open\": 164.36, \"high\": 166, \"low\": 163.21, \"close\": 163.33, \"volume\": 158619400, \"adjusted\": 163.33},\n        {\"date\": 15945, \"open\": 163.26, \"high\": 164.49, \"low\": 163.05, \"close\": 163.91, \"volume\": 108113000, \"adjusted\": 163.91},\n        {\"date\": 15946, \"open\": 163.55, \"high\": 165.04, \"low\": 163.4, \"close\": 164.17, \"volume\": 119200500, \"adjusted\": 164.17},\n        {\"date\": 15947, \"open\": 164.51, \"high\": 164.53, \"low\": 163.17, \"close\": 163.65, \"volume\": 134560800, \"adjusted\": 163.65},\n        {\"date\": 15951, \"open\": 165.23, \"high\": 165.58, \"low\": 163.7, \"close\": 164.39, \"volume\": 142322300, \"adjusted\": 164.39},\n        {\"date\": 15952, \"open\": 164.43, \"high\": 166.03, \"low\": 164.13, \"close\": 165.75, \"volume\": 97304000, \"adjusted\": 165.75},\n        {\"date\": 15953, \"open\": 165.85, \"high\": 166.4, \"low\": 165.73, \"close\": 165.96, \"volume\": 62930500, \"adjusted\": 165.96}\n    ]}];\n\n    nv.addGraph(function() {\n        var chart = nv.models.ohlcBar()\n            .x(function(d) { return d['date'] })\n            .y(function(d) { return d['close'] });\n        d3.select(\"#chart1 svg\")\n                .datum(data)\n                .transition().duration(500)\n                .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/ohlcChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\">\n    <svg></svg>\n</div>\n\n<script>\n\n    var data = [{values: [\n        {\"date\": 15707, \"open\": 145.11, \"high\": 146.15, \"low\": 144.73, \"close\": 146.06, \"volume\": 192059000, \"adjusted\": 144.65},\n        {\"date\": 15708, \"open\": 145.99, \"high\": 146.37, \"low\": 145.34, \"close\": 145.73, \"volume\": 144761800, \"adjusted\": 144.32},\n        {\"date\": 15709, \"open\": 145.97, \"high\": 146.61, \"low\": 145.67, \"close\": 146.37, \"volume\": 116817700, \"adjusted\": 144.95},\n        {\"date\": 15712, \"open\": 145.85, \"high\": 146.11, \"low\": 145.43, \"close\": 145.97, \"volume\": 110002500, \"adjusted\": 144.56},\n        {\"date\": 15713, \"open\": 145.71, \"high\": 145.91, \"low\": 144.98, \"close\": 145.55, \"volume\": 121265100, \"adjusted\": 144.14},\n        {\"date\": 15714, \"open\": 145.87, \"high\": 146.32, \"low\": 145.64, \"close\": 145.92, \"volume\": 90745600, \"adjusted\": 144.51},\n        {\"date\": 15715, \"open\": 146.73, \"high\": 147.09, \"low\": 145.97, \"close\": 147.08, \"volume\": 130735400, \"adjusted\": 145.66},\n        {\"date\": 15716, \"open\": 147.04, \"high\": 147.15, \"low\": 146.61, \"close\": 147.07, \"volume\": 113917300, \"adjusted\": 145.65},\n        {\"date\": 15719, \"open\": 146.89, \"high\": 147.07, \"low\": 146.43, \"close\": 146.97, \"volume\": 89567200, \"adjusted\": 145.55},\n        {\"date\": 15720, \"open\": 146.29, \"high\": 147.21, \"low\": 146.2, \"close\": 147.07, \"volume\": 93172600, \"adjusted\": 145.65},\n        {\"date\": 15721, \"open\": 146.77, \"high\": 147.28, \"low\": 146.61, \"close\": 147.05, \"volume\": 104849500, \"adjusted\": 145.63},\n        {\"date\": 15722, \"open\": 147.7, \"high\": 148.42, \"low\": 147.15, \"close\": 148, \"volume\": 133833500, \"adjusted\": 146.57},\n        {\"date\": 15723, \"open\": 147.97, \"high\": 148.49, \"low\": 147.43, \"close\": 148.33, \"volume\": 169906000, \"adjusted\": 146.9},\n        {\"date\": 15727, \"open\": 148.33, \"high\": 149.13, \"low\": 147.98, \"close\": 149.13, \"volume\": 111797300, \"adjusted\": 147.69},\n        {\"date\": 15728, \"open\": 149.13, \"high\": 149.5, \"low\": 148.86, \"close\": 149.37, \"volume\": 104596100, \"adjusted\": 147.93},\n        {\"date\": 15729, \"open\": 149.15, \"high\": 150.14, \"low\": 149.01, \"close\": 149.41, \"volume\": 146426400, \"adjusted\": 147.97},\n        {\"date\": 15730, \"open\": 149.88, \"high\": 150.25, \"low\": 149.37, \"close\": 150.25, \"volume\": 147211600, \"adjusted\": 148.8},\n        {\"date\": 15733, \"open\": 150.29, \"high\": 150.33, \"low\": 149.51, \"close\": 150.07, \"volume\": 113357700, \"adjusted\": 148.62},\n        {\"date\": 15734, \"open\": 149.77, \"high\": 150.85, \"low\": 149.67, \"close\": 150.66, \"volume\": 105694400, \"adjusted\": 149.2},\n        {\"date\": 15735, \"open\": 150.64, \"high\": 150.94, \"low\": 149.93, \"close\": 150.07, \"volume\": 137447700, \"adjusted\": 148.62},\n        {\"date\": 15736, \"open\": 149.89, \"high\": 150.38, \"low\": 149.6, \"close\": 149.7, \"volume\": 108975800, \"adjusted\": 148.25},\n        {\"date\": 15737, \"open\": 150.65, \"high\": 151.42, \"low\": 150.39, \"close\": 151.24, \"volume\": 131173000, \"adjusted\": 149.78},\n        {\"date\": 15740, \"open\": 150.32, \"high\": 151.27, \"low\": 149.43, \"close\": 149.54, \"volume\": 159073600, \"adjusted\": 148.09},\n        {\"date\": 15741, \"open\": 150.35, \"high\": 151.48, \"low\": 150.29, \"close\": 151.05, \"volume\": 113912400, \"adjusted\": 149.59},\n        {\"date\": 15742, \"open\": 150.52, \"high\": 151.26, \"low\": 150.41, \"close\": 151.16, \"volume\": 138762800, \"adjusted\": 149.7},\n        {\"date\": 15743, \"open\": 151.21, \"high\": 151.35, \"low\": 149.86, \"close\": 150.96, \"volume\": 162490000, \"adjusted\": 149.5},\n        {\"date\": 15744, \"open\": 151.22, \"high\": 151.89, \"low\": 151.22, \"close\": 151.8, \"volume\": 103133700, \"adjusted\": 150.33},\n        {\"date\": 15747, \"open\": 151.74, \"high\": 151.9, \"low\": 151.39, \"close\": 151.77, \"volume\": 73775000, \"adjusted\": 150.3},\n        {\"date\": 15748, \"open\": 151.78, \"high\": 152.3, \"low\": 151.61, \"close\": 152.02, \"volume\": 65392700, \"adjusted\": 150.55},\n        {\"date\": 15749, \"open\": 152.33, \"high\": 152.61, \"low\": 151.72, \"close\": 152.15, \"volume\": 82322600, \"adjusted\": 150.68},\n        {\"date\": 15750, \"open\": 151.69, \"high\": 152.47, \"low\": 151.52, \"close\": 152.29, \"volume\": 80834300, \"adjusted\": 150.82},\n        {\"date\": 15751, \"open\": 152.43, \"high\": 152.59, \"low\": 151.55, \"close\": 152.11, \"volume\": 215226500, \"adjusted\": 150.64},\n        {\"date\": 15755, \"open\": 152.37, \"high\": 153.28, \"low\": 152.16, \"close\": 153.25, \"volume\": 95105400, \"adjusted\": 151.77},\n        {\"date\": 15756, \"open\": 153.14, \"high\": 153.19, \"low\": 151.26, \"close\": 151.34, \"volume\": 160574800, \"adjusted\": 149.88},\n        {\"date\": 15757, \"open\": 150.96, \"high\": 151.42, \"low\": 149.94, \"close\": 150.42, \"volume\": 183257000, \"adjusted\": 148.97},\n        {\"date\": 15758, \"open\": 151.15, \"high\": 151.89, \"low\": 150.49, \"close\": 151.89, \"volume\": 106356600, \"adjusted\": 150.42},\n        {\"date\": 15761, \"open\": 152.63, \"high\": 152.86, \"low\": 149, \"close\": 149, \"volume\": 245824800, \"adjusted\": 147.56},\n        {\"date\": 15762, \"open\": 149.72, \"high\": 150.2, \"low\": 148.73, \"close\": 150.02, \"volume\": 186596200, \"adjusted\": 148.57},\n        {\"date\": 15763, \"open\": 149.89, \"high\": 152.33, \"low\": 149.76, \"close\": 151.91, \"volume\": 150781900, \"adjusted\": 150.44},\n        {\"date\": 15764, \"open\": 151.9, \"high\": 152.87, \"low\": 151.41, \"close\": 151.61, \"volume\": 126866000, \"adjusted\": 150.14},\n        {\"date\": 15765, \"open\": 151.09, \"high\": 152.34, \"low\": 150.41, \"close\": 152.11, \"volume\": 170634800, \"adjusted\": 150.64},\n        {\"date\": 15768, \"open\": 151.76, \"high\": 152.92, \"low\": 151.52, \"close\": 152.92, \"volume\": 99010200, \"adjusted\": 151.44},\n        {\"date\": 15769, \"open\": 153.66, \"high\": 154.7, \"low\": 153.64, \"close\": 154.29, \"volume\": 121431900, \"adjusted\": 152.8},\n        {\"date\": 15770, \"open\": 154.84, \"high\": 154.92, \"low\": 154.16, \"close\": 154.5, \"volume\": 94469900, \"adjusted\": 153.01},\n        {\"date\": 15771, \"open\": 154.7, \"high\": 154.98, \"low\": 154.52, \"close\": 154.78, \"volume\": 86101400, \"adjusted\": 153.28},\n        {\"date\": 15772, \"open\": 155.46, \"high\": 155.65, \"low\": 154.66, \"close\": 155.44, \"volume\": 123477800, \"adjusted\": 153.94},\n        {\"date\": 15775, \"open\": 155.32, \"high\": 156.04, \"low\": 155.13, \"close\": 156.03, \"volume\": 83746800, \"adjusted\": 154.52},\n        {\"date\": 15776, \"open\": 155.92, \"high\": 156.1, \"low\": 155.21, \"close\": 155.68, \"volume\": 105755800, \"adjusted\": 154.17},\n        {\"date\": 15777, \"open\": 155.76, \"high\": 156.12, \"low\": 155.23, \"close\": 155.9, \"volume\": 92550900, \"adjusted\": 154.39},\n        {\"date\": 15778, \"open\": 156.31, \"high\": 156.8, \"low\": 155.91, \"close\": 156.73, \"volume\": 126329900, \"adjusted\": 155.21},\n        {\"date\": 15779, \"open\": 155.85, \"high\": 156.04, \"low\": 155.31, \"close\": 155.83, \"volume\": 138601100, \"adjusted\": 155.01},\n        {\"date\": 15782, \"open\": 154.34, \"high\": 155.64, \"low\": 154.2, \"close\": 154.97, \"volume\": 126704300, \"adjusted\": 154.15},\n        {\"date\": 15783, \"open\": 155.3, \"high\": 155.51, \"low\": 153.59, \"close\": 154.61, \"volume\": 167567300, \"adjusted\": 153.8},\n        {\"date\": 15784, \"open\": 155.52, \"high\": 155.95, \"low\": 155.26, \"close\": 155.69, \"volume\": 113759300, \"adjusted\": 154.87},\n        {\"date\": 15785, \"open\": 154.76, \"high\": 155.64, \"low\": 154.1, \"close\": 154.36, \"volume\": 128605000, \"adjusted\": 153.55},\n        {\"date\": 15786, \"open\": 154.85, \"high\": 155.6, \"low\": 154.73, \"close\": 155.6, \"volume\": 111163600, \"adjusted\": 154.78},\n        {\"date\": 15789, \"open\": 156.01, \"high\": 156.27, \"low\": 154.35, \"close\": 154.95, \"volume\": 151322300, \"adjusted\": 154.13},\n        {\"date\": 15790, \"open\": 155.59, \"high\": 156.23, \"low\": 155.42, \"close\": 156.19, \"volume\": 86856600, \"adjusted\": 155.37},\n        {\"date\": 15791, \"open\": 155.26, \"high\": 156.24, \"low\": 155, \"close\": 156.19, \"volume\": 99950600, \"adjusted\": 155.37},\n        {\"date\": 15792, \"open\": 156.09, \"high\": 156.85, \"low\": 155.75, \"close\": 156.67, \"volume\": 102932800, \"adjusted\": 155.85},\n        {\"date\": 15796, \"open\": 156.59, \"high\": 156.91, \"low\": 155.67, \"close\": 156.05, \"volume\": 99194100, \"adjusted\": 155.23},\n        {\"date\": 15797, \"open\": 156.61, \"high\": 157.21, \"low\": 156.37, \"close\": 156.82, \"volume\": 101504300, \"adjusted\": 155.99},\n        {\"date\": 15798, \"open\": 156.91, \"high\": 157.03, \"low\": 154.82, \"close\": 155.23, \"volume\": 154167400, \"adjusted\": 154.41},\n        {\"date\": 15799, \"open\": 155.43, \"high\": 156.17, \"low\": 155.09, \"close\": 155.86, \"volume\": 131885000, \"adjusted\": 155.04},\n        {\"date\": 15800, \"open\": 153.95, \"high\": 155.35, \"low\": 153.77, \"close\": 155.16, \"volume\": 159666000, \"adjusted\": 154.34},\n        {\"date\": 15803, \"open\": 155.27, \"high\": 156.22, \"low\": 154.75, \"close\": 156.21, \"volume\": 86571200, \"adjusted\": 155.39},\n        {\"date\": 15804, \"open\": 156.5, \"high\": 157.32, \"low\": 155.98, \"close\": 156.75, \"volume\": 101922200, \"adjusted\": 155.92},\n        {\"date\": 15805, \"open\": 157.17, \"high\": 158.87, \"low\": 157.13, \"close\": 158.67, \"volume\": 135711100, \"adjusted\": 157.83},\n        {\"date\": 15806, \"open\": 158.7, \"high\": 159.71, \"low\": 158.54, \"close\": 159.19, \"volume\": 110142500, \"adjusted\": 158.35},\n        {\"date\": 15807, \"open\": 158.68, \"high\": 159.04, \"low\": 157.92, \"close\": 158.8, \"volume\": 116359900, \"adjusted\": 157.96},\n        {\"date\": 15810, \"open\": 158, \"high\": 158.13, \"low\": 155.1, \"close\": 155.12, \"volume\": 217259000, \"adjusted\": 154.3},\n        {\"date\": 15811, \"open\": 156.29, \"high\": 157.49, \"low\": 155.91, \"close\": 157.41, \"volume\": 147507800, \"adjusted\": 156.58},\n        {\"date\": 15812, \"open\": 156.29, \"high\": 156.32, \"low\": 154.28, \"close\": 155.11, \"volume\": 226834800, \"adjusted\": 154.29},\n        {\"date\": 15813, \"open\": 155.37, \"high\": 155.41, \"low\": 153.55, \"close\": 154.14, \"volume\": 167583200, \"adjusted\": 153.33},\n        {\"date\": 15814, \"open\": 154.5, \"high\": 155.55, \"low\": 154.12, \"close\": 155.48, \"volume\": 149687600, \"adjusted\": 154.66},\n        {\"date\": 15817, \"open\": 155.78, \"high\": 156.54, \"low\": 154.75, \"close\": 156.17, \"volume\": 106553500, \"adjusted\": 155.35},\n        {\"date\": 15818, \"open\": 156.95, \"high\": 157.93, \"low\": 156.17, \"close\": 157.78, \"volume\": 166141300, \"adjusted\": 156.95},\n        {\"date\": 15819, \"open\": 157.83, \"high\": 158.3, \"low\": 157.54, \"close\": 157.88, \"volume\": 96781200, \"adjusted\": 157.05},\n        {\"date\": 15820, \"open\": 158.34, \"high\": 159.27, \"low\": 158.1, \"close\": 158.52, \"volume\": 131060600, \"adjusted\": 157.69},\n        {\"date\": 15821, \"open\": 158.33, \"high\": 158.6, \"low\": 157.73, \"close\": 158.24, \"volume\": 95918800, \"adjusted\": 157.41},\n        {\"date\": 15824, \"open\": 158.67, \"high\": 159.65, \"low\": 158.42, \"close\": 159.3, \"volume\": 88572800, \"adjusted\": 158.46},\n        {\"date\": 15825, \"open\": 159.27, \"high\": 159.72, \"low\": 158.61, \"close\": 159.68, \"volume\": 116010700, \"adjusted\": 158.84},\n        {\"date\": 15826, \"open\": 159.33, \"high\": 159.41, \"low\": 158.1, \"close\": 158.28, \"volume\": 138874200, \"adjusted\": 157.45},\n        {\"date\": 15827, \"open\": 158.68, \"high\": 159.89, \"low\": 158.53, \"close\": 159.75, \"volume\": 96407600, \"adjusted\": 158.91},\n        {\"date\": 15828, \"open\": 161.14, \"high\": 161.88, \"low\": 159.78, \"close\": 161.37, \"volume\": 144202300, \"adjusted\": 160.52},\n        {\"date\": 15831, \"open\": 161.49, \"high\": 162.01, \"low\": 161.42, \"close\": 161.78, \"volume\": 66882100, \"adjusted\": 160.93},\n        {\"date\": 15832, \"open\": 162.13, \"high\": 162.65, \"low\": 161.67, \"close\": 162.6, \"volume\": 90359200, \"adjusted\": 161.74},\n        {\"date\": 15833, \"open\": 162.42, \"high\": 163.39, \"low\": 162.33, \"close\": 163.34, \"volume\": 97419200, \"adjusted\": 162.48},\n        {\"date\": 15834, \"open\": 163.27, \"high\": 163.7, \"low\": 162.47, \"close\": 162.88, \"volume\": 106738600, \"adjusted\": 162.02},\n        {\"date\": 15835, \"open\": 162.99, \"high\": 163.55, \"low\": 162.51, \"close\": 163.41, \"volume\": 103203000, \"adjusted\": 162.55},\n        {\"date\": 15838, \"open\": 163.2, \"high\": 163.81, \"low\": 162.82, \"close\": 163.54, \"volume\": 81843200, \"adjusted\": 162.68},\n        {\"date\": 15839, \"open\": 163.67, \"high\": 165.35, \"low\": 163.67, \"close\": 165.23, \"volume\": 119000900, \"adjusted\": 164.36},\n        {\"date\": 15840, \"open\": 164.96, \"high\": 166.45, \"low\": 164.91, \"close\": 166.12, \"volume\": 120718500, \"adjusted\": 165.25},\n        {\"date\": 15841, \"open\": 165.78, \"high\": 166.36, \"low\": 165.09, \"close\": 165.34, \"volume\": 109913600, \"adjusted\": 164.47},\n        {\"date\": 15842, \"open\": 165.95, \"high\": 167.04, \"low\": 165.73, \"close\": 166.94, \"volume\": 129801000, \"adjusted\": 166.06},\n        {\"date\": 15845, \"open\": 166.78, \"high\": 167.58, \"low\": 166.61, \"close\": 166.93, \"volume\": 85071200, \"adjusted\": 166.05},\n        {\"date\": 15846, \"open\": 167.08, \"high\": 167.8, \"low\": 166.5, \"close\": 167.17, \"volume\": 95804200, \"adjusted\": 166.29},\n        {\"date\": 15847, \"open\": 167.34, \"high\": 169.07, \"low\": 165.17, \"close\": 165.93, \"volume\": 244031800, \"adjusted\": 165.06},\n        {\"date\": 15848, \"open\": 164.16, \"high\": 165.91, \"low\": 163.94, \"close\": 165.45, \"volume\": 211064400, \"adjusted\": 164.58},\n        {\"date\": 15849, \"open\": 164.47, \"high\": 165.38, \"low\": 163.98, \"close\": 165.31, \"volume\": 151573900, \"adjusted\": 164.44},\n        {\"date\": 15853, \"open\": 167.04, \"high\": 167.78, \"low\": 165.81, \"close\": 166.3, \"volume\": 143679800, \"adjusted\": 165.42},\n        {\"date\": 15854, \"open\": 165.42, \"high\": 165.8, \"low\": 164.34, \"close\": 165.22, \"volume\": 160363400, \"adjusted\": 164.35},\n        {\"date\": 15855, \"open\": 165.35, \"high\": 166.59, \"low\": 165.22, \"close\": 165.83, \"volume\": 107793800, \"adjusted\": 164.96},\n        {\"date\": 15856, \"open\": 165.37, \"high\": 166.31, \"low\": 163.13, \"close\": 163.45, \"volume\": 176850100, \"adjusted\": 162.59},\n        {\"date\": 15859, \"open\": 163.83, \"high\": 164.46, \"low\": 162.66, \"close\": 164.35, \"volume\": 168390700, \"adjusted\": 163.48},\n        {\"date\": 15860, \"open\": 164.44, \"high\": 165.1, \"low\": 162.73, \"close\": 163.56, \"volume\": 157631500, \"adjusted\": 162.7},\n        {\"date\": 15861, \"open\": 163.09, \"high\": 163.42, \"low\": 161.13, \"close\": 161.27, \"volume\": 211737800, \"adjusted\": 160.42},\n        {\"date\": 15862, \"open\": 161.2, \"high\": 162.74, \"low\": 160.25, \"close\": 162.73, \"volume\": 200225500, \"adjusted\": 161.87},\n        {\"date\": 15863, \"open\": 163.85, \"high\": 164.95, \"low\": 163.14, \"close\": 164.8, \"volume\": 188337800, \"adjusted\": 163.93},\n        {\"date\": 15866, \"open\": 165.31, \"high\": 165.4, \"low\": 164.37, \"close\": 164.8, \"volume\": 105667100, \"adjusted\": 163.93},\n        {\"date\": 15867, \"open\": 163.3, \"high\": 164.54, \"low\": 162.74, \"close\": 163.1, \"volume\": 159505400, \"adjusted\": 162.24},\n        {\"date\": 15868, \"open\": 164.22, \"high\": 164.39, \"low\": 161.6, \"close\": 161.75, \"volume\": 177361500, \"adjusted\": 160.9},\n        {\"date\": 15869, \"open\": 161.66, \"high\": 164.5, \"low\": 161.3, \"close\": 164.21, \"volume\": 163587800, \"adjusted\": 163.35},\n        {\"date\": 15870, \"open\": 164.03, \"high\": 164.67, \"low\": 162.91, \"close\": 163.18, \"volume\": 141197500, \"adjusted\": 162.32},\n        {\"date\": 15873, \"open\": 164.29, \"high\": 165.22, \"low\": 163.22, \"close\": 164.44, \"volume\": 136295600, \"adjusted\": 163.57},\n        {\"date\": 15874, \"open\": 164.53, \"high\": 165.99, \"low\": 164.52, \"close\": 165.74, \"volume\": 114695600, \"adjusted\": 164.87},\n        {\"date\": 15875, \"open\": 165.6, \"high\": 165.89, \"low\": 163.38, \"close\": 163.45, \"volume\": 206149500, \"adjusted\": 162.59},\n        {\"date\": 15876, \"open\": 161.86, \"high\": 163.47, \"low\": 158.98, \"close\": 159.4, \"volume\": 321255900, \"adjusted\": 158.56},\n        {\"date\": 15877, \"open\": 159.64, \"high\": 159.76, \"low\": 157.47, \"close\": 159.07, \"volume\": 271956800, \"adjusted\": 159.07},\n        {\"date\": 15880, \"open\": 157.41, \"high\": 158.43, \"low\": 155.73, \"close\": 157.06, \"volume\": 222329000, \"adjusted\": 157.06},\n        {\"date\": 15881, \"open\": 158.48, \"high\": 160.1, \"low\": 157.42, \"close\": 158.57, \"volume\": 162262200, \"adjusted\": 158.57},\n        {\"date\": 15882, \"open\": 159.87, \"high\": 160.5, \"low\": 159.25, \"close\": 160.14, \"volume\": 134848000, \"adjusted\": 160.14},\n        {\"date\": 15883, \"open\": 161.1, \"high\": 161.82, \"low\": 160.95, \"close\": 161.08, \"volume\": 129483700, \"adjusted\": 161.08},\n        {\"date\": 15884, \"open\": 160.63, \"high\": 161.4, \"low\": 159.86, \"close\": 160.42, \"volume\": 160402900, \"adjusted\": 160.42},\n        {\"date\": 15887, \"open\": 161.26, \"high\": 162.48, \"low\": 161.08, \"close\": 161.36, \"volume\": 131954800, \"adjusted\": 161.36},\n        {\"date\": 15888, \"open\": 161.12, \"high\": 162.3, \"low\": 160.5, \"close\": 161.21, \"volume\": 154863700, \"adjusted\": 161.21},\n        {\"date\": 15889, \"open\": 160.48, \"high\": 161.77, \"low\": 160.22, \"close\": 161.28, \"volume\": 75216400, \"adjusted\": 161.28},\n        {\"date\": 15891, \"open\": 162.47, \"high\": 163.08, \"low\": 161.3, \"close\": 163.02, \"volume\": 122416900, \"adjusted\": 163.02},\n        {\"date\": 15894, \"open\": 163.86, \"high\": 164.39, \"low\": 163.08, \"close\": 163.95, \"volume\": 108092500, \"adjusted\": 163.95},\n        {\"date\": 15895, \"open\": 164.98, \"high\": 165.33, \"low\": 164.27, \"close\": 165.13, \"volume\": 119298000, \"adjusted\": 165.13},\n        {\"date\": 15896, \"open\": 164.97, \"high\": 165.75, \"low\": 164.63, \"close\": 165.19, \"volume\": 121410100, \"adjusted\": 165.19},\n        {\"date\": 15897, \"open\": 167.11, \"high\": 167.61, \"low\": 165.18, \"close\": 167.44, \"volume\": 135592200, \"adjusted\": 167.44},\n        {\"date\": 15898, \"open\": 167.39, \"high\": 167.93, \"low\": 167.13, \"close\": 167.51, \"volume\": 104212700, \"adjusted\": 167.51},\n        {\"date\": 15901, \"open\": 167.97, \"high\": 168.39, \"low\": 167.68, \"close\": 168.15, \"volume\": 69450600, \"adjusted\": 168.15},\n        {\"date\": 15902, \"open\": 168.26, \"high\": 168.36, \"low\": 167.07, \"close\": 167.52, \"volume\": 88702100, \"adjusted\": 167.52},\n        {\"date\": 15903, \"open\": 168.16, \"high\": 168.48, \"low\": 167.73, \"close\": 167.95, \"volume\": 92873900, \"adjusted\": 167.95},\n        {\"date\": 15904, \"open\": 168.31, \"high\": 169.27, \"low\": 168.2, \"close\": 168.87, \"volume\": 103620100, \"adjusted\": 168.87},\n        {\"date\": 15905, \"open\": 168.52, \"high\": 169.23, \"low\": 168.31, \"close\": 169.17, \"volume\": 103831700, \"adjusted\": 169.17},\n        {\"date\": 15908, \"open\": 169.41, \"high\": 169.74, \"low\": 169.01, \"close\": 169.5, \"volume\": 79428600, \"adjusted\": 169.5},\n        {\"date\": 15909, \"open\": 169.8, \"high\": 169.83, \"low\": 169.05, \"close\": 169.14, \"volume\": 80829700, \"adjusted\": 169.14},\n        {\"date\": 15910, \"open\": 169.79, \"high\": 169.86, \"low\": 168.18, \"close\": 168.52, \"volume\": 112914000, \"adjusted\": 168.52},\n        {\"date\": 15911, \"open\": 168.22, \"high\": 169.08, \"low\": 167.94, \"close\": 168.93, \"volume\": 111088600, \"adjusted\": 168.93},\n        {\"date\": 15912, \"open\": 168.22, \"high\": 169.16, \"low\": 167.52, \"close\": 169.11, \"volume\": 107814600, \"adjusted\": 169.11},\n        {\"date\": 15915, \"open\": 168.68, \"high\": 169.06, \"low\": 168.11, \"close\": 168.59, \"volume\": 79695000, \"adjusted\": 168.59},\n        {\"date\": 15916, \"open\": 169.1, \"high\": 169.28, \"low\": 168.19, \"close\": 168.59, \"volume\": 85209600, \"adjusted\": 168.59},\n        {\"date\": 15917, \"open\": 168.94, \"high\": 169.85, \"low\": 168.49, \"close\": 168.71, \"volume\": 142388700, \"adjusted\": 168.71},\n        {\"date\": 15918, \"open\": 169.99, \"high\": 170.81, \"low\": 169.9, \"close\": 170.66, \"volume\": 110438400, \"adjusted\": 170.66},\n        {\"date\": 15919, \"open\": 170.28, \"high\": 170.97, \"low\": 170.05, \"close\": 170.95, \"volume\": 91116700, \"adjusted\": 170.95},\n        {\"date\": 15922, \"open\": 170.57, \"high\": 170.96, \"low\": 170.35, \"close\": 170.7, \"volume\": 54072700, \"adjusted\": 170.7},\n        {\"date\": 15923, \"open\": 170.37, \"high\": 170.74, \"low\": 169.35, \"close\": 169.73, \"volume\": 87495000, \"adjusted\": 169.73},\n        {\"date\": 15924, \"open\": 169.19, \"high\": 169.43, \"low\": 168.55, \"close\": 169.18, \"volume\": 84854700, \"adjusted\": 169.18},\n        {\"date\": 15925, \"open\": 169.98, \"high\": 170.18, \"low\": 168.93, \"close\": 169.8, \"volume\": 102181300, \"adjusted\": 169.8},\n        {\"date\": 15926, \"open\": 169.58, \"high\": 170.1, \"low\": 168.72, \"close\": 169.31, \"volume\": 91757700, \"adjusted\": 169.31},\n        {\"date\": 15929, \"open\": 168.46, \"high\": 169.31, \"low\": 168.38, \"close\": 169.11, \"volume\": 68593300, \"adjusted\": 169.11},\n        {\"date\": 15930, \"open\": 169.41, \"high\": 169.9, \"low\": 168.41, \"close\": 169.61, \"volume\": 80806000, \"adjusted\": 169.61},\n        {\"date\": 15931, \"open\": 169.53, \"high\": 169.8, \"low\": 168.7, \"close\": 168.74, \"volume\": 79829200, \"adjusted\": 168.74},\n        {\"date\": 15932, \"open\": 167.41, \"high\": 167.43, \"low\": 166.09, \"close\": 166.38, \"volume\": 152931800, \"adjusted\": 166.38},\n        {\"date\": 15933, \"open\": 166.06, \"high\": 166.63, \"low\": 165.5, \"close\": 165.83, \"volume\": 130868200, \"adjusted\": 165.83},\n        {\"date\": 15936, \"open\": 165.64, \"high\": 166.21, \"low\": 164.76, \"close\": 164.77, \"volume\": 96437600, \"adjusted\": 164.77},\n        {\"date\": 15937, \"open\": 165.04, \"high\": 166.2, \"low\": 164.86, \"close\": 165.58, \"volume\": 89294400, \"adjusted\": 165.58},\n        {\"date\": 15938, \"open\": 165.12, \"high\": 166.03, \"low\": 164.19, \"close\": 164.56, \"volume\": 159530500, \"adjusted\": 164.56},\n        {\"date\": 15939, \"open\": 164.9, \"high\": 166.3, \"low\": 164.89, \"close\": 166.06, \"volume\": 101471400, \"adjusted\": 166.06},\n        {\"date\": 15940, \"open\": 166.55, \"high\": 166.83, \"low\": 165.77, \"close\": 166.62, \"volume\": 90888900, \"adjusted\": 166.62},\n        {\"date\": 15943, \"open\": 166.79, \"high\": 167.3, \"low\": 165.89, \"close\": 166, \"volume\": 89702100, \"adjusted\": 166},\n        {\"date\": 15944, \"open\": 164.36, \"high\": 166, \"low\": 163.21, \"close\": 163.33, \"volume\": 158619400, \"adjusted\": 163.33},\n        {\"date\": 15945, \"open\": 163.26, \"high\": 164.49, \"low\": 163.05, \"close\": 163.91, \"volume\": 108113000, \"adjusted\": 163.91},\n        {\"date\": 15946, \"open\": 163.55, \"high\": 165.04, \"low\": 163.4, \"close\": 164.17, \"volume\": 119200500, \"adjusted\": 164.17},\n        {\"date\": 15947, \"open\": 164.51, \"high\": 164.53, \"low\": 163.17, \"close\": 163.65, \"volume\": 134560800, \"adjusted\": 163.65},\n        {\"date\": 15951, \"open\": 165.23, \"high\": 165.58, \"low\": 163.7, \"close\": 164.39, \"volume\": 142322300, \"adjusted\": 164.39},\n        {\"date\": 15952, \"open\": 164.43, \"high\": 166.03, \"low\": 164.13, \"close\": 165.75, \"volume\": 97304000, \"adjusted\": 165.75},\n        {\"date\": 15953, \"open\": 165.85, \"high\": 166.4, \"low\": 165.73, \"close\": 165.96, \"volume\": 62930500, \"adjusted\": 165.96}\n    ]}];\n\n    nv.addGraph(function() {\n        var chart = nv.models.ohlcBarChart()\n            .x(function(d) { return d['date'] })\n            .y(function(d) { return d['close'] })\n            .duration(250)\n            .margin({left: 75, bottom: 50});\n\n        // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        chart.xAxis\n                .axisLabel(\"Dates\")\n                .tickFormat(function(d) {\n                    // I didn't feel like changing all the above date values\n                    // so I hack it to make each value fall on a different date\n                    return d3.time.format('%x')(new Date(new Date() - (20000 * 86400000) + (d * 86400000)));\n                });\n\n        chart.yAxis\n                .axisLabel('Stock Price')\n                .tickFormat(function(d,i){ return '$' + d3.format(',.1f')(d); });\n\n\n\n        d3.select(\"#chart1 svg\")\n                .datum(data)\n                .transition().duration(500)\n                .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/parallelCoordinates.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n            box-sizing: border-box;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart1\" class=\"chart\">\n    <svg></svg>\n</div>\n\n<script>\n\nvar chart;\nnv.addGraph(function() {\n\n    chart = nv.models.parallelCoordinates()\n        .dimensionData([{\"key\":\"economy (mpg)\",\"format\":d3.format(\"0.5f\")}, {\"key\":\"cylinders\",\"format\":d3.format(\"e\")},{\"key\":\"displacement (cc)\",\"format\":d3.format(\"g\")},{\"key\":\"power (hp)\",\"format\": d3.format(\"d\")},{\"key\":\"weight (lb)\",\"format\":d3.format(\"\")},{\"key\":\"0-60 mph (s)\",\"format\":d3.format(\"%\")},{\"key\":\"year\",\"format\":d3.format(\"p\")}])\n        .lineTension(0.85);\n\t\t\n\n    d3.select('#chart1 svg')\n            .datum(data())\n            .call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    return chart;\n});\n\nfunction data() {\n    return [\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}\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/parallelCoordinatesChart.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n        <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n        <script src=\"../build/nv.d3.js\"></script>\n\n        <style>\n            text {\n                font: 12px sans-serif;\n            }\n            svg {\n                display: block;\n            }\n            html, body {\n                margin: 0px;\n                padding: 0px;\n                height: 100%;\n                width: 100%;\n            }\n            #resetBrushButton {\n                color: white;\n                visibility: hidden;\n                background: gray;\n                border: 0;\n            }\n            #resetSortingButton {\n                left: 84px;\n                visibility: hidden;\n                color: white;\n                background: gray;\n                border: 0;\n            }\n        </style>\n    </head>\n    <body>\n        <div style=\"position:absolute; top: 0; left: 0;\">\n            <button id=\"resetBrushButton\" onclick=\"resetBrush();\">Reset Brush</button>\n            <button id=\"resetSortingButton\" onclick=\"resetSorting();\">Reset Sorting</button>\n        </div>\n\n        <svg id=\"test\" class=\"myparallelCoordinatechart\"></svg>\n\n        <script>\n        \n            function resetBrush() {\n                chart.filters([]);\n                chart.active([]);\n                chart.displayBrush(true);\n                d3.select(\"#resetBrushButton\").style(\"visibility\", \"hidden\");\n                chart.update();\n            }\n\n            function resetSorting() {\n                var dim = chart.dimensionData();\n                dim.map(function (d) { return d.currentPosition = d.originalPosition; });\n                dim.sort(function (a, b) { return a.originalPosition - b.originalPosition; });\n                chart.dimensionData(dim);\n                d3.select(\"#resetSortingButton\").style(\"visibility\", \"hidden\");\n                chart.update();\n            }\n\n            nv.addGraph(function () {\n\n                var dim = dimensions();\n                chart = nv.models.parallelCoordinatesChart()\n                    .dimensionData(dim)\n                    .displayBrush(false)\n                    .lineTension(0.85);\n\n                var data = mydata();\n                d3.select('#test')\n                    .datum(data)\n                    .call(chart);\n\n                nv.utils.windowResize(chart.update);\n\n                chart.dispatch.on('brushEnd', function (e) {\n                    d3.select(\"#resetBrushButton\").style(\"visibility\", \"visible\");\n                });\n\n                chart.dispatch.on('dimensionsOrder', function (e, b) {\n                    if (b) {\n                        d3.select(\"#resetSortingButton\").style(\"visibility\", \"visible\");\n                    }\n                });\n\n                // update chart data values randomly\n                setInterval(function () {\n                    data[0].values.P1 = Math.floor(Math.random() * 100);\n                    chart.update();\n                }, 4000);\n\n                // update chart data dimension randomly\n                setInterval(function () {\n                    var element = {\n                        key: \"P7\",\n                        format: d3.format(\"p\"),\n                        tooltip: \"year\",\n                    }\n                    if (dim.length === 7) {\n                        dim.splice(dim.indexOf(element), 1);\n                    } else {\n                        dim.push(element);\n                    }\n                    chart.dimensionData(dim);\n                    chart.update();\n                }, 10000);\n\n                return chart;\n            });\n\n            function dimensions() {\n                return [\n                    {\n                        key: \"P1\",\n                        format: d3.format(\"0.5f\"),\n                        tooltip: \"economy (mpg)\",\n                    },\n                    {\n                        key: \"P2\",\n                        format: d3.format(\"e\"),\n                        tooltip: \"cylinders\",\n                    },\n                    {\n                        key: \"P3\",\n                        format: d3.format(\"g\"),\n                        tooltip: \"displacement (cc)\",\n                    },\n                    {\n                        key: \"P4\",\n                        format: d3.format(\"d\"),\n                        tooltip: \"power (hp)\",\n                    },\n                    {\n                        key: \"P5\",\n                        format: d3.format(\"\"),\n                        tooltip: \"weight (lb)\",\n                    },\n                    {\n                        key: \"P6\",\n                        format: d3.format(\"%\"),\n                        tooltip: \"0-60 mph (s)\",\n                    },\n                    {\n                        key: \"P7\",\n                        format: d3.format(\"p\"),\n                        tooltip: \"year\",\n                    }\n                ];\n            }\n\n            function mydata() {\n                return [\n                    {\n                        name: \"Current design point\",\n                        values: {\n                            \"P1\": \"13\",\n                            \"P2\": \"8\",\n                            \"P3\": \"360\",\n                            \"P4\": \"175\",\n                            \"P5\": \"3821\",\n                            \"P6\": \"11\",\n                            \"P7\": \"73\"\n                        },\n                        color: \"red\",\n                        strokeWidth: 2\n                    },\n                    {\n                        name: \"DP1\",\n                        values: {\n                            \"P1\": \"15\",\n                            \"P2\": \"8\",\n                            \"P3\": \"390\",\n                            \"P4\": \"190\",\n                            \"P5\": \"3850\",\n                            \"P6\": \"8.5\",\n                            \"P7\": \"70\"\n                        },\n                        color: \"blue\",\n                        strokeWidth: 1\n                    },\n                    {\n                        name: \"DP2\",\n                        values: {\n                            \"P1\": \"17\",\n                            \"P2\": \"8\",\n                            \"P3\": \"304\",\n                            \"P4\": \"150\",\n                            \"P5\": \"3672\",\n                            \"P6\": \"11.5\",\n                            \"P7\": \"72\"\n                        },\n                        color: \"blue\",\n                        strokeWidth: 2\n                    },\n                    {\n                        name: \"DP3\",\n                        values: {\n                            \"P1\": \"20.2\",\n                            \"P2\": \"6\",\n                            \"P3\": \"232\",\n                            \"P4\": \"\",\n                            \"P5\": \"3265\",\n                            \"P6\": \"18.2\",\n                            \"P7\": \"79\"\n                        },\n                        color: \"blue\",\n                        strokeWidth: 1\n                    },\n                    {\n                        name: \"DP4\",\n                        values: {\n                            \"P1\": \"18.1\",\n                            \"P2\": \"6\",\n                            \"P3\": \"258\",\n                            \"P4\": \"120\",\n                            \"P5\": \"3410\",\n                            \"P6\": \"15.1\",\n                            \"P7\": \"78\"\n                        },\n                        color: \"blue\",\n                        strokeWidth: 1\n                    }\n                ];\n            }\n\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "examples/pie.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        .testBlock {\n            display: block;\n            float: left;\n            height: 300px;\n            width: 300px;\n        }\n        html, body {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div class=\"testBlock\"><svg id=\"test1\"></svg></div>\n<div class=\"testBlock\"><svg id=\"test2\"></svg></div>\n\n<script>\n\n    var testdata = [\n        {key: \"One\", y: 5},\n        {key: \"Two\", y: 2},\n        {key: \"Three\", y: 9},\n        {key: \"Four\", y: 7},\n        {key: \"Five\", y: 4},\n        {key: \"Six\", y: 3},\n        {key: \"Seven\", y: 0.5}\n    ];\n\n    var width = 300;\n    var height = 300;\n\n    nv.addGraph(function() {\n        var chart = nv.models.pie()\n                .x(function(d) { return d.key; })\n                .y(function(d) { return d.y; })\n                .width(width)\n                .height(height)\n                .labelType(function(d, i, values) {\n                    return values.key + ':' + values.value;\n                })\n                ;\n\n        d3.select(\"#test1\")\n                .datum([testdata])\n                .transition().duration(1200)\n                .attr('width', width)\n                .attr('height', height)\n                .call(chart);\n\n        // LISTEN TO CLICK EVENTS ON THE PIE CONTAINER\n        // chart.dispatch.on('chartClick', function() {\n        //   code...\n        // });\n\n        // LISTEN TO CLICK EVENTS ON THE SLICES OF THE PIE\n        // chart.dispatch.on('elementClick', function() {\n        //   code...\n        // });\n\n        // OTHER EVENTS DISPATCHED BY THE PIE INCLUDE: elementDblClick, elementMouseover, elementMouseout, elementMousemove, renderEnd\n        // @see nv.models.pie\n        return chart;\n    });\n\n    nv.addGraph(function() {\n        var chart = nv.models.pie()\n                .x(function(d) { return d.key; })\n                .y(function(d) { return d.y; })\n                .width(width)\n                .height(height)\n                .labelType('percent')\n                .valueFormat(d3.format('%'))\n                .donut(true);\n\n        d3.select(\"#test2\")\n                .datum([testdata])\n                .transition().duration(1200)\n                .attr('width', width)\n                .attr('height', height)\n                .call(chart);\n\n        return chart;\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/pieChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n            float: left;\n            height: 350px !important;\n            width: 350px !important;\n        }\n        html, body {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<svg id=\"test1\" class=\"mypiechart\"></svg>\n<svg id=\"test2\" class=\"mypiechart\"></svg>\n\n<script>\n\n    var testdata = [\n        {key: \"One\", y: 5, color: \"#5F5\"},\n        {key: \"Two\", y: 2},\n        {key: \"Three\", y: 9},\n        {key: \"Four\", y: 7},\n        {key: \"Five\", y: 4},\n        {key: \"Six\", y: 3},\n        {key: \"Seven\", y: 0.5}\n    ];\n    var testdata2 = [\n        {key: \"One\", y: 5},\n        {key: \"Two\", y: 2},\n        {key: \"Three\", y: 9},\n        {key: \"Four\", y: 7},\n        {key: \"Five\", y: 4},\n        {key: \"Six\", y: 3},\n        {key: \"Seven\", y: 0.5}\n    ];\n\n    var height = 350;\n    var width = 350;\n\n    nv.addGraph(function() {\n        var chart = nv.models.pieChart()\n            .x(function(d) { return d.key })\n            .y(function(d) { return d.y })\n            .width(width)\n            .height(height)\n            .showTooltipPercent(true);\n\n        d3.select(\"#test1\")\n            .datum(testdata2)\n            .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n        // update chart data values randomly\n        setInterval(function() {\n            testdata2[0].y = Math.floor(Math.random() * 10);\n            testdata2[1].y = Math.floor(Math.random() * 10);\n            chart.update();\n        }, 4000);\n\n        return chart;\n    });\n\n    nv.addGraph(function() {\n        var chart = nv.models.pieChart()\n            .x(function(d) { return d.key })\n            .y(function(d) { return d.y })\n            //.labelThreshold(.08)\n            //.showLabels(false)\n            .color(d3.scale.category20().range().slice(8))\n            .growOnHover(false)\n            .labelType('value')\n            .width(width)\n            .height(height);\n\n        // make it a half circle\n        chart.pie\n            .startAngle(function(d) { return d.startAngle/2 -Math.PI/2 })\n            .endAngle(function(d) { return d.endAngle/2 -Math.PI/2 });\n\n        // MAKES LABELS OUTSIDE OF PIE/DONUT\n        //chart.pie.donutLabelsOutside(true).donut(true);\n\n        // LISTEN TO CLICK EVENTS ON SLICES OF THE PIE/DONUT\n        // chart.pie.dispatch.on('elementClick', function() {\n        //     code...\n        // });\n\n        // chart.pie.dispatch.on('chartClick', function() {\n        //     code...\n        // });\n\n        // LISTEN TO DOUBLECLICK EVENTS ON SLICES OF THE PIE/DONUT\n        // chart.pie.dispatch.on('elementDblClick', function() {\n        //     code...\n        // });\n\n        // LISTEN TO THE renderEnd EVENT OF THE PIE/DONUT\n        // chart.pie.dispatch.on('renderEnd', function() {\n        //     code...\n        // });\n\n        // OTHER EVENTS DISPATCHED BY THE PIE INCLUDE: elementMouseover, elementMouseout, elementMousemove\n        // @see nv.models.pie\n\n        d3.select(\"#test2\")\n            .datum(testdata)\n            .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n        // disable and enable some of the sections\n        var is_disabled = false;\n        setInterval(function() {\n            chart.dispatch.changeState({disabled: {2: !is_disabled, 4: !is_disabled}});\n            is_disabled = !is_disabled;\n        }, 3000);\n\n        return chart;\n    });\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/predicted.json",
    "content": "[{\"actual\":54.36052778662519,\"falling_edge\":\"2017-06-30 15:00:00+00:00\",\"predicted\":54.36052778662519,\"rising_edge\":\"2017-06-30 14:30:00+00:00\"},{\"actual\":49.25752740561633,\"falling_edge\":\"2017-06-30 15:30:00+00:00\",\"predicted\":49.25752740561633,\"rising_edge\":\"2017-06-30 15:00:00+00:00\"},{\"actual\":45.97036299597331,\"falling_edge\":\"2017-06-30 16:00:00+00:00\",\"predicted\":45.97036299597331,\"rising_edge\":\"2017-06-30 15:30:00+00:00\"},{\"actual\":45.69754186891356,\"falling_edge\":\"2017-06-30 16:30:00+00:00\",\"predicted\":45.69754186891356,\"rising_edge\":\"2017-06-30 16:00:00+00:00\"},{\"actual\":44.96142228319308,\"falling_edge\":\"2017-06-30 17:00:00+00:00\",\"predicted\":44.96142228319308,\"rising_edge\":\"2017-06-30 16:30:00+00:00\"},{\"actual\":45.51063026323638,\"falling_edge\":\"2017-06-30 17:30:00+00:00\",\"predicted\":45.51063026323638,\"rising_edge\":\"2017-06-30 17:00:00+00:00\"},{\"actual\":44.81584620790972,\"falling_edge\":\"2017-06-30 18:00:00+00:00\",\"predicted\":44.81584620790972,\"rising_edge\":\"2017-06-30 17:30:00+00:00\"},{\"actual\":45.80573558803053,\"falling_edge\":\"2017-06-30 18:30:00+00:00\",\"predicted\":45.80573558803053,\"rising_edge\":\"2017-06-30 18:00:00+00:00\"},{\"actual\":46.11541500651583,\"falling_edge\":\"2017-06-30 19:00:00+00:00\",\"predicted\":46.11541500651583,\"rising_edge\":\"2017-06-30 18:30:00+00:00\"},{\"actual\":46.70585318978923,\"falling_edge\":\"2017-06-30 19:30:00+00:00\",\"predicted\":46.70585318978923,\"rising_edge\":\"2017-06-30 19:00:00+00:00\"},{\"actual\":45.91226687808685,\"falling_edge\":\"2017-06-30 20:00:00+00:00\",\"predicted\":45.91226687808685,\"rising_edge\":\"2017-06-30 19:30:00+00:00\"},{\"actual\":46.94304983477127,\"falling_edge\":\"2017-06-30 20:30:00+00:00\",\"predicted\":46.94304983477127,\"rising_edge\":\"2017-06-30 20:00:00+00:00\"},{\"actual\":49.46970975296014,\"falling_edge\":\"2017-06-30 21:00:00+00:00\",\"predicted\":49.46970975296014,\"rising_edge\":\"2017-06-30 20:30:00+00:00\"},{\"actual\":57.20880426191144,\"falling_edge\":\"2017-06-30 21:30:00+00:00\",\"predicted\":57.20880426191144,\"rising_edge\":\"2017-06-30 21:00:00+00:00\"},{\"actual\":60.50737451332328,\"falling_edge\":\"2017-06-30 22:00:00+00:00\",\"predicted\":60.50737451332328,\"rising_edge\":\"2017-06-30 21:30:00+00:00\"},{\"actual\":59.89928779176659,\"falling_edge\":\"2017-06-30 22:30:00+00:00\",\"predicted\":59.89928779176659,\"rising_edge\":\"2017-06-30 22:00:00+00:00\"},{\"actual\":59.77592192471999,\"falling_edge\":\"2017-06-30 23:00:00+00:00\",\"predicted\":59.77592192471999,\"rising_edge\":\"2017-06-30 22:30:00+00:00\"},{\"actual\":61.81796629595747,\"falling_edge\":\"2017-06-30 23:30:00+00:00\",\"predicted\":61.81796629595747,\"rising_edge\":\"2017-06-30 23:00:00+00:00\"},{\"actual\":66.3791475823068,\"falling_edge\":\"2017-07-01 00:00:00+00:00\",\"predicted\":66.3791475823068,\"rising_edge\":\"2017-06-30 23:30:00+00:00\"},{\"actual\":74.63577600007757,\"falling_edge\":\"2017-07-01 00:30:00+00:00\",\"predicted\":74.63577600007757,\"rising_edge\":\"2017-07-01 00:00:00+00:00\"},{\"actual\":79.09750954598738,\"falling_edge\":\"2017-07-01 01:00:00+00:00\",\"predicted\":79.09750954598738,\"rising_edge\":\"2017-07-01 00:30:00+00:00\"},{\"actual\":81.08383752035148,\"falling_edge\":\"2017-07-01 01:30:00+00:00\",\"predicted\":81.08383752035148,\"rising_edge\":\"2017-07-01 01:00:00+00:00\"},{\"actual\":79.32401408084314,\"falling_edge\":\"2017-07-01 02:00:00+00:00\",\"predicted\":79.32401408084314,\"rising_edge\":\"2017-07-01 01:30:00+00:00\"},{\"actual\":78.75743002793175,\"falling_edge\":\"2017-07-01 02:30:00+00:00\",\"predicted\":78.75743002793175,\"rising_edge\":\"2017-07-01 02:00:00+00:00\"},{\"actual\":80.48505178613166,\"falling_edge\":\"2017-07-01 03:00:00+00:00\",\"predicted\":80.48505178613166,\"rising_edge\":\"2017-07-01 02:30:00+00:00\"},{\"actual\":80.43730739589051,\"falling_edge\":\"2017-07-01 03:30:00+00:00\",\"predicted\":80.43730739589051,\"rising_edge\":\"2017-07-01 03:00:00+00:00\"},{\"actual\":80.20103103338306,\"falling_edge\":\"2017-07-01 04:00:00+00:00\",\"predicted\":80.20103103338306,\"rising_edge\":\"2017-07-01 03:30:00+00:00\"},{\"actual\":82.38922943862532,\"falling_edge\":\"2017-07-01 04:30:00+00:00\",\"predicted\":82.38922943862532,\"rising_edge\":\"2017-07-01 04:00:00+00:00\"},{\"actual\":82.2086707828573,\"falling_edge\":\"2017-07-01 05:00:00+00:00\",\"predicted\":82.2086707828573,\"rising_edge\":\"2017-07-01 04:30:00+00:00\"},{\"actual\":81.21719807041764,\"falling_edge\":\"2017-07-01 05:30:00+00:00\",\"predicted\":81.21719807041764,\"rising_edge\":\"2017-07-01 05:00:00+00:00\"},{\"actual\":81.29197059018803,\"falling_edge\":\"2017-07-01 06:00:00+00:00\",\"predicted\":81.29197059018803,\"rising_edge\":\"2017-07-01 05:30:00+00:00\"},{\"actual\":80.24596040908925,\"falling_edge\":\"2017-07-01 06:30:00+00:00\",\"predicted\":80.24596040908925,\"rising_edge\":\"2017-07-01 06:00:00+00:00\"},{\"actual\":81.16692642003652,\"falling_edge\":\"2017-07-01 07:00:00+00:00\",\"predicted\":81.16692642003652,\"rising_edge\":\"2017-07-01 06:30:00+00:00\"},{\"actual\":80.94238324713203,\"falling_edge\":\"2017-07-01 07:30:00+00:00\",\"predicted\":80.94238324713203,\"rising_edge\":\"2017-07-01 07:00:00+00:00\"},{\"actual\":79.91177000871063,\"falling_edge\":\"2017-07-01 08:00:00+00:00\",\"predicted\":79.91177000871063,\"rising_edge\":\"2017-07-01 07:30:00+00:00\"},{\"actual\":79.67410395097966,\"falling_edge\":\"2017-07-01 08:30:00+00:00\",\"predicted\":79.67410395097966,\"rising_edge\":\"2017-07-01 08:00:00+00:00\"},{\"actual\":74.09976944544647,\"falling_edge\":\"2017-07-01 09:00:00+00:00\",\"predicted\":74.09976944544647,\"rising_edge\":\"2017-07-01 08:30:00+00:00\"},{\"actual\":66.02058605093278,\"falling_edge\":\"2017-07-01 09:30:00+00:00\",\"predicted\":66.02058605093278,\"rising_edge\":\"2017-07-01 09:00:00+00:00\"},{\"actual\":64.24119487731926,\"falling_edge\":\"2017-07-01 10:00:00+00:00\",\"predicted\":64.24119487731926,\"rising_edge\":\"2017-07-01 09:30:00+00:00\"},{\"actual\":61.36683608678591,\"falling_edge\":\"2017-07-01 10:30:00+00:00\",\"predicted\":61.36683608678591,\"rising_edge\":\"2017-07-01 10:00:00+00:00\"},{\"actual\":59.82711968413477,\"falling_edge\":\"2017-07-01 11:00:00+00:00\",\"predicted\":59.82711968413477,\"rising_edge\":\"2017-07-01 10:30:00+00:00\"},{\"actual\":59.22764761026551,\"falling_edge\":\"2017-07-01 11:30:00+00:00\",\"predicted\":59.22764761026551,\"rising_edge\":\"2017-07-01 11:00:00+00:00\"},{\"actual\":57.20063146986028,\"falling_edge\":\"2017-07-01 12:00:00+00:00\",\"predicted\":57.20063146986028,\"rising_edge\":\"2017-07-01 11:30:00+00:00\"},{\"actual\":53.34881763229704,\"falling_edge\":\"2017-07-01 12:30:00+00:00\",\"predicted\":53.34881763229704,\"rising_edge\":\"2017-07-01 12:00:00+00:00\"},{\"actual\":51.87665409591391,\"falling_edge\":\"2017-07-01 13:00:00+00:00\",\"predicted\":51.87665409591391,\"rising_edge\":\"2017-07-01 12:30:00+00:00\"},{\"actual\":51.21397006112933,\"falling_edge\":\"2017-07-01 13:30:00+00:00\",\"predicted\":51.21397006112933,\"rising_edge\":\"2017-07-01 13:00:00+00:00\"},{\"actual\":50.43194125544224,\"falling_edge\":\"2017-07-01 14:00:00+00:00\",\"predicted\":50.43194125544224,\"rising_edge\":\"2017-07-01 13:30:00+00:00\"},{\"actual\":48.46624792680034,\"falling_edge\":\"2017-07-01 14:30:00+00:00\",\"predicted\":48.46624792680034,\"rising_edge\":\"2017-07-01 14:00:00+00:00\"},{\"actual\":47.55846048009032,\"falling_edge\":\"2017-07-01 15:00:00+00:00\",\"predicted\":47.55846048009032,\"rising_edge\":\"2017-07-01 14:30:00+00:00\"},{\"actual\":47.42054001869748,\"falling_edge\":\"2017-07-01 15:30:00+00:00\",\"predicted\":47.42054001869748,\"rising_edge\":\"2017-07-01 15:00:00+00:00\"},{\"actual\":45.91448887024012,\"falling_edge\":\"2017-07-01 16:00:00+00:00\",\"predicted\":45.91448887024012,\"rising_edge\":\"2017-07-01 15:30:00+00:00\"},{\"actual\":46.14057830037459,\"falling_edge\":\"2017-07-01 16:30:00+00:00\",\"predicted\":46.14057830037459,\"rising_edge\":\"2017-07-01 16:00:00+00:00\"},{\"actual\":45.237418259578455,\"falling_edge\":\"2017-07-01 17:00:00+00:00\",\"predicted\":45.237418259578455,\"rising_edge\":\"2017-07-01 16:30:00+00:00\"},{\"actual\":45.48823819473981,\"falling_edge\":\"2017-07-01 17:30:00+00:00\",\"predicted\":45.48823819473981,\"rising_edge\":\"2017-07-01 17:00:00+00:00\"},{\"actual\":44.9591970510554,\"falling_edge\":\"2017-07-01 18:00:00+00:00\",\"predicted\":44.9591970510554,\"rising_edge\":\"2017-07-01 17:30:00+00:00\"},{\"actual\":45.22021512909244,\"falling_edge\":\"2017-07-01 18:30:00+00:00\",\"predicted\":45.22021512909244,\"rising_edge\":\"2017-07-01 18:00:00+00:00\"},{\"actual\":45.16931711454131,\"falling_edge\":\"2017-07-01 19:00:00+00:00\",\"predicted\":45.16931711454131,\"rising_edge\":\"2017-07-01 18:30:00+00:00\"},{\"actual\":45.14677973852566,\"falling_edge\":\"2017-07-01 19:30:00+00:00\",\"predicted\":45.14677973852566,\"rising_edge\":\"2017-07-01 19:00:00+00:00\"},{\"actual\":45.541281323330544,\"falling_edge\":\"2017-07-01 20:00:00+00:00\",\"predicted\":45.541281323330544,\"rising_edge\":\"2017-07-01 19:30:00+00:00\"},{\"actual\":45.36200363180318,\"falling_edge\":\"2017-07-01 20:30:00+00:00\",\"predicted\":45.36200363180318,\"rising_edge\":\"2017-07-01 20:00:00+00:00\"},{\"actual\":46.42421948837546,\"falling_edge\":\"2017-07-01 21:00:00+00:00\",\"predicted\":46.42421948837546,\"rising_edge\":\"2017-07-01 20:30:00+00:00\"},{\"actual\":47.075449847550836,\"falling_edge\":\"2017-07-01 21:30:00+00:00\",\"predicted\":47.075449847550836,\"rising_edge\":\"2017-07-01 21:00:00+00:00\"},{\"actual\":49.44981600501445,\"falling_edge\":\"2017-07-01 22:00:00+00:00\",\"predicted\":49.44981600501445,\"rising_edge\":\"2017-07-01 21:30:00+00:00\"},{\"actual\":50.84130454890258,\"falling_edge\":\"2017-07-01 22:30:00+00:00\",\"predicted\":50.84130454890258,\"rising_edge\":\"2017-07-01 22:00:00+00:00\"},{\"actual\":51.09754406356962,\"falling_edge\":\"2017-07-01 23:00:00+00:00\",\"predicted\":51.09754406356962,\"rising_edge\":\"2017-07-01 22:30:00+00:00\"},{\"actual\":55.34219798418586,\"falling_edge\":\"2017-07-01 23:30:00+00:00\",\"predicted\":55.34219798418586,\"rising_edge\":\"2017-07-01 23:00:00+00:00\"},{\"actual\":58.53543962885969,\"falling_edge\":\"2017-07-02 00:00:00+00:00\",\"predicted\":58.53543962885969,\"rising_edge\":\"2017-07-01 23:30:00+00:00\"},{\"actual\":64.17186348629046,\"falling_edge\":\"2017-07-02 00:30:00+00:00\",\"predicted\":64.17186348629046,\"rising_edge\":\"2017-07-02 00:00:00+00:00\"},{\"actual\":67.1449824819642,\"falling_edge\":\"2017-07-02 01:00:00+00:00\",\"predicted\":67.1449824819642,\"rising_edge\":\"2017-07-02 00:30:00+00:00\"},{\"actual\":68.14869969521473,\"falling_edge\":\"2017-07-02 01:30:00+00:00\",\"predicted\":68.14869969521473,\"rising_edge\":\"2017-07-02 01:00:00+00:00\"},{\"actual\":68.43420736889522,\"falling_edge\":\"2017-07-02 02:00:00+00:00\",\"predicted\":68.43420736889522,\"rising_edge\":\"2017-07-02 01:30:00+00:00\"},{\"actual\":68.99108231782868,\"falling_edge\":\"2017-07-02 02:30:00+00:00\",\"predicted\":68.99108231782868,\"rising_edge\":\"2017-07-02 02:00:00+00:00\"},{\"actual\":69.50994005537758,\"falling_edge\":\"2017-07-02 03:00:00+00:00\",\"predicted\":69.50994005537758,\"rising_edge\":\"2017-07-02 02:30:00+00:00\"},{\"actual\":70.13241800877181,\"falling_edge\":\"2017-07-02 03:30:00+00:00\",\"predicted\":70.13241800877181,\"rising_edge\":\"2017-07-02 03:00:00+00:00\"},{\"actual\":69.80983414428287,\"falling_edge\":\"2017-07-02 04:00:00+00:00\",\"predicted\":69.80983414428287,\"rising_edge\":\"2017-07-02 03:30:00+00:00\"},{\"actual\":74.62118046165294,\"falling_edge\":\"2017-07-02 04:30:00+00:00\",\"predicted\":74.62118046165294,\"rising_edge\":\"2017-07-02 04:00:00+00:00\"},{\"actual\":74.73757039210626,\"falling_edge\":\"2017-07-02 05:00:00+00:00\",\"predicted\":74.73757039210626,\"rising_edge\":\"2017-07-02 04:30:00+00:00\"},{\"actual\":76.67503653867307,\"falling_edge\":\"2017-07-02 05:30:00+00:00\",\"predicted\":76.67503653867307,\"rising_edge\":\"2017-07-02 05:00:00+00:00\"},{\"actual\":73.85896058857453,\"falling_edge\":\"2017-07-02 06:00:00+00:00\",\"predicted\":73.85896058857453,\"rising_edge\":\"2017-07-02 05:30:00+00:00\"},{\"actual\":75.55083230541204,\"falling_edge\":\"2017-07-02 06:30:00+00:00\",\"predicted\":75.55083230541204,\"rising_edge\":\"2017-07-02 06:00:00+00:00\"},{\"actual\":77.62091779033874,\"falling_edge\":\"2017-07-02 07:00:00+00:00\",\"predicted\":77.62091779033874,\"rising_edge\":\"2017-07-02 06:30:00+00:00\"},{\"actual\":77.84908794003042,\"falling_edge\":\"2017-07-02 07:30:00+00:00\",\"predicted\":77.84908794003042,\"rising_edge\":\"2017-07-02 07:00:00+00:00\"},{\"actual\":74.16839605769886,\"falling_edge\":\"2017-07-02 08:00:00+00:00\",\"predicted\":74.16839605769886,\"rising_edge\":\"2017-07-02 07:30:00+00:00\"},{\"actual\":72.37737212495318,\"falling_edge\":\"2017-07-02 08:30:00+00:00\",\"predicted\":72.37737212495318,\"rising_edge\":\"2017-07-02 08:00:00+00:00\"},{\"actual\":70.06326663892881,\"falling_edge\":\"2017-07-02 09:00:00+00:00\",\"predicted\":70.06326663892881,\"rising_edge\":\"2017-07-02 08:30:00+00:00\"},{\"actual\":65.99219528269568,\"falling_edge\":\"2017-07-02 09:30:00+00:00\",\"predicted\":65.99219528269568,\"rising_edge\":\"2017-07-02 09:00:00+00:00\"},{\"actual\":64.52418315857481,\"falling_edge\":\"2017-07-02 10:00:00+00:00\",\"predicted\":64.52418315857481,\"rising_edge\":\"2017-07-02 09:30:00+00:00\"},{\"actual\":60.834100547053126,\"falling_edge\":\"2017-07-02 10:30:00+00:00\",\"predicted\":60.834100547053126,\"rising_edge\":\"2017-07-02 10:00:00+00:00\"},{\"actual\":59.081976319821486,\"falling_edge\":\"2017-07-02 11:00:00+00:00\",\"predicted\":59.081976319821486,\"rising_edge\":\"2017-07-02 10:30:00+00:00\"},{\"actual\":57.53121767348194,\"falling_edge\":\"2017-07-02 11:30:00+00:00\",\"predicted\":57.53121767348194,\"rising_edge\":\"2017-07-02 11:00:00+00:00\"},{\"actual\":57.65267955101386,\"falling_edge\":\"2017-07-02 12:00:00+00:00\",\"predicted\":57.65267955101386,\"rising_edge\":\"2017-07-02 11:30:00+00:00\"},{\"actual\":54.284438270111345,\"falling_edge\":\"2017-07-02 12:30:00+00:00\",\"predicted\":54.284438270111345,\"rising_edge\":\"2017-07-02 12:00:00+00:00\"},{\"actual\":52.77685437669969,\"falling_edge\":\"2017-07-02 13:00:00+00:00\",\"predicted\":52.77685437669969,\"rising_edge\":\"2017-07-02 12:30:00+00:00\"},{\"actual\":51.85972974521758,\"falling_edge\":\"2017-07-02 13:30:00+00:00\",\"predicted\":51.85972974521758,\"rising_edge\":\"2017-07-02 13:00:00+00:00\"},{\"actual\":49.97948400406949,\"falling_edge\":\"2017-07-02 14:00:00+00:00\",\"predicted\":49.97948400406949,\"rising_edge\":\"2017-07-02 13:30:00+00:00\"},{\"actual\":50.887978015841604,\"falling_edge\":\"2017-07-02 14:30:00+00:00\",\"predicted\":50.887978015841604,\"rising_edge\":\"2017-07-02 14:00:00+00:00\"},{\"actual\":48.954231611651814,\"falling_edge\":\"2017-07-02 15:00:00+00:00\",\"predicted\":48.954231611651814,\"rising_edge\":\"2017-07-02 14:30:00+00:00\"},{\"actual\":48.52063029612959,\"falling_edge\":\"2017-07-02 15:30:00+00:00\",\"predicted\":48.52063029612959,\"rising_edge\":\"2017-07-02 15:00:00+00:00\"},{\"actual\":47.983999006898934,\"falling_edge\":\"2017-07-02 16:00:00+00:00\",\"predicted\":47.983999006898934,\"rising_edge\":\"2017-07-02 15:30:00+00:00\"},{\"actual\":48.689075217937074,\"falling_edge\":\"2017-07-02 16:30:00+00:00\",\"predicted\":48.689075217937074,\"rising_edge\":\"2017-07-02 16:00:00+00:00\"},{\"actual\":47.3038195607827,\"falling_edge\":\"2017-07-02 17:00:00+00:00\",\"predicted\":47.3038195607827,\"rising_edge\":\"2017-07-02 16:30:00+00:00\"},{\"actual\":46.39695851232495,\"falling_edge\":\"2017-07-02 17:30:00+00:00\",\"predicted\":46.39695851232495,\"rising_edge\":\"2017-07-02 17:00:00+00:00\"},{\"actual\":47.076498405897496,\"falling_edge\":\"2017-07-02 18:00:00+00:00\",\"predicted\":47.076498405897496,\"rising_edge\":\"2017-07-02 17:30:00+00:00\"},{\"actual\":46.4681151249321,\"falling_edge\":\"2017-07-02 18:30:00+00:00\",\"predicted\":46.4681151249321,\"rising_edge\":\"2017-07-02 18:00:00+00:00\"},{\"actual\":46.637521782491824,\"falling_edge\":\"2017-07-02 19:00:00+00:00\",\"predicted\":46.637521782491824,\"rising_edge\":\"2017-07-02 18:30:00+00:00\"},{\"actual\":45.91397317194595,\"falling_edge\":\"2017-07-02 19:30:00+00:00\",\"predicted\":45.91397317194595,\"rising_edge\":\"2017-07-02 19:00:00+00:00\"},{\"actual\":46.559729245939856,\"falling_edge\":\"2017-07-02 20:00:00+00:00\",\"predicted\":46.559729245939856,\"rising_edge\":\"2017-07-02 19:30:00+00:00\"},{\"actual\":47.26266271816268,\"falling_edge\":\"2017-07-02 20:30:00+00:00\",\"predicted\":47.26266271816268,\"rising_edge\":\"2017-07-02 20:00:00+00:00\"},{\"actual\":52.3805261519144,\"falling_edge\":\"2017-07-02 21:00:00+00:00\",\"predicted\":52.3805261519144,\"rising_edge\":\"2017-07-02 20:30:00+00:00\"},{\"actual\":70.18451402372149,\"falling_edge\":\"2017-07-02 21:30:00+00:00\",\"predicted\":70.18451402372149,\"rising_edge\":\"2017-07-02 21:00:00+00:00\"},{\"actual\":126.43190466333122,\"falling_edge\":\"2017-07-02 22:00:00+00:00\",\"predicted\":126.43190466333122,\"rising_edge\":\"2017-07-02 21:30:00+00:00\"},{\"actual\":110.43336098547563,\"falling_edge\":\"2017-07-02 22:30:00+00:00\",\"predicted\":110.43336098547563,\"rising_edge\":\"2017-07-02 22:00:00+00:00\"},{\"actual\":130.28709204015158,\"falling_edge\":\"2017-07-02 23:00:00+00:00\",\"predicted\":130.28709204015158,\"rising_edge\":\"2017-07-02 22:30:00+00:00\"},{\"actual\":158.78563708276837,\"falling_edge\":\"2017-07-02 23:30:00+00:00\",\"predicted\":158.78563708276837,\"rising_edge\":\"2017-07-02 23:00:00+00:00\"},{\"actual\":200.9486331291908,\"falling_edge\":\"2017-07-03 00:00:00+00:00\",\"predicted\":200.9486331291908,\"rising_edge\":\"2017-07-02 23:30:00+00:00\"},{\"actual\":214.46453849301008,\"falling_edge\":\"2017-07-03 00:30:00+00:00\",\"predicted\":214.46453849301008,\"rising_edge\":\"2017-07-03 00:00:00+00:00\"},{\"actual\":217.0850665211394,\"falling_edge\":\"2017-07-03 01:00:00+00:00\",\"predicted\":217.0850665211394,\"rising_edge\":\"2017-07-03 00:30:00+00:00\"},{\"actual\":224.22945030325843,\"falling_edge\":\"2017-07-03 01:30:00+00:00\",\"predicted\":224.22945030325843,\"rising_edge\":\"2017-07-03 01:00:00+00:00\"},{\"actual\":222.84273348587007,\"falling_edge\":\"2017-07-03 02:00:00+00:00\",\"predicted\":222.84273348587007,\"rising_edge\":\"2017-07-03 01:30:00+00:00\"},{\"actual\":220.09697035299473,\"falling_edge\":\"2017-07-03 02:30:00+00:00\",\"predicted\":220.09697035299473,\"rising_edge\":\"2017-07-03 02:00:00+00:00\"},{\"actual\":218.25679923261276,\"falling_edge\":\"2017-07-03 03:00:00+00:00\",\"predicted\":218.25679923261276,\"rising_edge\":\"2017-07-03 02:30:00+00:00\"},{\"actual\":214.14184659781358,\"falling_edge\":\"2017-07-03 03:30:00+00:00\",\"predicted\":214.14184659781358,\"rising_edge\":\"2017-07-03 03:00:00+00:00\"},{\"actual\":196.8695402471554,\"falling_edge\":\"2017-07-03 04:00:00+00:00\",\"predicted\":196.8695402471554,\"rising_edge\":\"2017-07-03 03:30:00+00:00\"},{\"actual\":211.12859338435453,\"falling_edge\":\"2017-07-03 04:30:00+00:00\",\"predicted\":211.12859338435453,\"rising_edge\":\"2017-07-03 04:00:00+00:00\"},{\"actual\":208.50923966422005,\"falling_edge\":\"2017-07-03 05:00:00+00:00\",\"predicted\":208.50923966422005,\"rising_edge\":\"2017-07-03 04:30:00+00:00\"},{\"actual\":206.35827313633422,\"falling_edge\":\"2017-07-03 05:30:00+00:00\",\"predicted\":206.35827313633422,\"rising_edge\":\"2017-07-03 05:00:00+00:00\"},{\"actual\":207.52451288695616,\"falling_edge\":\"2017-07-03 06:00:00+00:00\",\"predicted\":207.52451288695616,\"rising_edge\":\"2017-07-03 05:30:00+00:00\"},{\"actual\":213.04807708221347,\"falling_edge\":\"2017-07-03 06:30:00+00:00\",\"predicted\":213.04807708221347,\"rising_edge\":\"2017-07-03 06:00:00+00:00\"},{\"actual\":215.24766745916344,\"falling_edge\":\"2017-07-03 07:00:00+00:00\",\"predicted\":215.24766745916344,\"rising_edge\":\"2017-07-03 06:30:00+00:00\"},{\"actual\":211.52467410138468,\"falling_edge\":\"2017-07-03 07:30:00+00:00\",\"predicted\":211.52467410138468,\"rising_edge\":\"2017-07-03 07:00:00+00:00\"},{\"actual\":208.49670519376502,\"falling_edge\":\"2017-07-03 08:00:00+00:00\",\"predicted\":208.49670519376502,\"rising_edge\":\"2017-07-03 07:30:00+00:00\"},{\"actual\":211.66347951676593,\"falling_edge\":\"2017-07-03 08:30:00+00:00\",\"predicted\":211.66347951676593,\"rising_edge\":\"2017-07-03 08:00:00+00:00\"},{\"actual\":198.8631678923863,\"falling_edge\":\"2017-07-03 09:00:00+00:00\",\"predicted\":198.8631678923863,\"rising_edge\":\"2017-07-03 08:30:00+00:00\"},{\"actual\":170.70797622671887,\"falling_edge\":\"2017-07-03 09:30:00+00:00\",\"predicted\":170.70797622671887,\"rising_edge\":\"2017-07-03 09:00:00+00:00\"},{\"actual\":158.07526827270505,\"falling_edge\":\"2017-07-03 10:00:00+00:00\",\"predicted\":158.07526827270505,\"rising_edge\":\"2017-07-03 09:30:00+00:00\"},{\"actual\":135.4388861733956,\"falling_edge\":\"2017-07-03 10:30:00+00:00\",\"predicted\":135.4388861733956,\"rising_edge\":\"2017-07-03 10:00:00+00:00\"},{\"actual\":131.74151918488468,\"falling_edge\":\"2017-07-03 11:00:00+00:00\",\"predicted\":131.74151918488468,\"rising_edge\":\"2017-07-03 10:30:00+00:00\"},{\"actual\":124.163227699957,\"falling_edge\":\"2017-07-03 11:30:00+00:00\",\"predicted\":124.163227699957,\"rising_edge\":\"2017-07-03 11:00:00+00:00\"},{\"actual\":112.2088041121433,\"falling_edge\":\"2017-07-03 12:00:00+00:00\",\"predicted\":112.2088041121433,\"rising_edge\":\"2017-07-03 11:30:00+00:00\"},{\"actual\":101.04678931510966,\"falling_edge\":\"2017-07-03 12:30:00+00:00\",\"predicted\":101.04678931510966,\"rising_edge\":\"2017-07-03 12:00:00+00:00\"},{\"actual\":93.36111416486159,\"falling_edge\":\"2017-07-03 13:00:00+00:00\",\"predicted\":93.36111416486159,\"rising_edge\":\"2017-07-03 12:30:00+00:00\"},{\"actual\":85.58114685081433,\"falling_edge\":\"2017-07-03 13:30:00+00:00\",\"predicted\":85.58114685081433,\"rising_edge\":\"2017-07-03 13:00:00+00:00\"},{\"actual\":74.20860960413054,\"falling_edge\":\"2017-07-03 14:00:00+00:00\",\"predicted\":74.20860960413054,\"rising_edge\":\"2017-07-03 13:30:00+00:00\"},{\"actual\":64.1624151850402,\"falling_edge\":\"2017-07-03 14:30:00+00:00\",\"predicted\":64.1624151850402,\"rising_edge\":\"2017-07-03 14:00:00+00:00\"},{\"actual\":56.91119643748203,\"falling_edge\":\"2017-07-03 15:00:00+00:00\",\"predicted\":56.91119643748203,\"rising_edge\":\"2017-07-03 14:30:00+00:00\"},{\"actual\":52.06326229726732,\"falling_edge\":\"2017-07-03 15:30:00+00:00\",\"predicted\":52.06326229726732,\"rising_edge\":\"2017-07-03 15:00:00+00:00\"},{\"actual\":47.86406831736378,\"falling_edge\":\"2017-07-03 16:00:00+00:00\",\"predicted\":47.86406831736378,\"rising_edge\":\"2017-07-03 15:30:00+00:00\"},{\"actual\":46.70266335100992,\"falling_edge\":\"2017-07-03 16:30:00+00:00\",\"predicted\":46.70266335100992,\"rising_edge\":\"2017-07-03 16:00:00+00:00\"},{\"actual\":46.13170476216933,\"falling_edge\":\"2017-07-03 17:00:00+00:00\",\"predicted\":46.13170476216933,\"rising_edge\":\"2017-07-03 16:30:00+00:00\"},{\"actual\":46.050663802369044,\"falling_edge\":\"2017-07-03 17:30:00+00:00\",\"predicted\":46.050663802369044,\"rising_edge\":\"2017-07-03 17:00:00+00:00\"},{\"actual\":45.35372089340315,\"falling_edge\":\"2017-07-03 18:00:00+00:00\",\"predicted\":45.35372089340315,\"rising_edge\":\"2017-07-03 17:30:00+00:00\"},{\"actual\":45.21408423915497,\"falling_edge\":\"2017-07-03 18:30:00+00:00\",\"predicted\":45.21408423915497,\"rising_edge\":\"2017-07-03 18:00:00+00:00\"},{\"actual\":44.6246001926098,\"falling_edge\":\"2017-07-03 19:00:00+00:00\",\"predicted\":44.6246001926098,\"rising_edge\":\"2017-07-03 18:30:00+00:00\"},{\"actual\":45.02464315609231,\"falling_edge\":\"2017-07-03 19:30:00+00:00\",\"predicted\":45.02464315609231,\"rising_edge\":\"2017-07-03 19:00:00+00:00\"},{\"actual\":44.28952208801992,\"falling_edge\":\"2017-07-03 20:00:00+00:00\",\"predicted\":44.28952208801992,\"rising_edge\":\"2017-07-03 19:30:00+00:00\"},{\"actual\":46.28182759177426,\"falling_edge\":\"2017-07-03 20:30:00+00:00\",\"predicted\":46.28182759177426,\"rising_edge\":\"2017-07-03 20:00:00+00:00\"},{\"actual\":51.13249694957967,\"falling_edge\":\"2017-07-03 21:00:00+00:00\",\"predicted\":51.13249694957967,\"rising_edge\":\"2017-07-03 20:30:00+00:00\"},{\"actual\":67.86006060681797,\"falling_edge\":\"2017-07-03 21:30:00+00:00\",\"predicted\":67.86006060681797,\"rising_edge\":\"2017-07-03 21:00:00+00:00\"},{\"actual\":106.71198206573257,\"falling_edge\":\"2017-07-03 22:00:00+00:00\",\"predicted\":106.71198206573257,\"rising_edge\":\"2017-07-03 21:30:00+00:00\"},{\"actual\":104.84381714930883,\"falling_edge\":\"2017-07-03 22:30:00+00:00\",\"predicted\":104.84381714930883,\"rising_edge\":\"2017-07-03 22:00:00+00:00\"},{\"actual\":130.71156885234706,\"falling_edge\":\"2017-07-03 23:00:00+00:00\",\"predicted\":130.71156885234706,\"rising_edge\":\"2017-07-03 22:30:00+00:00\"},{\"actual\":166.7766199871199,\"falling_edge\":\"2017-07-03 23:30:00+00:00\",\"predicted\":166.7766199871199,\"rising_edge\":\"2017-07-03 23:00:00+00:00\"},{\"actual\":205.32041834128827,\"falling_edge\":\"2017-07-04 00:00:00+00:00\",\"predicted\":205.32041834128827,\"rising_edge\":\"2017-07-03 23:30:00+00:00\"},{\"actual\":213.01962931317627,\"falling_edge\":\"2017-07-04 00:30:00+00:00\",\"predicted\":213.01962931317627,\"rising_edge\":\"2017-07-04 00:00:00+00:00\"},{\"actual\":217.56849658186587,\"falling_edge\":\"2017-07-04 01:00:00+00:00\",\"predicted\":217.56849658186587,\"rising_edge\":\"2017-07-04 00:30:00+00:00\"},{\"actual\":217.2340318973378,\"falling_edge\":\"2017-07-04 01:30:00+00:00\",\"predicted\":217.2340318973378,\"rising_edge\":\"2017-07-04 01:00:00+00:00\"},{\"actual\":216.82869065718876,\"falling_edge\":\"2017-07-04 02:00:00+00:00\",\"predicted\":216.82869065718876,\"rising_edge\":\"2017-07-04 01:30:00+00:00\"},{\"actual\":209.45032311899917,\"falling_edge\":\"2017-07-04 02:30:00+00:00\",\"predicted\":209.45032311899917,\"rising_edge\":\"2017-07-04 02:00:00+00:00\"},{\"actual\":200.49969089924105,\"falling_edge\":\"2017-07-04 03:00:00+00:00\",\"predicted\":200.49969089924105,\"rising_edge\":\"2017-07-04 02:30:00+00:00\"},{\"actual\":193.37270748786574,\"falling_edge\":\"2017-07-04 03:30:00+00:00\",\"predicted\":193.37270748786574,\"rising_edge\":\"2017-07-04 03:00:00+00:00\"},{\"actual\":187.39077012007468,\"falling_edge\":\"2017-07-04 04:00:00+00:00\",\"predicted\":187.39077012007468,\"rising_edge\":\"2017-07-04 03:30:00+00:00\"},{\"actual\":196.5540199820921,\"falling_edge\":\"2017-07-04 04:30:00+00:00\",\"predicted\":196.5540199820921,\"rising_edge\":\"2017-07-04 04:00:00+00:00\"},{\"actual\":194.96322204578237,\"falling_edge\":\"2017-07-04 05:00:00+00:00\",\"predicted\":194.96322204578237,\"rising_edge\":\"2017-07-04 04:30:00+00:00\"},{\"actual\":192.1558888059677,\"falling_edge\":\"2017-07-04 05:30:00+00:00\",\"predicted\":192.1558888059677,\"rising_edge\":\"2017-07-04 05:00:00+00:00\"},{\"actual\":199.30324053199317,\"falling_edge\":\"2017-07-04 06:00:00+00:00\",\"predicted\":199.30324053199317,\"rising_edge\":\"2017-07-04 05:30:00+00:00\"},{\"actual\":197.0280186007689,\"falling_edge\":\"2017-07-04 06:30:00+00:00\",\"predicted\":197.0280186007689,\"rising_edge\":\"2017-07-04 06:00:00+00:00\"},{\"actual\":198.84627915778643,\"falling_edge\":\"2017-07-04 07:00:00+00:00\",\"predicted\":198.84627915778643,\"rising_edge\":\"2017-07-04 06:30:00+00:00\"},{\"actual\":196.57177910486186,\"falling_edge\":\"2017-07-04 07:30:00+00:00\",\"predicted\":196.57177910486186,\"rising_edge\":\"2017-07-04 07:00:00+00:00\"},{\"actual\":196.30647705982346,\"falling_edge\":\"2017-07-04 08:00:00+00:00\",\"predicted\":196.30647705982346,\"rising_edge\":\"2017-07-04 07:30:00+00:00\"},{\"actual\":201.45496467317975,\"falling_edge\":\"2017-07-04 08:30:00+00:00\",\"predicted\":201.45496467317975,\"rising_edge\":\"2017-07-04 08:00:00+00:00\"},{\"actual\":196.1229852292311,\"falling_edge\":\"2017-07-04 09:00:00+00:00\",\"predicted\":196.1229852292311,\"rising_edge\":\"2017-07-04 08:30:00+00:00\"},{\"actual\":168.38448300193082,\"falling_edge\":\"2017-07-04 09:30:00+00:00\",\"predicted\":168.38448300193082,\"rising_edge\":\"2017-07-04 09:00:00+00:00\"},{\"actual\":157.6615934247332,\"falling_edge\":\"2017-07-04 10:00:00+00:00\",\"predicted\":157.6615934247332,\"rising_edge\":\"2017-07-04 09:30:00+00:00\"},{\"actual\":138.6120149991092,\"falling_edge\":\"2017-07-04 10:30:00+00:00\",\"predicted\":138.6120149991092,\"rising_edge\":\"2017-07-04 10:00:00+00:00\"},{\"actual\":136.17920760335997,\"falling_edge\":\"2017-07-04 11:00:00+00:00\",\"predicted\":136.17920760335997,\"rising_edge\":\"2017-07-04 10:30:00+00:00\"},{\"actual\":129.16347866979476,\"falling_edge\":\"2017-07-04 11:30:00+00:00\",\"predicted\":129.16347866979476,\"rising_edge\":\"2017-07-04 11:00:00+00:00\"},{\"actual\":119.58863195965827,\"falling_edge\":\"2017-07-04 12:00:00+00:00\",\"predicted\":119.58863195965827,\"rising_edge\":\"2017-07-04 11:30:00+00:00\"},{\"actual\":108.83173594473458,\"falling_edge\":\"2017-07-04 12:30:00+00:00\",\"predicted\":108.83173594473458,\"rising_edge\":\"2017-07-04 12:00:00+00:00\"},{\"actual\":97.35865966527088,\"falling_edge\":\"2017-07-04 13:00:00+00:00\",\"predicted\":97.35865966527088,\"rising_edge\":\"2017-07-04 12:30:00+00:00\"},{\"actual\":88.79889895978643,\"falling_edge\":\"2017-07-04 13:30:00+00:00\",\"predicted\":88.79889895978643,\"rising_edge\":\"2017-07-04 13:00:00+00:00\"},{\"actual\":75.62947229792867,\"falling_edge\":\"2017-07-04 14:00:00+00:00\",\"predicted\":75.62947229792867,\"rising_edge\":\"2017-07-04 13:30:00+00:00\"},{\"actual\":65.39702207103429,\"falling_edge\":\"2017-07-04 14:30:00+00:00\",\"predicted\":65.39702207103429,\"rising_edge\":\"2017-07-04 14:00:00+00:00\"},{\"actual\":58.09814842581181,\"falling_edge\":\"2017-07-04 15:00:00+00:00\",\"predicted\":58.09814842581181,\"rising_edge\":\"2017-07-04 14:30:00+00:00\"},{\"actual\":54.419085926775985,\"falling_edge\":\"2017-08-08 15:30:00+00:00\",\"predicted\":54.419085926775985,\"rising_edge\":\"2017-08-08 15:00:00+00:00\"},{\"actual\":51.23820847348304,\"falling_edge\":\"2017-08-08 16:00:00+00:00\",\"predicted\":51.23820847348304,\"rising_edge\":\"2017-08-08 15:30:00+00:00\"},{\"actual\":52.336659700061105,\"falling_edge\":\"2017-08-08 16:30:00+00:00\",\"predicted\":52.336659700061105,\"rising_edge\":\"2017-08-08 16:00:00+00:00\"},{\"actual\":49.459448624949,\"falling_edge\":\"2017-08-08 17:00:00+00:00\",\"predicted\":49.459448624949,\"rising_edge\":\"2017-08-08 16:30:00+00:00\"},{\"actual\":48.258249389230784,\"falling_edge\":\"2017-08-08 17:30:00+00:00\",\"predicted\":48.258249389230784,\"rising_edge\":\"2017-08-08 17:00:00+00:00\"},{\"actual\":47.86282913085337,\"falling_edge\":\"2017-08-08 18:00:00+00:00\",\"predicted\":47.86282913085337,\"rising_edge\":\"2017-08-08 17:30:00+00:00\"},{\"actual\":45.879065348711435,\"falling_edge\":\"2017-08-08 18:30:00+00:00\",\"predicted\":45.879065348711435,\"rising_edge\":\"2017-08-08 18:00:00+00:00\"},{\"actual\":44.76760502584984,\"falling_edge\":\"2017-08-08 19:00:00+00:00\",\"predicted\":44.76760502584984,\"rising_edge\":\"2017-08-08 18:30:00+00:00\"},{\"actual\":45.99671317866938,\"falling_edge\":\"2017-08-08 19:30:00+00:00\",\"predicted\":45.99671317866938,\"rising_edge\":\"2017-08-08 19:00:00+00:00\"},{\"actual\":46.059930781987724,\"falling_edge\":\"2017-08-08 20:00:00+00:00\",\"predicted\":46.059930781987724,\"rising_edge\":\"2017-08-08 19:30:00+00:00\"},{\"actual\":47.49826695511959,\"falling_edge\":\"2017-08-08 20:30:00+00:00\",\"predicted\":47.49826695511959,\"rising_edge\":\"2017-08-08 20:00:00+00:00\"},{\"actual\":52.479354790599636,\"falling_edge\":\"2017-08-08 21:00:00+00:00\",\"predicted\":52.479354790599636,\"rising_edge\":\"2017-08-08 20:30:00+00:00\"},{\"actual\":70.19004598012893,\"falling_edge\":\"2017-08-08 21:30:00+00:00\",\"predicted\":70.19004598012893,\"rising_edge\":\"2017-08-08 21:00:00+00:00\"},{\"actual\":102.89920780007665,\"falling_edge\":\"2017-08-08 22:00:00+00:00\",\"predicted\":102.89920780007665,\"rising_edge\":\"2017-08-08 21:30:00+00:00\"},{\"actual\":99.58516453179436,\"falling_edge\":\"2017-08-08 22:30:00+00:00\",\"predicted\":99.58516453179436,\"rising_edge\":\"2017-08-08 22:00:00+00:00\"},{\"actual\":122.53490272879391,\"falling_edge\":\"2017-08-08 23:00:00+00:00\",\"predicted\":122.53490272879391,\"rising_edge\":\"2017-08-08 22:30:00+00:00\"},{\"actual\":168.05066249271073,\"falling_edge\":\"2017-08-08 23:30:00+00:00\",\"predicted\":168.05066249271073,\"rising_edge\":\"2017-08-08 23:00:00+00:00\"},{\"actual\":209.6246274131777,\"falling_edge\":\"2017-08-09 00:00:00+00:00\",\"predicted\":209.6246274131777,\"rising_edge\":\"2017-08-08 23:30:00+00:00\"},{\"actual\":224.62580579894112,\"falling_edge\":\"2017-08-09 00:30:00+00:00\",\"predicted\":224.62580579894112,\"rising_edge\":\"2017-08-09 00:00:00+00:00\"},{\"actual\":220.43228942114544,\"falling_edge\":\"2017-08-09 01:00:00+00:00\",\"predicted\":220.43228942114544,\"rising_edge\":\"2017-08-09 00:30:00+00:00\"},{\"actual\":231.00886216218663,\"falling_edge\":\"2017-08-09 01:30:00+00:00\",\"predicted\":231.00886216218663,\"rising_edge\":\"2017-08-09 01:00:00+00:00\"},{\"actual\":223.25447131798364,\"falling_edge\":\"2017-08-09 02:00:00+00:00\",\"predicted\":223.25447131798364,\"rising_edge\":\"2017-08-09 01:30:00+00:00\"},{\"actual\":233.89392089989704,\"falling_edge\":\"2017-08-09 02:30:00+00:00\",\"predicted\":233.89392089989704,\"rising_edge\":\"2017-08-09 02:00:00+00:00\"},{\"actual\":229.11826102692214,\"falling_edge\":\"2017-08-09 03:00:00+00:00\",\"predicted\":229.11826102692214,\"rising_edge\":\"2017-08-09 02:30:00+00:00\"},{\"actual\":220.3374067628817,\"falling_edge\":\"2017-08-09 03:30:00+00:00\",\"predicted\":220.3374067628817,\"rising_edge\":\"2017-08-09 03:00:00+00:00\"},{\"actual\":214.14851330576653,\"falling_edge\":\"2017-08-09 04:00:00+00:00\",\"predicted\":214.14851330576653,\"rising_edge\":\"2017-08-09 03:30:00+00:00\"},{\"actual\":226.33421570365627,\"falling_edge\":\"2017-08-09 04:30:00+00:00\",\"predicted\":226.33421570365627,\"rising_edge\":\"2017-08-09 04:00:00+00:00\"},{\"actual\":224.4259874116268,\"falling_edge\":\"2017-08-09 05:00:00+00:00\",\"predicted\":224.4259874116268,\"rising_edge\":\"2017-08-09 04:30:00+00:00\"},{\"actual\":216.84949617588822,\"falling_edge\":\"2017-08-09 05:30:00+00:00\",\"predicted\":216.84949617588822,\"rising_edge\":\"2017-08-09 05:00:00+00:00\"},{\"actual\":220.92558068561664,\"falling_edge\":\"2017-08-09 06:00:00+00:00\",\"predicted\":220.92558068561664,\"rising_edge\":\"2017-08-09 05:30:00+00:00\"},{\"actual\":232.586734025574,\"falling_edge\":\"2017-08-09 06:30:00+00:00\",\"predicted\":232.586734025574,\"rising_edge\":\"2017-08-09 06:00:00+00:00\"},{\"actual\":234.24712918877538,\"falling_edge\":\"2017-08-09 07:00:00+00:00\",\"predicted\":234.24712918877538,\"rising_edge\":\"2017-08-09 06:30:00+00:00\"},{\"actual\":229.12594073987609,\"falling_edge\":\"2017-08-09 07:30:00+00:00\",\"predicted\":229.12594073987609,\"rising_edge\":\"2017-08-09 07:00:00+00:00\"},{\"actual\":225.98455318833285,\"falling_edge\":\"2017-08-09 08:00:00+00:00\",\"predicted\":225.98455318833285,\"rising_edge\":\"2017-08-09 07:30:00+00:00\"},{\"actual\":223.4330976938116,\"falling_edge\":\"2017-08-09 08:30:00+00:00\",\"predicted\":223.4330976938116,\"rising_edge\":\"2017-08-09 08:00:00+00:00\"},{\"actual\":211.35302465766625,\"falling_edge\":\"2017-08-09 09:00:00+00:00\",\"predicted\":211.35302465766625,\"rising_edge\":\"2017-08-09 08:30:00+00:00\"},{\"actual\":177.33742857027198,\"falling_edge\":\"2017-08-09 09:30:00+00:00\",\"predicted\":177.33742857027198,\"rising_edge\":\"2017-08-09 09:00:00+00:00\"},{\"actual\":158.58345782937704,\"falling_edge\":\"2017-08-09 10:00:00+00:00\",\"predicted\":158.58345782937704,\"rising_edge\":\"2017-08-09 09:30:00+00:00\"},{\"actual\":127.99358293740666,\"falling_edge\":\"2017-08-09 10:30:00+00:00\",\"predicted\":127.99358293740666,\"rising_edge\":\"2017-08-09 10:00:00+00:00\"},{\"actual\":122.43274726541982,\"falling_edge\":\"2017-08-09 11:00:00+00:00\",\"predicted\":122.43274726541982,\"rising_edge\":\"2017-08-09 10:30:00+00:00\"},{\"actual\":114.05361356932781,\"falling_edge\":\"2017-08-09 11:30:00+00:00\",\"predicted\":114.05361356932781,\"rising_edge\":\"2017-08-09 11:00:00+00:00\"},{\"actual\":109.18505163290635,\"falling_edge\":\"2017-08-09 12:00:00+00:00\",\"predicted\":109.18505163290635,\"rising_edge\":\"2017-08-09 11:30:00+00:00\"},{\"actual\":101.70700052171712,\"falling_edge\":\"2017-08-09 12:30:00+00:00\",\"predicted\":101.70700052171712,\"rising_edge\":\"2017-08-09 12:00:00+00:00\"},{\"actual\":93.51210641970644,\"falling_edge\":\"2017-08-09 13:00:00+00:00\",\"predicted\":93.51210641970644,\"rising_edge\":\"2017-08-09 12:30:00+00:00\"},{\"actual\":80.7938739808895,\"falling_edge\":\"2017-08-09 13:30:00+00:00\",\"predicted\":80.7938739808895,\"rising_edge\":\"2017-08-09 13:00:00+00:00\"},{\"actual\":70.89748761721911,\"falling_edge\":\"2017-08-09 14:00:00+00:00\",\"predicted\":70.89748761721911,\"rising_edge\":\"2017-08-09 13:30:00+00:00\"},{\"actual\":63.03782769630544,\"falling_edge\":\"2017-08-09 14:30:00+00:00\",\"predicted\":63.03782769630544,\"rising_edge\":\"2017-08-09 14:00:00+00:00\"},{\"actual\":56.86744763935753,\"falling_edge\":\"2017-08-09 15:00:00+00:00\",\"predicted\":56.86744763935753,\"rising_edge\":\"2017-08-09 14:30:00+00:00\"},{\"actual\":52.396334031772405,\"falling_edge\":\"2017-08-09 15:30:00+00:00\",\"predicted\":52.396334031772405,\"rising_edge\":\"2017-08-09 15:00:00+00:00\"},{\"actual\":49.6939243811914,\"falling_edge\":\"2017-08-09 16:00:00+00:00\",\"predicted\":49.6939243811914,\"rising_edge\":\"2017-08-09 15:30:00+00:00\"},{\"actual\":47.26113346313511,\"falling_edge\":\"2017-08-09 16:30:00+00:00\",\"predicted\":47.26113346313511,\"rising_edge\":\"2017-08-09 16:00:00+00:00\"},{\"actual\":47.19974380544476,\"falling_edge\":\"2017-08-09 17:00:00+00:00\",\"predicted\":47.19974380544476,\"rising_edge\":\"2017-08-09 16:30:00+00:00\"},{\"actual\":48.16055340502203,\"falling_edge\":\"2017-08-09 17:30:00+00:00\",\"predicted\":48.16055340502203,\"rising_edge\":\"2017-08-09 17:00:00+00:00\"},{\"actual\":47.640333276435506,\"falling_edge\":\"2017-08-09 18:00:00+00:00\",\"predicted\":47.640333276435506,\"rising_edge\":\"2017-08-09 17:30:00+00:00\"},{\"actual\":46.89446660678482,\"falling_edge\":\"2017-08-09 18:30:00+00:00\",\"predicted\":46.89446660678482,\"rising_edge\":\"2017-08-09 18:00:00+00:00\"},{\"actual\":46.482052037348545,\"falling_edge\":\"2017-08-09 19:00:00+00:00\",\"predicted\":46.482052037348545,\"rising_edge\":\"2017-08-09 18:30:00+00:00\"},{\"actual\":46.179518257957156,\"falling_edge\":\"2017-08-09 19:30:00+00:00\",\"predicted\":46.179518257957156,\"rising_edge\":\"2017-08-09 19:00:00+00:00\"},{\"actual\":46.32751814873525,\"falling_edge\":\"2017-08-09 20:00:00+00:00\",\"predicted\":46.32751814873525,\"rising_edge\":\"2017-08-09 19:30:00+00:00\"},{\"actual\":47.532361005058654,\"falling_edge\":\"2017-08-09 20:30:00+00:00\",\"predicted\":47.532361005058654,\"rising_edge\":\"2017-08-09 20:00:00+00:00\"},{\"actual\":52.660325708178604,\"falling_edge\":\"2017-08-09 21:00:00+00:00\",\"predicted\":52.660325708178604,\"rising_edge\":\"2017-08-09 20:30:00+00:00\"},{\"actual\":71.33435419543473,\"falling_edge\":\"2017-08-09 21:30:00+00:00\",\"predicted\":71.33435419543473,\"rising_edge\":\"2017-08-09 21:00:00+00:00\"},{\"actual\":107.49251270949783,\"falling_edge\":\"2017-08-09 22:00:00+00:00\",\"predicted\":107.49251270949783,\"rising_edge\":\"2017-08-09 21:30:00+00:00\"},{\"actual\":105.46834218078376,\"falling_edge\":\"2017-08-09 22:30:00+00:00\",\"predicted\":105.46834218078376,\"rising_edge\":\"2017-08-09 22:00:00+00:00\"},{\"actual\":127.67159072498572,\"falling_edge\":\"2017-08-09 23:00:00+00:00\",\"predicted\":127.67159072498572,\"rising_edge\":\"2017-08-09 22:30:00+00:00\"},{\"actual\":164.83243025527074,\"falling_edge\":\"2017-08-09 23:30:00+00:00\",\"predicted\":164.83243025527074,\"rising_edge\":\"2017-08-09 23:00:00+00:00\"},{\"actual\":205.11066164996942,\"falling_edge\":\"2017-08-10 00:00:00+00:00\",\"predicted\":205.11066164996942,\"rising_edge\":\"2017-08-09 23:30:00+00:00\"},{\"actual\":218.03073622597242,\"falling_edge\":\"2017-08-10 00:30:00+00:00\",\"predicted\":218.03073622597242,\"rising_edge\":\"2017-08-10 00:00:00+00:00\"},{\"actual\":218.89801257923946,\"falling_edge\":\"2017-08-10 01:00:00+00:00\",\"predicted\":218.89801257923946,\"rising_edge\":\"2017-08-10 00:30:00+00:00\"},{\"actual\":227.27282878092146,\"falling_edge\":\"2017-08-10 01:30:00+00:00\",\"predicted\":227.27282878092146,\"rising_edge\":\"2017-08-10 01:00:00+00:00\"},{\"actual\":229.84070011774256,\"falling_edge\":\"2017-08-10 02:00:00+00:00\",\"predicted\":229.84070011774256,\"rising_edge\":\"2017-08-10 01:30:00+00:00\"},{\"actual\":230.33550470918743,\"falling_edge\":\"2017-08-10 02:30:00+00:00\",\"predicted\":230.33550470918743,\"rising_edge\":\"2017-08-10 02:00:00+00:00\"},{\"actual\":222.46444513065555,\"falling_edge\":\"2017-08-10 03:00:00+00:00\",\"predicted\":222.46444513065555,\"rising_edge\":\"2017-08-10 02:30:00+00:00\"},{\"actual\":215.52780973782404,\"falling_edge\":\"2017-08-10 03:30:00+00:00\",\"predicted\":215.52780973782404,\"rising_edge\":\"2017-08-10 03:00:00+00:00\"},{\"actual\":210.26690190040955,\"falling_edge\":\"2017-08-10 04:00:00+00:00\",\"predicted\":210.26690190040955,\"rising_edge\":\"2017-08-10 03:30:00+00:00\"},{\"actual\":222.9003768524504,\"falling_edge\":\"2017-08-10 04:30:00+00:00\",\"predicted\":222.9003768524504,\"rising_edge\":\"2017-08-10 04:00:00+00:00\"},{\"actual\":223.9042211153032,\"falling_edge\":\"2017-08-10 05:00:00+00:00\",\"predicted\":223.9042211153032,\"rising_edge\":\"2017-08-10 04:30:00+00:00\"},{\"actual\":231.1482458694368,\"falling_edge\":\"2017-08-10 05:30:00+00:00\",\"predicted\":231.1482458694368,\"rising_edge\":\"2017-08-10 05:00:00+00:00\"},{\"actual\":239.32240626637224,\"falling_edge\":\"2017-08-10 06:00:00+00:00\",\"predicted\":239.32240626637224,\"rising_edge\":\"2017-08-10 05:30:00+00:00\"},{\"actual\":245.48757544050062,\"falling_edge\":\"2017-08-10 06:30:00+00:00\",\"predicted\":245.48757544050062,\"rising_edge\":\"2017-08-10 06:00:00+00:00\"},{\"actual\":240.114477900543,\"falling_edge\":\"2017-08-10 07:00:00+00:00\",\"predicted\":240.114477900543,\"rising_edge\":\"2017-08-10 06:30:00+00:00\"},{\"actual\":246.48640488604013,\"falling_edge\":\"2017-08-10 07:30:00+00:00\",\"predicted\":246.48640488604013,\"rising_edge\":\"2017-08-10 07:00:00+00:00\"},{\"actual\":254.13610481918548,\"falling_edge\":\"2017-08-10 08:00:00+00:00\",\"predicted\":254.13610481918548,\"rising_edge\":\"2017-08-10 07:30:00+00:00\"},{\"actual\":252.85083952213319,\"falling_edge\":\"2017-08-10 08:30:00+00:00\",\"predicted\":252.85083952213319,\"rising_edge\":\"2017-08-10 08:00:00+00:00\"},{\"actual\":233.98971481414517,\"falling_edge\":\"2017-08-10 09:00:00+00:00\",\"predicted\":233.98971481414517,\"rising_edge\":\"2017-08-10 08:30:00+00:00\"},{\"actual\":201.18736614307358,\"falling_edge\":\"2017-08-10 09:30:00+00:00\",\"predicted\":201.18736614307358,\"rising_edge\":\"2017-08-10 09:00:00+00:00\"},{\"actual\":177.68129164179012,\"falling_edge\":\"2017-08-10 10:00:00+00:00\",\"predicted\":177.68129164179012,\"rising_edge\":\"2017-08-10 09:30:00+00:00\"},{\"actual\":152.0605413482581,\"falling_edge\":\"2017-08-10 10:30:00+00:00\",\"predicted\":152.0605413482581,\"rising_edge\":\"2017-08-10 10:00:00+00:00\"},{\"actual\":147.89491759106636,\"falling_edge\":\"2017-08-10 11:00:00+00:00\",\"predicted\":147.89491759106636,\"rising_edge\":\"2017-08-10 10:30:00+00:00\"},{\"actual\":136.9424113919971,\"falling_edge\":\"2017-08-10 11:30:00+00:00\",\"predicted\":136.9424113919971,\"rising_edge\":\"2017-08-10 11:00:00+00:00\"},{\"actual\":123.98025540885497,\"falling_edge\":\"2017-08-10 12:00:00+00:00\",\"predicted\":123.98025540885497,\"rising_edge\":\"2017-08-10 11:30:00+00:00\"},{\"actual\":113.6502494957401,\"falling_edge\":\"2017-08-10 12:30:00+00:00\",\"predicted\":113.6502494957401,\"rising_edge\":\"2017-08-10 12:00:00+00:00\"},{\"actual\":100.5656239253851,\"falling_edge\":\"2017-08-10 13:00:00+00:00\",\"predicted\":100.5656239253851,\"rising_edge\":\"2017-08-10 12:30:00+00:00\"},{\"actual\":86.79452900580628,\"falling_edge\":\"2017-08-10 13:30:00+00:00\",\"predicted\":86.79452900580628,\"rising_edge\":\"2017-08-10 13:00:00+00:00\"},{\"actual\":76.81510438983739,\"falling_edge\":\"2017-08-10 14:00:00+00:00\",\"predicted\":76.81510438983739,\"rising_edge\":\"2017-08-10 13:30:00+00:00\"},{\"actual\":70.03246291131575,\"falling_edge\":\"2017-08-10 14:30:00+00:00\",\"predicted\":70.03246291131575,\"rising_edge\":\"2017-08-10 14:00:00+00:00\"},{\"actual\":62.25419580093924,\"falling_edge\":\"2017-08-10 15:00:00+00:00\",\"predicted\":62.25419580093924,\"rising_edge\":\"2017-08-10 14:30:00+00:00\"},{\"actual\":54.518796300605146,\"falling_edge\":\"2017-08-10 15:30:00+00:00\",\"predicted\":54.518796300605146,\"rising_edge\":\"2017-08-10 15:00:00+00:00\"},{\"actual\":49.31647355762566,\"falling_edge\":\"2017-08-10 16:00:00+00:00\",\"predicted\":49.31647355762566,\"rising_edge\":\"2017-08-10 15:30:00+00:00\"},{\"actual\":47.73225667089444,\"falling_edge\":\"2017-08-10 16:30:00+00:00\",\"predicted\":47.73225667089444,\"rising_edge\":\"2017-08-10 16:00:00+00:00\"},{\"actual\":48.528962412375336,\"falling_edge\":\"2017-08-10 17:00:00+00:00\",\"predicted\":48.528962412375336,\"rising_edge\":\"2017-08-10 16:30:00+00:00\"},{\"actual\":48.3078040876235,\"falling_edge\":\"2017-08-10 17:30:00+00:00\",\"predicted\":48.3078040876235,\"rising_edge\":\"2017-08-10 17:00:00+00:00\"},{\"actual\":46.48243815388582,\"falling_edge\":\"2017-08-10 18:00:00+00:00\",\"predicted\":46.48243815388582,\"rising_edge\":\"2017-08-10 17:30:00+00:00\"},{\"actual\":47.19285883498315,\"falling_edge\":\"2017-08-10 18:30:00+00:00\",\"predicted\":47.19285883498315,\"rising_edge\":\"2017-08-10 18:00:00+00:00\"},{\"actual\":47.05125592870837,\"falling_edge\":\"2017-08-10 19:00:00+00:00\",\"predicted\":47.05125592870837,\"rising_edge\":\"2017-08-10 18:30:00+00:00\"},{\"actual\":47.93107576374616,\"falling_edge\":\"2017-08-10 19:30:00+00:00\",\"predicted\":47.93107576374616,\"rising_edge\":\"2017-08-10 19:00:00+00:00\"},{\"actual\":46.52930735227755,\"falling_edge\":\"2017-08-10 20:00:00+00:00\",\"predicted\":46.52930735227755,\"rising_edge\":\"2017-08-10 19:30:00+00:00\"},{\"actual\":48.53137183475149,\"falling_edge\":\"2017-08-10 20:30:00+00:00\",\"predicted\":48.53137183475149,\"rising_edge\":\"2017-08-10 20:00:00+00:00\"},{\"actual\":53.1514030160058,\"falling_edge\":\"2017-08-10 21:00:00+00:00\",\"predicted\":53.1514030160058,\"rising_edge\":\"2017-08-10 20:30:00+00:00\"},{\"actual\":69.55634074260946,\"falling_edge\":\"2017-08-10 21:30:00+00:00\",\"predicted\":69.55634074260946,\"rising_edge\":\"2017-08-10 21:00:00+00:00\"},{\"actual\":111.06862878290262,\"falling_edge\":\"2017-08-10 22:00:00+00:00\",\"predicted\":111.06862878290262,\"rising_edge\":\"2017-08-10 21:30:00+00:00\"},{\"actual\":109.1375341790687,\"falling_edge\":\"2017-08-10 22:30:00+00:00\",\"predicted\":109.1375341790687,\"rising_edge\":\"2017-08-10 22:00:00+00:00\"},{\"actual\":125.467239150148,\"falling_edge\":\"2017-08-10 23:00:00+00:00\",\"predicted\":125.467239150148,\"rising_edge\":\"2017-08-10 22:30:00+00:00\"},{\"actual\":158.85248435243778,\"falling_edge\":\"2017-08-10 23:30:00+00:00\",\"predicted\":158.85248435243778,\"rising_edge\":\"2017-08-10 23:00:00+00:00\"},{\"actual\":207.63953428637095,\"falling_edge\":\"2017-08-11 00:00:00+00:00\",\"predicted\":207.63953428637095,\"rising_edge\":\"2017-08-10 23:30:00+00:00\"},{\"actual\":227.43749202500834,\"falling_edge\":\"2017-08-11 00:30:00+00:00\",\"predicted\":227.43749202500834,\"rising_edge\":\"2017-08-11 00:00:00+00:00\"},{\"actual\":218.85112513156767,\"falling_edge\":\"2017-08-11 01:00:00+00:00\",\"predicted\":218.85112513156767,\"rising_edge\":\"2017-08-11 00:30:00+00:00\"},{\"actual\":229.46973823615272,\"falling_edge\":\"2017-08-11 01:30:00+00:00\",\"predicted\":229.46973823615272,\"rising_edge\":\"2017-08-11 01:00:00+00:00\"},{\"actual\":229.61930662892865,\"falling_edge\":\"2017-08-11 02:00:00+00:00\",\"predicted\":229.61930662892865,\"rising_edge\":\"2017-08-11 01:30:00+00:00\"},{\"actual\":223.63400991433818,\"falling_edge\":\"2017-08-11 02:30:00+00:00\",\"predicted\":223.63400991433818,\"rising_edge\":\"2017-08-11 02:00:00+00:00\"},{\"actual\":219.52888456962089,\"falling_edge\":\"2017-08-11 03:00:00+00:00\",\"predicted\":219.52888456962089,\"rising_edge\":\"2017-08-11 02:30:00+00:00\"},{\"actual\":225.75168293366195,\"falling_edge\":\"2017-08-11 03:30:00+00:00\",\"predicted\":225.75168293366195,\"rising_edge\":\"2017-08-11 03:00:00+00:00\"},{\"actual\":213.7612536262905,\"falling_edge\":\"2017-08-11 04:00:00+00:00\",\"predicted\":213.7612536262905,\"rising_edge\":\"2017-08-11 03:30:00+00:00\"},{\"actual\":232.01489612711583,\"falling_edge\":\"2017-08-11 04:30:00+00:00\",\"predicted\":232.01489612711583,\"rising_edge\":\"2017-08-11 04:00:00+00:00\"},{\"actual\":239.90707432822646,\"falling_edge\":\"2017-08-11 05:00:00+00:00\",\"predicted\":239.90707432822646,\"rising_edge\":\"2017-08-11 04:30:00+00:00\"},{\"actual\":232.05125626523227,\"falling_edge\":\"2017-08-11 05:30:00+00:00\",\"predicted\":232.05125626523227,\"rising_edge\":\"2017-08-11 05:00:00+00:00\"},{\"actual\":233.78132768030775,\"falling_edge\":\"2017-08-11 06:00:00+00:00\",\"predicted\":233.78132768030775,\"rising_edge\":\"2017-08-11 05:30:00+00:00\"},{\"actual\":232.5087118157547,\"falling_edge\":\"2017-08-11 06:30:00+00:00\",\"predicted\":232.5087118157547,\"rising_edge\":\"2017-08-11 06:00:00+00:00\"},{\"actual\":241.02575069013713,\"falling_edge\":\"2017-08-11 07:00:00+00:00\",\"predicted\":241.02575069013713,\"rising_edge\":\"2017-08-11 06:30:00+00:00\"},{\"actual\":233.85584720604894,\"falling_edge\":\"2017-08-11 07:30:00+00:00\",\"predicted\":233.85584720604894,\"rising_edge\":\"2017-08-11 07:00:00+00:00\"},{\"actual\":239.29722802935933,\"falling_edge\":\"2017-08-11 08:00:00+00:00\",\"predicted\":239.29722802935933,\"rising_edge\":\"2017-08-11 07:30:00+00:00\"},{\"actual\":237.9870642011752,\"falling_edge\":\"2017-08-11 08:30:00+00:00\",\"predicted\":237.9870642011752,\"rising_edge\":\"2017-08-11 08:00:00+00:00\"},{\"actual\":213.95817753774946,\"falling_edge\":\"2017-08-11 09:00:00+00:00\",\"predicted\":213.95817753774946,\"rising_edge\":\"2017-08-11 08:30:00+00:00\"},{\"actual\":188.4414238565777,\"falling_edge\":\"2017-08-11 09:30:00+00:00\",\"predicted\":188.4414238565777,\"rising_edge\":\"2017-08-11 09:00:00+00:00\"},{\"actual\":167.73106139800905,\"falling_edge\":\"2017-08-11 10:00:00+00:00\",\"predicted\":167.73106139800905,\"rising_edge\":\"2017-08-11 09:30:00+00:00\"},{\"actual\":137.15851716378927,\"falling_edge\":\"2017-08-11 10:30:00+00:00\",\"predicted\":137.15851716378927,\"rising_edge\":\"2017-08-11 10:00:00+00:00\"},{\"actual\":128.60248441902345,\"falling_edge\":\"2017-08-11 11:00:00+00:00\",\"predicted\":128.60248441902345,\"rising_edge\":\"2017-08-11 10:30:00+00:00\"},{\"actual\":114.72371607166724,\"falling_edge\":\"2017-08-11 11:30:00+00:00\",\"predicted\":114.72371607166724,\"rising_edge\":\"2017-08-11 11:00:00+00:00\"},{\"actual\":104.14129418876418,\"falling_edge\":\"2017-08-11 12:00:00+00:00\",\"predicted\":104.14129418876418,\"rising_edge\":\"2017-08-11 11:30:00+00:00\"},{\"actual\":93.13421223042627,\"falling_edge\":\"2017-08-11 12:30:00+00:00\",\"predicted\":93.13421223042627,\"rising_edge\":\"2017-08-11 12:00:00+00:00\"},{\"actual\":83.16040874480137,\"falling_edge\":\"2017-08-11 13:00:00+00:00\",\"predicted\":83.16040874480137,\"rising_edge\":\"2017-08-11 12:30:00+00:00\"},{\"actual\":75.5929145242805,\"falling_edge\":\"2017-08-11 13:30:00+00:00\",\"predicted\":75.5929145242805,\"rising_edge\":\"2017-08-11 13:00:00+00:00\"},{\"actual\":70.92882252331124,\"falling_edge\":\"2017-08-11 14:00:00+00:00\",\"predicted\":70.92882252331124,\"rising_edge\":\"2017-08-11 13:30:00+00:00\"},{\"actual\":61.15213287983627,\"falling_edge\":\"2017-08-11 14:30:00+00:00\",\"predicted\":61.15213287983627,\"rising_edge\":\"2017-08-11 14:00:00+00:00\"},{\"actual\":57.012246909185656,\"falling_edge\":\"2017-08-11 15:00:00+00:00\",\"predicted\":57.012246909185656,\"rising_edge\":\"2017-08-11 14:30:00+00:00\"},{\"actual\":50.791750297058535,\"falling_edge\":\"2017-08-11 15:30:00+00:00\",\"predicted\":50.791750297058535,\"rising_edge\":\"2017-08-11 15:00:00+00:00\"},{\"actual\":47.578063890584275,\"falling_edge\":\"2017-08-11 16:00:00+00:00\",\"predicted\":47.578063890584275,\"rising_edge\":\"2017-08-11 15:30:00+00:00\"},{\"actual\":48.29035063765445,\"falling_edge\":\"2017-08-11 16:30:00+00:00\",\"predicted\":48.29035063765445,\"rising_edge\":\"2017-08-11 16:00:00+00:00\"},{\"actual\":47.62216682182844,\"falling_edge\":\"2017-08-11 17:00:00+00:00\",\"predicted\":47.62216682182844,\"rising_edge\":\"2017-08-11 16:30:00+00:00\"},{\"actual\":47.76746534368265,\"falling_edge\":\"2017-08-11 17:30:00+00:00\",\"predicted\":47.76746534368265,\"rising_edge\":\"2017-08-11 17:00:00+00:00\"},{\"actual\":46.20651616344821,\"falling_edge\":\"2017-08-11 18:00:00+00:00\",\"predicted\":46.20651616344821,\"rising_edge\":\"2017-08-11 17:30:00+00:00\"},{\"actual\":47.85745994538916,\"falling_edge\":\"2017-08-11 18:30:00+00:00\",\"predicted\":47.85745994538916,\"rising_edge\":\"2017-08-11 18:00:00+00:00\"},{\"actual\":49.07291578013346,\"falling_edge\":\"2017-08-11 19:00:00+00:00\",\"predicted\":49.07291578013346,\"rising_edge\":\"2017-08-11 18:30:00+00:00\"},{\"actual\":49.92375561400337,\"falling_edge\":\"2017-08-11 19:30:00+00:00\",\"predicted\":49.92375561400337,\"rising_edge\":\"2017-08-11 19:00:00+00:00\"},{\"actual\":49.30311141342266,\"falling_edge\":\"2017-08-11 20:00:00+00:00\",\"predicted\":49.30311141342266,\"rising_edge\":\"2017-08-11 19:30:00+00:00\"},{\"actual\":49.969680199397935,\"falling_edge\":\"2017-08-11 20:30:00+00:00\",\"predicted\":49.969680199397935,\"rising_edge\":\"2017-08-11 20:00:00+00:00\"},{\"actual\":52.06484669117899,\"falling_edge\":\"2017-08-11 21:00:00+00:00\",\"predicted\":52.06484669117899,\"rising_edge\":\"2017-08-11 20:30:00+00:00\"},{\"actual\":61.22727159651524,\"falling_edge\":\"2017-08-11 21:30:00+00:00\",\"predicted\":61.22727159651524,\"rising_edge\":\"2017-08-11 21:00:00+00:00\"},{\"actual\":64.18972440597582,\"falling_edge\":\"2017-08-11 22:00:00+00:00\",\"predicted\":64.18972440597582,\"rising_edge\":\"2017-08-11 21:30:00+00:00\"},{\"actual\":63.56193840870798,\"falling_edge\":\"2017-08-11 22:30:00+00:00\",\"predicted\":63.56193840870798,\"rising_edge\":\"2017-08-11 22:00:00+00:00\"},{\"actual\":64.99328880472255,\"falling_edge\":\"2017-08-11 23:00:00+00:00\",\"predicted\":64.99328880472255,\"rising_edge\":\"2017-08-11 22:30:00+00:00\"},{\"actual\":67.8933687477279,\"falling_edge\":\"2017-08-11 23:30:00+00:00\",\"predicted\":67.8933687477279,\"rising_edge\":\"2017-08-11 23:00:00+00:00\"},{\"actual\":72.57292325555792,\"falling_edge\":\"2017-08-12 00:00:00+00:00\",\"predicted\":72.57292325555792,\"rising_edge\":\"2017-08-11 23:30:00+00:00\"},{\"actual\":81.59780632925288,\"falling_edge\":\"2017-08-12 00:30:00+00:00\",\"predicted\":81.59780632925288,\"rising_edge\":\"2017-08-12 00:00:00+00:00\"},{\"actual\":91.24807235591092,\"falling_edge\":\"2017-08-12 01:00:00+00:00\",\"predicted\":91.24807235591092,\"rising_edge\":\"2017-08-12 00:30:00+00:00\"},{\"actual\":88.68081269203363,\"falling_edge\":\"2017-08-12 01:30:00+00:00\",\"predicted\":88.68081269203363,\"rising_edge\":\"2017-08-12 01:00:00+00:00\"},{\"actual\":88.78028306588983,\"falling_edge\":\"2017-08-12 02:00:00+00:00\",\"predicted\":88.78028306588983,\"rising_edge\":\"2017-08-12 01:30:00+00:00\"},{\"actual\":89.00444470341057,\"falling_edge\":\"2017-08-12 02:30:00+00:00\",\"predicted\":89.00444470341057,\"rising_edge\":\"2017-08-12 02:00:00+00:00\"},{\"actual\":91.08453460942708,\"falling_edge\":\"2017-08-12 03:00:00+00:00\",\"predicted\":91.08453460942708,\"rising_edge\":\"2017-08-12 02:30:00+00:00\"},{\"actual\":88.98829922707073,\"falling_edge\":\"2017-08-12 03:30:00+00:00\",\"predicted\":88.98829922707073,\"rising_edge\":\"2017-08-12 03:00:00+00:00\"},{\"actual\":90.86753205230957,\"falling_edge\":\"2017-08-12 04:00:00+00:00\",\"predicted\":90.86753205230957,\"rising_edge\":\"2017-08-12 03:30:00+00:00\"},{\"actual\":95.51545465595251,\"falling_edge\":\"2017-08-12 04:30:00+00:00\",\"predicted\":95.51545465595251,\"rising_edge\":\"2017-08-12 04:00:00+00:00\"},{\"actual\":92.22783581339255,\"falling_edge\":\"2017-08-12 05:00:00+00:00\",\"predicted\":92.22783581339255,\"rising_edge\":\"2017-08-12 04:30:00+00:00\"},{\"actual\":89.40682499516747,\"falling_edge\":\"2017-08-12 05:30:00+00:00\",\"predicted\":89.40682499516747,\"rising_edge\":\"2017-08-12 05:00:00+00:00\"},{\"actual\":89.57286982715249,\"falling_edge\":\"2017-08-12 06:00:00+00:00\",\"predicted\":89.57286982715249,\"rising_edge\":\"2017-08-12 05:30:00+00:00\"},{\"actual\":88.29825746328618,\"falling_edge\":\"2017-08-12 06:30:00+00:00\",\"predicted\":88.29825746328618,\"rising_edge\":\"2017-08-12 06:00:00+00:00\"},{\"actual\":89.96446773139449,\"falling_edge\":\"2017-08-12 07:00:00+00:00\",\"predicted\":89.96446773139449,\"rising_edge\":\"2017-08-12 06:30:00+00:00\"},{\"actual\":89.35600459790982,\"falling_edge\":\"2017-08-12 07:30:00+00:00\",\"predicted\":89.35600459790982,\"rising_edge\":\"2017-08-12 07:00:00+00:00\"},{\"actual\":87.58358619883438,\"falling_edge\":\"2017-08-12 08:00:00+00:00\",\"predicted\":87.58358619883438,\"rising_edge\":\"2017-08-12 07:30:00+00:00\"},{\"actual\":85.02028441935184,\"falling_edge\":\"2017-08-12 08:30:00+00:00\",\"predicted\":85.02028441935184,\"rising_edge\":\"2017-08-12 08:00:00+00:00\"},{\"actual\":78.8568906259304,\"falling_edge\":\"2017-08-12 09:00:00+00:00\",\"predicted\":78.8568906259304,\"rising_edge\":\"2017-08-12 08:30:00+00:00\"},{\"actual\":69.2752905427013,\"falling_edge\":\"2017-08-12 09:30:00+00:00\",\"predicted\":69.2752905427013,\"rising_edge\":\"2017-08-12 09:00:00+00:00\"},{\"actual\":67.12493819257041,\"falling_edge\":\"2017-08-12 10:00:00+00:00\",\"predicted\":67.12493819257041,\"rising_edge\":\"2017-08-12 09:30:00+00:00\"},{\"actual\":64.39566926022522,\"falling_edge\":\"2017-08-12 10:30:00+00:00\",\"predicted\":64.39566926022522,\"rising_edge\":\"2017-08-12 10:00:00+00:00\"},{\"actual\":61.98349787121546,\"falling_edge\":\"2017-08-12 11:00:00+00:00\",\"predicted\":61.98349787121546,\"rising_edge\":\"2017-08-12 10:30:00+00:00\"},{\"actual\":61.12379675658134,\"falling_edge\":\"2017-08-12 11:30:00+00:00\",\"predicted\":61.12379675658134,\"rising_edge\":\"2017-08-12 11:00:00+00:00\"},{\"actual\":59.14541380487749,\"falling_edge\":\"2017-08-12 12:00:00+00:00\",\"predicted\":59.14541380487749,\"rising_edge\":\"2017-08-12 11:30:00+00:00\"},{\"actual\":54.83354935651643,\"falling_edge\":\"2017-08-12 12:30:00+00:00\",\"predicted\":54.83354935651643,\"rising_edge\":\"2017-08-12 12:00:00+00:00\"},{\"actual\":53.94538582472015,\"falling_edge\":\"2017-08-12 13:00:00+00:00\",\"predicted\":53.94538582472015,\"rising_edge\":\"2017-08-12 12:30:00+00:00\"},{\"actual\":53.29378665336265,\"falling_edge\":\"2017-08-12 13:30:00+00:00\",\"predicted\":53.29378665336265,\"rising_edge\":\"2017-08-12 13:00:00+00:00\"},{\"actual\":52.55742314615942,\"falling_edge\":\"2017-08-12 14:00:00+00:00\",\"predicted\":52.55742314615942,\"rising_edge\":\"2017-08-12 13:30:00+00:00\"},{\"actual\":49.89287364579101,\"falling_edge\":\"2017-08-12 14:30:00+00:00\",\"predicted\":49.89287364579101,\"rising_edge\":\"2017-08-12 14:00:00+00:00\"},{\"actual\":48.936029487790485,\"falling_edge\":\"2017-08-12 15:00:00+00:00\",\"predicted\":48.936029487790485,\"rising_edge\":\"2017-08-12 14:30:00+00:00\"},{\"actual\":49.19825779205303,\"falling_edge\":\"2017-08-12 15:30:00+00:00\",\"predicted\":49.19825779205303,\"rising_edge\":\"2017-08-12 15:00:00+00:00\"},{\"actual\":47.24853404314293,\"falling_edge\":\"2017-08-12 16:00:00+00:00\",\"predicted\":47.24853404314293,\"rising_edge\":\"2017-08-12 15:30:00+00:00\"},{\"actual\":47.179605378138014,\"falling_edge\":\"2017-08-12 16:30:00+00:00\",\"predicted\":47.179605378138014,\"rising_edge\":\"2017-08-12 16:00:00+00:00\"},{\"actual\":46.63305457754063,\"falling_edge\":\"2017-08-12 17:00:00+00:00\",\"predicted\":46.63305457754063,\"rising_edge\":\"2017-08-12 16:30:00+00:00\"},{\"actual\":47.124033128401464,\"falling_edge\":\"2017-08-12 17:30:00+00:00\",\"predicted\":47.124033128401464,\"rising_edge\":\"2017-08-12 17:00:00+00:00\"},{\"actual\":46.569318641406774,\"falling_edge\":\"2017-08-12 18:00:00+00:00\",\"predicted\":46.569318641406774,\"rising_edge\":\"2017-08-12 17:30:00+00:00\"},{\"actual\":46.92660740428029,\"falling_edge\":\"2017-08-12 18:30:00+00:00\",\"predicted\":46.92660740428029,\"rising_edge\":\"2017-08-12 18:00:00+00:00\"},{\"actual\":46.373643931367624,\"falling_edge\":\"2017-08-12 19:00:00+00:00\",\"predicted\":46.373643931367624,\"rising_edge\":\"2017-08-12 18:30:00+00:00\"},{\"actual\":46.14349709480515,\"falling_edge\":\"2017-08-12 19:30:00+00:00\",\"predicted\":46.14349709480515,\"rising_edge\":\"2017-08-12 19:00:00+00:00\"},{\"actual\":46.56792611388364,\"falling_edge\":\"2017-08-12 20:00:00+00:00\",\"predicted\":46.56792611388364,\"rising_edge\":\"2017-08-12 19:30:00+00:00\"},{\"actual\":45.92190495957928,\"falling_edge\":\"2017-08-12 20:30:00+00:00\",\"predicted\":45.92190495957928,\"rising_edge\":\"2017-08-12 20:00:00+00:00\"},{\"actual\":47.33893588061124,\"falling_edge\":\"2017-08-12 21:00:00+00:00\",\"predicted\":47.33893588061124,\"rising_edge\":\"2017-08-12 20:30:00+00:00\"},{\"actual\":47.78235877262256,\"falling_edge\":\"2017-08-12 21:30:00+00:00\",\"predicted\":47.78235877262256,\"rising_edge\":\"2017-08-12 21:00:00+00:00\"},{\"actual\":50.32774948032127,\"falling_edge\":\"2017-08-12 22:00:00+00:00\",\"predicted\":50.32774948032127,\"rising_edge\":\"2017-08-12 21:30:00+00:00\"},{\"actual\":52.31891878161063,\"falling_edge\":\"2017-08-12 22:30:00+00:00\",\"predicted\":52.31891878161063,\"rising_edge\":\"2017-08-12 22:00:00+00:00\"},{\"actual\":52.174066996340734,\"falling_edge\":\"2017-08-12 23:00:00+00:00\",\"predicted\":52.174066996340734,\"rising_edge\":\"2017-08-12 22:30:00+00:00\"},{\"actual\":56.78021186711044,\"falling_edge\":\"2017-08-12 23:30:00+00:00\",\"predicted\":56.78021186711044,\"rising_edge\":\"2017-08-12 23:00:00+00:00\"},{\"actual\":59.82149496258744,\"falling_edge\":\"2017-08-13 00:00:00+00:00\",\"predicted\":59.82149496258744,\"rising_edge\":\"2017-08-12 23:30:00+00:00\"},{\"actual\":65.66647918686927,\"falling_edge\":\"2017-08-13 00:30:00+00:00\",\"predicted\":65.66647918686927,\"rising_edge\":\"2017-08-13 00:00:00+00:00\"},{\"actual\":68.0562586854074,\"falling_edge\":\"2017-08-13 01:00:00+00:00\",\"predicted\":68.0562586854074,\"rising_edge\":\"2017-08-13 00:30:00+00:00\"},{\"actual\":67.64863774350567,\"falling_edge\":\"2017-08-13 01:30:00+00:00\",\"predicted\":67.64863774350567,\"rising_edge\":\"2017-08-13 01:00:00+00:00\"},{\"actual\":67.08709914767934,\"falling_edge\":\"2017-08-13 02:00:00+00:00\",\"predicted\":67.08709914767934,\"rising_edge\":\"2017-08-13 01:30:00+00:00\"},{\"actual\":68.51830296786522,\"falling_edge\":\"2017-08-13 02:30:00+00:00\",\"predicted\":68.51830296786522,\"rising_edge\":\"2017-08-13 02:00:00+00:00\"},{\"actual\":68.90370440218273,\"falling_edge\":\"2017-08-13 03:00:00+00:00\",\"predicted\":68.90370440218273,\"rising_edge\":\"2017-08-13 02:30:00+00:00\"},{\"actual\":69.2668450696971,\"falling_edge\":\"2017-08-13 03:30:00+00:00\",\"predicted\":69.2668450696971,\"rising_edge\":\"2017-08-13 03:00:00+00:00\"},{\"actual\":68.8266101558864,\"falling_edge\":\"2017-08-13 04:00:00+00:00\",\"predicted\":68.8266101558864,\"rising_edge\":\"2017-08-13 03:30:00+00:00\"},{\"actual\":73.09365789865417,\"falling_edge\":\"2017-08-13 04:30:00+00:00\",\"predicted\":73.09365789865417,\"rising_edge\":\"2017-08-13 04:00:00+00:00\"},{\"actual\":73.7832647451016,\"falling_edge\":\"2017-08-13 05:00:00+00:00\",\"predicted\":73.7832647451016,\"rising_edge\":\"2017-08-13 04:30:00+00:00\"},{\"actual\":73.66124920218472,\"falling_edge\":\"2017-08-13 05:30:00+00:00\",\"predicted\":73.66124920218472,\"rising_edge\":\"2017-08-13 05:00:00+00:00\"},{\"actual\":76.6649896637411,\"falling_edge\":\"2017-08-13 06:00:00+00:00\",\"predicted\":76.6649896637411,\"rising_edge\":\"2017-08-13 05:30:00+00:00\"},{\"actual\":76.84979988441403,\"falling_edge\":\"2017-08-13 06:30:00+00:00\",\"predicted\":76.84979988441403,\"rising_edge\":\"2017-08-13 06:00:00+00:00\"},{\"actual\":80.22841490512693,\"falling_edge\":\"2017-08-13 07:00:00+00:00\",\"predicted\":80.22841490512693,\"rising_edge\":\"2017-08-13 06:30:00+00:00\"},{\"actual\":81.42168450796629,\"falling_edge\":\"2017-08-13 07:30:00+00:00\",\"predicted\":81.42168450796629,\"rising_edge\":\"2017-08-13 07:00:00+00:00\"},{\"actual\":79.55365935246755,\"falling_edge\":\"2017-08-13 08:00:00+00:00\",\"predicted\":79.55365935246755,\"rising_edge\":\"2017-08-13 07:30:00+00:00\"},{\"actual\":77.55908518798702,\"falling_edge\":\"2017-08-13 08:30:00+00:00\",\"predicted\":77.55908518798702,\"rising_edge\":\"2017-08-13 08:00:00+00:00\"},{\"actual\":74.18400595368273,\"falling_edge\":\"2017-08-13 09:00:00+00:00\",\"predicted\":74.18400595368273,\"rising_edge\":\"2017-08-13 08:30:00+00:00\"},{\"actual\":66.63105031595316,\"falling_edge\":\"2017-08-13 09:30:00+00:00\",\"predicted\":66.63105031595316,\"rising_edge\":\"2017-08-13 09:00:00+00:00\"},{\"actual\":64.36497673580303,\"falling_edge\":\"2017-08-13 10:00:00+00:00\",\"predicted\":64.36497673580303,\"rising_edge\":\"2017-08-13 09:30:00+00:00\"},{\"actual\":60.696431399418046,\"falling_edge\":\"2017-08-13 10:30:00+00:00\",\"predicted\":60.696431399418046,\"rising_edge\":\"2017-08-13 10:00:00+00:00\"},{\"actual\":60.16570292769407,\"falling_edge\":\"2017-08-13 11:00:00+00:00\",\"predicted\":60.16570292769407,\"rising_edge\":\"2017-08-13 10:30:00+00:00\"},{\"actual\":59.38106821392948,\"falling_edge\":\"2017-08-13 11:30:00+00:00\",\"predicted\":59.38106821392948,\"rising_edge\":\"2017-08-13 11:00:00+00:00\"},{\"actual\":59.31967598874854,\"falling_edge\":\"2017-08-13 12:00:00+00:00\",\"predicted\":59.31967598874854,\"rising_edge\":\"2017-08-13 11:30:00+00:00\"},{\"actual\":55.83837171320501,\"falling_edge\":\"2017-08-13 12:30:00+00:00\",\"predicted\":55.83837171320501,\"rising_edge\":\"2017-08-13 12:00:00+00:00\"},{\"actual\":53.6237963092964,\"falling_edge\":\"2017-08-13 13:00:00+00:00\",\"predicted\":53.6237963092964,\"rising_edge\":\"2017-08-13 12:30:00+00:00\"},{\"actual\":52.47491551853473,\"falling_edge\":\"2017-08-13 13:30:00+00:00\",\"predicted\":52.47491551853473,\"rising_edge\":\"2017-08-13 13:00:00+00:00\"},{\"actual\":50.20128992087897,\"falling_edge\":\"2017-08-13 14:00:00+00:00\",\"predicted\":50.20128992087897,\"rising_edge\":\"2017-08-13 13:30:00+00:00\"},{\"actual\":51.03985917952794,\"falling_edge\":\"2017-08-13 14:30:00+00:00\",\"predicted\":51.03985917952794,\"rising_edge\":\"2017-08-13 14:00:00+00:00\"},{\"actual\":49.24530452671577,\"falling_edge\":\"2017-08-13 15:00:00+00:00\",\"predicted\":49.24530452671577,\"rising_edge\":\"2017-08-13 14:30:00+00:00\"},{\"actual\":48.946270287249504,\"falling_edge\":\"2017-08-13 15:30:00+00:00\",\"predicted\":48.946270287249504,\"rising_edge\":\"2017-08-13 15:00:00+00:00\"},{\"actual\":48.05525342678571,\"falling_edge\":\"2017-08-13 16:00:00+00:00\",\"predicted\":48.05525342678571,\"rising_edge\":\"2017-08-13 15:30:00+00:00\"},{\"actual\":48.397744520045876,\"falling_edge\":\"2017-08-13 16:30:00+00:00\",\"predicted\":48.397744520045876,\"rising_edge\":\"2017-08-13 16:00:00+00:00\"},{\"actual\":47.00906497031298,\"falling_edge\":\"2017-08-13 17:00:00+00:00\",\"predicted\":47.00906497031298,\"rising_edge\":\"2017-08-13 16:30:00+00:00\"},{\"actual\":45.939444687981066,\"falling_edge\":\"2017-08-13 17:30:00+00:00\",\"predicted\":45.939444687981066,\"rising_edge\":\"2017-08-13 17:00:00+00:00\"},{\"actual\":46.621507186337766,\"falling_edge\":\"2017-08-13 18:00:00+00:00\",\"predicted\":46.621507186337766,\"rising_edge\":\"2017-08-13 17:30:00+00:00\"},{\"actual\":45.950839077990615,\"falling_edge\":\"2017-08-13 18:30:00+00:00\",\"predicted\":45.950839077990615,\"rising_edge\":\"2017-08-13 18:00:00+00:00\"},{\"actual\":46.32858686736054,\"falling_edge\":\"2017-08-13 19:00:00+00:00\",\"predicted\":46.32858686736054,\"rising_edge\":\"2017-08-13 18:30:00+00:00\"},{\"actual\":45.83973956296681,\"falling_edge\":\"2017-08-13 19:30:00+00:00\",\"predicted\":45.83973956296681,\"rising_edge\":\"2017-08-13 19:00:00+00:00\"},{\"actual\":46.11572474919584,\"falling_edge\":\"2017-08-13 20:00:00+00:00\",\"predicted\":46.11572474919584,\"rising_edge\":\"2017-08-13 19:30:00+00:00\"},{\"actual\":47.182386949345094,\"falling_edge\":\"2017-08-13 20:30:00+00:00\",\"predicted\":47.182386949345094,\"rising_edge\":\"2017-08-13 20:00:00+00:00\"},{\"actual\":52.005451873846404,\"falling_edge\":\"2017-08-13 21:00:00+00:00\",\"predicted\":52.005451873846404,\"rising_edge\":\"2017-08-13 20:30:00+00:00\"},{\"actual\":69.93372594507244,\"falling_edge\":\"2017-08-13 21:30:00+00:00\",\"predicted\":69.93372594507244,\"rising_edge\":\"2017-08-13 21:00:00+00:00\"},{\"actual\":125.37676394086421,\"falling_edge\":\"2017-08-13 22:00:00+00:00\",\"predicted\":125.37676394086421,\"rising_edge\":\"2017-08-13 21:30:00+00:00\"},{\"actual\":108.26803806872985,\"falling_edge\":\"2017-08-13 22:30:00+00:00\",\"predicted\":108.26803806872985,\"rising_edge\":\"2017-08-13 22:00:00+00:00\"},{\"actual\":126.75915124626042,\"falling_edge\":\"2017-08-13 23:00:00+00:00\",\"predicted\":126.75915124626042,\"rising_edge\":\"2017-08-13 22:30:00+00:00\"},{\"actual\":159.65033268058892,\"falling_edge\":\"2017-08-13 23:30:00+00:00\",\"predicted\":159.65033268058892,\"rising_edge\":\"2017-08-13 23:00:00+00:00\"},{\"actual\":199.06480476801036,\"falling_edge\":\"2017-08-14 00:00:00+00:00\",\"predicted\":199.06480476801036,\"rising_edge\":\"2017-08-13 23:30:00+00:00\"},{\"actual\":214.46453849301102,\"falling_edge\":\"2017-08-14 00:30:00+00:00\",\"predicted\":214.46453849301102,\"rising_edge\":\"2017-08-14 00:00:00+00:00\"},{\"actual\":222.64508623232967,\"falling_edge\":\"2017-08-14 01:00:00+00:00\",\"predicted\":222.64508623232967,\"rising_edge\":\"2017-08-14 00:30:00+00:00\"},{\"actual\":224.22945030325818,\"falling_edge\":\"2017-08-14 01:30:00+00:00\",\"predicted\":224.22945030325818,\"rising_edge\":\"2017-08-14 01:00:00+00:00\"},{\"actual\":219.0305586093534,\"falling_edge\":\"2017-08-14 02:00:00+00:00\",\"predicted\":219.0305586093534,\"rising_edge\":\"2017-08-14 01:30:00+00:00\"},{\"actual\":214.81592219042983,\"falling_edge\":\"2017-08-14 02:30:00+00:00\",\"predicted\":214.81592219042983,\"rising_edge\":\"2017-08-14 02:00:00+00:00\"},{\"actual\":210.40771103411245,\"falling_edge\":\"2017-08-14 03:00:00+00:00\",\"predicted\":210.40771103411245,\"rising_edge\":\"2017-08-14 02:30:00+00:00\"},{\"actual\":207.56700972583843,\"falling_edge\":\"2017-08-14 03:30:00+00:00\",\"predicted\":207.56700972583843,\"rising_edge\":\"2017-08-14 03:00:00+00:00\"},{\"actual\":198.21565791131096,\"falling_edge\":\"2017-08-14 04:00:00+00:00\",\"predicted\":198.21565791131096,\"rising_edge\":\"2017-08-14 03:30:00+00:00\"},{\"actual\":214.5569173382084,\"falling_edge\":\"2017-08-14 04:30:00+00:00\",\"predicted\":214.5569173382084,\"rising_edge\":\"2017-08-14 04:00:00+00:00\"},{\"actual\":213.0816592885271,\"falling_edge\":\"2017-08-14 05:00:00+00:00\",\"predicted\":213.0816592885271,\"rising_edge\":\"2017-08-14 04:30:00+00:00\"},{\"actual\":207.01765431758798,\"falling_edge\":\"2017-08-14 05:30:00+00:00\",\"predicted\":207.01765431758798,\"rising_edge\":\"2017-08-14 05:00:00+00:00\"},{\"actual\":215.61935674666532,\"falling_edge\":\"2017-08-14 06:00:00+00:00\",\"predicted\":215.61935674666532,\"rising_edge\":\"2017-08-14 05:30:00+00:00\"},{\"actual\":216.2437695417699,\"falling_edge\":\"2017-08-14 06:30:00+00:00\",\"predicted\":216.2437695417699,\"rising_edge\":\"2017-08-14 06:00:00+00:00\"},{\"actual\":218.29810545511577,\"falling_edge\":\"2017-08-14 07:00:00+00:00\",\"predicted\":218.29810545511577,\"rising_edge\":\"2017-08-14 06:30:00+00:00\"},{\"actual\":218.46763269483523,\"falling_edge\":\"2017-08-14 07:30:00+00:00\",\"predicted\":218.46763269483523,\"rising_edge\":\"2017-08-14 07:00:00+00:00\"},{\"actual\":222.75940936272818,\"falling_edge\":\"2017-08-14 08:00:00+00:00\",\"predicted\":222.75940936272818,\"rising_edge\":\"2017-08-14 07:30:00+00:00\"},{\"actual\":222.27192046884926,\"falling_edge\":\"2017-08-14 08:30:00+00:00\",\"predicted\":222.27192046884926,\"rising_edge\":\"2017-08-14 08:00:00+00:00\"},{\"actual\":205.4165838121583,\"falling_edge\":\"2017-08-14 09:00:00+00:00\",\"predicted\":205.4165838121583,\"rising_edge\":\"2017-08-14 08:30:00+00:00\"},{\"actual\":174.6053009370446,\"falling_edge\":\"2017-08-14 09:30:00+00:00\",\"predicted\":174.6053009370446,\"rising_edge\":\"2017-08-14 09:00:00+00:00\"},{\"actual\":160.25454587768988,\"falling_edge\":\"2017-08-14 10:00:00+00:00\",\"predicted\":160.25454587768988,\"rising_edge\":\"2017-08-14 09:30:00+00:00\"},{\"actual\":137.0944568123798,\"falling_edge\":\"2017-08-14 10:30:00+00:00\",\"predicted\":137.0944568123798,\"rising_edge\":\"2017-08-14 10:00:00+00:00\"},{\"actual\":134.0854462688491,\"falling_edge\":\"2017-08-14 11:00:00+00:00\",\"predicted\":134.0854462688491,\"rising_edge\":\"2017-08-14 10:30:00+00:00\"},{\"actual\":125.98992994397707,\"falling_edge\":\"2017-08-14 11:30:00+00:00\",\"predicted\":125.98992994397707,\"rising_edge\":\"2017-08-14 11:00:00+00:00\"},{\"actual\":113.62832518209127,\"falling_edge\":\"2017-08-14 12:00:00+00:00\",\"predicted\":113.62832518209127,\"rising_edge\":\"2017-08-14 11:30:00+00:00\"},{\"actual\":103.40372991102821,\"falling_edge\":\"2017-08-14 12:30:00+00:00\",\"predicted\":103.40372991102821,\"rising_edge\":\"2017-08-14 12:00:00+00:00\"},{\"actual\":94.8309602145741,\"falling_edge\":\"2017-08-14 13:00:00+00:00\",\"predicted\":94.8309602145741,\"rising_edge\":\"2017-08-14 12:30:00+00:00\"},{\"actual\":86.90000506604115,\"falling_edge\":\"2017-08-14 13:30:00+00:00\",\"predicted\":86.90000506604115,\"rising_edge\":\"2017-08-14 13:00:00+00:00\"},{\"actual\":75.64459543712545,\"falling_edge\":\"2017-08-14 14:00:00+00:00\",\"predicted\":75.64459543712545,\"rising_edge\":\"2017-08-14 13:30:00+00:00\"},{\"actual\":65.04155918496963,\"falling_edge\":\"2017-08-14 14:30:00+00:00\",\"predicted\":65.04155918496963,\"rising_edge\":\"2017-08-14 14:00:00+00:00\"},{\"actual\":57.72369757960356,\"falling_edge\":\"2017-08-14 15:00:00+00:00\",\"predicted\":57.72369757960356,\"rising_edge\":\"2017-08-14 14:30:00+00:00\"},{\"actual\":52.28165489695247,\"falling_edge\":\"2017-08-14 15:30:00+00:00\",\"predicted\":52.28165489695247,\"rising_edge\":\"2017-08-14 15:00:00+00:00\"},{\"actual\":47.530994365779,\"falling_edge\":\"2017-08-14 16:00:00+00:00\",\"predicted\":47.530994365779,\"rising_edge\":\"2017-08-14 15:30:00+00:00\"},{\"actual\":46.29287610562758,\"falling_edge\":\"2017-08-14 16:30:00+00:00\",\"predicted\":46.29287610562758,\"rising_edge\":\"2017-08-14 16:00:00+00:00\"},{\"actual\":45.893381939912885,\"falling_edge\":\"2017-08-14 17:00:00+00:00\",\"predicted\":45.893381939912885,\"rising_edge\":\"2017-08-14 16:30:00+00:00\"},{\"actual\":45.46249923545307,\"falling_edge\":\"2017-08-14 17:30:00+00:00\",\"predicted\":45.46249923545307,\"rising_edge\":\"2017-08-14 17:00:00+00:00\"},{\"actual\":45.00518187179576,\"falling_edge\":\"2017-08-14 18:00:00+00:00\",\"predicted\":45.00518187179576,\"rising_edge\":\"2017-08-14 17:30:00+00:00\"},{\"actual\":44.634748423857836,\"falling_edge\":\"2017-08-14 18:30:00+00:00\",\"predicted\":44.634748423857836,\"rising_edge\":\"2017-08-14 18:00:00+00:00\"},{\"actual\":44.00850075644931,\"falling_edge\":\"2017-08-14 19:00:00+00:00\",\"predicted\":44.00850075644931,\"rising_edge\":\"2017-08-14 18:30:00+00:00\"},{\"actual\":44.29432335501467,\"falling_edge\":\"2017-08-14 19:30:00+00:00\",\"predicted\":44.29432335501467,\"rising_edge\":\"2017-08-14 19:00:00+00:00\"},{\"actual\":43.50832453162324,\"falling_edge\":\"2017-08-14 20:00:00+00:00\",\"predicted\":43.50832453162324,\"rising_edge\":\"2017-08-14 19:30:00+00:00\"},{\"actual\":44.84782122717753,\"falling_edge\":\"2017-08-14 20:30:00+00:00\",\"predicted\":44.84782122717753,\"rising_edge\":\"2017-08-14 20:00:00+00:00\"},{\"actual\":49.73791707331431,\"falling_edge\":\"2017-08-14 21:00:00+00:00\",\"predicted\":49.73791707331431,\"rising_edge\":\"2017-08-14 20:30:00+00:00\"},{\"actual\":66.34890483187816,\"falling_edge\":\"2017-08-14 21:30:00+00:00\",\"predicted\":66.34890483187816,\"rising_edge\":\"2017-08-14 21:00:00+00:00\"},{\"actual\":98.03685086957441,\"falling_edge\":\"2017-08-14 22:00:00+00:00\",\"predicted\":98.03685086957441,\"rising_edge\":\"2017-08-14 21:30:00+00:00\"},{\"actual\":91.6350979504878,\"falling_edge\":\"2017-08-14 22:30:00+00:00\",\"predicted\":91.6350979504878,\"rising_edge\":\"2017-08-14 22:00:00+00:00\"},{\"actual\":113.7773164045531,\"falling_edge\":\"2017-08-14 23:00:00+00:00\",\"predicted\":113.7773164045531,\"rising_edge\":\"2017-08-14 22:30:00+00:00\"},{\"actual\":146.17196685480536,\"falling_edge\":\"2017-08-14 23:30:00+00:00\",\"predicted\":146.17196685480536,\"rising_edge\":\"2017-08-14 23:00:00+00:00\"},{\"actual\":186.2298591937707,\"falling_edge\":\"2017-08-15 00:00:00+00:00\",\"predicted\":186.2298591937707,\"rising_edge\":\"2017-08-14 23:30:00+00:00\"},{\"actual\":205.75979201392732,\"falling_edge\":\"2017-08-15 00:30:00+00:00\",\"predicted\":205.75979201392732,\"rising_edge\":\"2017-08-15 00:00:00+00:00\"},{\"actual\":208.88891876555633,\"falling_edge\":\"2017-08-15 01:00:00+00:00\",\"predicted\":208.88891876555633,\"rising_edge\":\"2017-08-15 00:30:00+00:00\"},{\"actual\":209.9192490238653,\"falling_edge\":\"2017-08-15 01:30:00+00:00\",\"predicted\":209.9192490238653,\"rising_edge\":\"2017-08-15 01:00:00+00:00\"},{\"actual\":215.99942967362946,\"falling_edge\":\"2017-08-15 02:00:00+00:00\",\"predicted\":215.99942967362946,\"rising_edge\":\"2017-08-15 01:30:00+00:00\"},{\"actual\":216.58295657172138,\"falling_edge\":\"2017-08-15 02:30:00+00:00\",\"predicted\":216.58295657172138,\"rising_edge\":\"2017-08-15 02:00:00+00:00\"},{\"actual\":215.56249213487123,\"falling_edge\":\"2017-08-15 03:00:00+00:00\",\"predicted\":215.56249213487123,\"rising_edge\":\"2017-08-15 02:30:00+00:00\"},{\"actual\":204.96496694990472,\"falling_edge\":\"2017-08-15 03:30:00+00:00\",\"predicted\":204.96496694990472,\"rising_edge\":\"2017-08-15 03:00:00+00:00\"},{\"actual\":199.1539246656307,\"falling_edge\":\"2017-08-15 04:00:00+00:00\",\"predicted\":199.1539246656307,\"rising_edge\":\"2017-08-15 03:30:00+00:00\"},{\"actual\":209.1622734211775,\"falling_edge\":\"2017-08-15 04:30:00+00:00\",\"predicted\":209.1622734211775,\"rising_edge\":\"2017-08-15 04:00:00+00:00\"},{\"actual\":208.24374726081865,\"falling_edge\":\"2017-08-15 05:00:00+00:00\",\"predicted\":208.24374726081865,\"rising_edge\":\"2017-08-15 04:30:00+00:00\"},{\"actual\":204.603661516441,\"falling_edge\":\"2017-08-15 05:30:00+00:00\",\"predicted\":204.603661516441,\"rising_edge\":\"2017-08-15 05:00:00+00:00\"},{\"actual\":209.6219770934909,\"falling_edge\":\"2017-08-15 06:00:00+00:00\",\"predicted\":209.6219770934909,\"rising_edge\":\"2017-08-15 05:30:00+00:00\"},{\"actual\":210.61187221106988,\"falling_edge\":\"2017-08-15 06:30:00+00:00\",\"predicted\":210.61187221106988,\"rising_edge\":\"2017-08-15 06:00:00+00:00\"},{\"actual\":210.93132627042002,\"falling_edge\":\"2017-08-15 07:00:00+00:00\",\"predicted\":210.93132627042002,\"rising_edge\":\"2017-08-15 06:30:00+00:00\"},{\"actual\":211.13717126729307,\"falling_edge\":\"2017-08-15 07:30:00+00:00\",\"predicted\":211.13717126729307,\"rising_edge\":\"2017-08-15 07:00:00+00:00\"},{\"actual\":207.33475250487533,\"falling_edge\":\"2017-08-15 08:00:00+00:00\",\"predicted\":207.33475250487533,\"rising_edge\":\"2017-08-15 07:30:00+00:00\"},{\"actual\":211.11349353873564,\"falling_edge\":\"2017-08-15 08:30:00+00:00\",\"predicted\":211.11349353873564,\"rising_edge\":\"2017-08-15 08:00:00+00:00\"},{\"actual\":203.7407599560672,\"falling_edge\":\"2017-08-15 09:00:00+00:00\",\"predicted\":203.7407599560672,\"rising_edge\":\"2017-08-15 08:30:00+00:00\"},{\"actual\":177.9461486971856,\"falling_edge\":\"2017-08-15 09:30:00+00:00\",\"predicted\":177.9461486971856,\"rising_edge\":\"2017-08-15 09:00:00+00:00\"},{\"actual\":161.74590188192875,\"falling_edge\":\"2017-08-15 10:00:00+00:00\",\"predicted\":161.74590188192875,\"rising_edge\":\"2017-08-15 09:30:00+00:00\"},{\"actual\":142.88696677290307,\"falling_edge\":\"2017-08-15 10:30:00+00:00\",\"predicted\":142.88696677290307,\"rising_edge\":\"2017-08-15 10:00:00+00:00\"},{\"actual\":140.15365779258616,\"falling_edge\":\"2017-08-15 11:00:00+00:00\",\"predicted\":140.15365779258616,\"rising_edge\":\"2017-08-15 10:30:00+00:00\"},{\"actual\":133.59084681720586,\"falling_edge\":\"2017-08-15 11:30:00+00:00\",\"predicted\":133.59084681720586,\"rising_edge\":\"2017-08-15 11:00:00+00:00\"},{\"actual\":124.67849861643799,\"falling_edge\":\"2017-08-15 12:00:00+00:00\",\"predicted\":124.67849861643799,\"rising_edge\":\"2017-08-15 11:30:00+00:00\"},{\"actual\":112.59920651437098,\"falling_edge\":\"2017-08-15 12:30:00+00:00\",\"predicted\":112.59920651437098,\"rising_edge\":\"2017-08-15 12:00:00+00:00\"},{\"actual\":99.74965307816484,\"falling_edge\":\"2017-08-15 13:00:00+00:00\",\"predicted\":99.74965307816484,\"rising_edge\":\"2017-08-15 12:30:00+00:00\"},{\"actual\":90.66583704781327,\"falling_edge\":\"2017-08-15 13:30:00+00:00\",\"predicted\":90.66583704781327,\"rising_edge\":\"2017-08-15 13:00:00+00:00\"},{\"actual\":76.67392522242662,\"falling_edge\":\"2017-08-15 14:00:00+00:00\",\"predicted\":76.67392522242662,\"rising_edge\":\"2017-08-15 13:30:00+00:00\"},{\"actual\":66.02496691894427,\"falling_edge\":\"2017-08-15 14:30:00+00:00\",\"predicted\":66.02496691894427,\"rising_edge\":\"2017-08-15 14:00:00+00:00\"},{\"actual\":58.374468175596746,\"falling_edge\":\"2017-08-15 15:00:00+00:00\",\"predicted\":58.374468175596746,\"rising_edge\":\"2017-08-15 14:30:00+00:00\"},{\"actual\":53.53229793465219,\"falling_edge\":\"2017-08-15 15:30:00+00:00\",\"predicted\":53.53229793465219,\"rising_edge\":\"2017-08-15 15:00:00+00:00\"},{\"actual\":50.3646915792848,\"falling_edge\":\"2017-08-15 16:00:00+00:00\",\"predicted\":50.3646915792848,\"rising_edge\":\"2017-08-15 15:30:00+00:00\"},{\"actual\":51.895767623219676,\"falling_edge\":\"2017-08-15 16:30:00+00:00\",\"predicted\":51.895767623219676,\"rising_edge\":\"2017-08-15 16:00:00+00:00\"},{\"actual\":49.45944862494896,\"falling_edge\":\"2017-08-15 17:00:00+00:00\",\"predicted\":49.45944862494896,\"rising_edge\":\"2017-08-15 16:30:00+00:00\"},{\"actual\":47.698942698904474,\"falling_edge\":\"2017-08-15 17:30:00+00:00\",\"predicted\":47.698942698904474,\"rising_edge\":\"2017-08-15 17:00:00+00:00\"},{\"actual\":47.5402861786553,\"falling_edge\":\"2017-08-15 18:00:00+00:00\",\"predicted\":47.5402861786553,\"rising_edge\":\"2017-08-15 17:30:00+00:00\"},{\"actual\":45.58759093808503,\"falling_edge\":\"2017-08-15 18:30:00+00:00\",\"predicted\":45.58759093808503,\"rising_edge\":\"2017-08-15 18:00:00+00:00\"},{\"actual\":44.45877146320051,\"falling_edge\":\"2017-08-15 19:00:00+00:00\",\"predicted\":44.45877146320051,\"rising_edge\":\"2017-08-15 18:30:00+00:00\"},{\"actual\":45.91259902565705,\"falling_edge\":\"2017-08-15 19:30:00+00:00\",\"predicted\":45.91259902565705,\"rising_edge\":\"2017-08-15 19:00:00+00:00\"},{\"actual\":45.71302130123724,\"falling_edge\":\"2017-08-15 20:00:00+00:00\",\"predicted\":45.71302130123724,\"rising_edge\":\"2017-08-15 19:30:00+00:00\"},{\"actual\":47.252883912847686,\"falling_edge\":\"2017-08-15 20:30:00+00:00\",\"predicted\":47.252883912847686,\"rising_edge\":\"2017-08-15 20:00:00+00:00\"},{\"actual\":52.386545721197784,\"falling_edge\":\"2017-08-15 21:00:00+00:00\",\"predicted\":52.386545721197784,\"rising_edge\":\"2017-08-15 20:30:00+00:00\"},{\"actual\":69.59140489486299,\"falling_edge\":\"2017-08-15 21:30:00+00:00\",\"predicted\":69.59140489486299,\"rising_edge\":\"2017-08-15 21:00:00+00:00\"},{\"actual\":102.29992404694572,\"falling_edge\":\"2017-08-15 22:00:00+00:00\",\"predicted\":102.29992404694572,\"rising_edge\":\"2017-08-15 21:30:00+00:00\"},{\"actual\":98.0827505506442,\"falling_edge\":\"2017-08-15 22:30:00+00:00\",\"predicted\":98.0827505506442,\"rising_edge\":\"2017-08-15 22:00:00+00:00\"},{\"actual\":116.85962256898664,\"falling_edge\":\"2017-08-15 23:00:00+00:00\",\"predicted\":116.85962256898664,\"rising_edge\":\"2017-08-15 22:30:00+00:00\"},{\"actual\":156.5607377691876,\"falling_edge\":\"2017-08-15 23:30:00+00:00\",\"predicted\":156.5607377691876,\"rising_edge\":\"2017-08-15 23:00:00+00:00\"},{\"actual\":204.93710918278018,\"falling_edge\":\"2017-08-16 00:00:00+00:00\",\"predicted\":204.93710918278018,\"rising_edge\":\"2017-08-15 23:30:00+00:00\"},{\"actual\":214.06943987471374,\"falling_edge\":\"2017-08-16 00:30:00+00:00\",\"predicted\":214.06943987471374,\"rising_edge\":\"2017-08-16 00:00:00+00:00\"},{\"actual\":217.9155701578573,\"falling_edge\":\"2017-08-16 01:00:00+00:00\",\"predicted\":217.9155701578573,\"rising_edge\":\"2017-08-16 00:30:00+00:00\"},{\"actual\":228.14621395887505,\"falling_edge\":\"2017-08-16 01:30:00+00:00\",\"predicted\":228.14621395887505,\"rising_edge\":\"2017-08-16 01:00:00+00:00\"},{\"actual\":219.884036025844,\"falling_edge\":\"2017-08-16 02:00:00+00:00\",\"predicted\":219.884036025844,\"rising_edge\":\"2017-08-16 01:30:00+00:00\"},{\"actual\":220.54682907843767,\"falling_edge\":\"2017-08-16 02:30:00+00:00\",\"predicted\":220.54682907843767,\"rising_edge\":\"2017-08-16 02:00:00+00:00\"},{\"actual\":220.19695696640122,\"falling_edge\":\"2017-08-16 03:00:00+00:00\",\"predicted\":220.19695696640122,\"rising_edge\":\"2017-08-16 02:30:00+00:00\"},{\"actual\":218.85610740253628,\"falling_edge\":\"2017-08-16 03:30:00+00:00\",\"predicted\":218.85610740253628,\"rising_edge\":\"2017-08-16 03:00:00+00:00\"},{\"actual\":206.6043822186573,\"falling_edge\":\"2017-08-16 04:00:00+00:00\",\"predicted\":206.6043822186573,\"rising_edge\":\"2017-08-16 03:30:00+00:00\"},{\"actual\":219.51583741280496,\"falling_edge\":\"2017-08-16 04:30:00+00:00\",\"predicted\":219.51583741280496,\"rising_edge\":\"2017-08-16 04:00:00+00:00\"},{\"actual\":224.42598741162624,\"falling_edge\":\"2017-08-16 05:00:00+00:00\",\"predicted\":224.42598741162624,\"rising_edge\":\"2017-08-16 04:30:00+00:00\"},{\"actual\":219.55884282689283,\"falling_edge\":\"2017-08-16 05:30:00+00:00\",\"predicted\":219.55884282689283,\"rising_edge\":\"2017-08-16 05:00:00+00:00\"},{\"actual\":227.68160364751392,\"falling_edge\":\"2017-08-16 06:00:00+00:00\",\"predicted\":227.68160364751392,\"rising_edge\":\"2017-08-16 05:30:00+00:00\"},{\"actual\":239.73617709250942,\"falling_edge\":\"2017-08-16 06:30:00+00:00\",\"predicted\":239.73617709250942,\"rising_edge\":\"2017-08-16 06:00:00+00:00\"},{\"actual\":236.90348842214718,\"falling_edge\":\"2017-08-16 07:00:00+00:00\",\"predicted\":236.90348842214718,\"rising_edge\":\"2017-08-16 06:30:00+00:00\"},{\"actual\":240.00296494961214,\"falling_edge\":\"2017-08-16 07:30:00+00:00\",\"predicted\":240.00296494961214,\"rising_edge\":\"2017-08-16 07:00:00+00:00\"},{\"actual\":234.58962020297668,\"falling_edge\":\"2017-08-16 08:00:00+00:00\",\"predicted\":234.58962020297668,\"rising_edge\":\"2017-08-16 07:30:00+00:00\"},{\"actual\":228.23717697735316,\"falling_edge\":\"2017-08-16 08:30:00+00:00\",\"predicted\":228.23717697735316,\"rising_edge\":\"2017-08-16 08:00:00+00:00\"},{\"actual\":213.3624994660141,\"falling_edge\":\"2017-08-16 09:00:00+00:00\",\"predicted\":213.3624994660141,\"rising_edge\":\"2017-08-16 08:30:00+00:00\"},{\"actual\":174.708225488233,\"falling_edge\":\"2017-08-16 09:30:00+00:00\",\"predicted\":174.708225488233,\"rising_edge\":\"2017-08-16 09:00:00+00:00\"},{\"actual\":154.2489469037698,\"falling_edge\":\"2017-08-16 10:00:00+00:00\",\"predicted\":154.2489469037698,\"rising_edge\":\"2017-08-16 09:30:00+00:00\"},{\"actual\":126.64795336108304,\"falling_edge\":\"2017-08-16 10:30:00+00:00\",\"predicted\":126.64795336108304,\"rising_edge\":\"2017-08-16 10:00:00+00:00\"},{\"actual\":120.78602871861456,\"falling_edge\":\"2017-08-16 11:00:00+00:00\",\"predicted\":120.78602871861456,\"rising_edge\":\"2017-08-16 10:30:00+00:00\"},{\"actual\":112.18576822071485,\"falling_edge\":\"2017-08-16 11:30:00+00:00\",\"predicted\":112.18576822071485,\"rising_edge\":\"2017-08-16 11:00:00+00:00\"},{\"actual\":106.6278311528914,\"falling_edge\":\"2017-08-16 12:00:00+00:00\",\"predicted\":106.6278311528914,\"rising_edge\":\"2017-08-16 11:30:00+00:00\"},{\"actual\":99.97976873893994,\"falling_edge\":\"2017-08-16 12:30:00+00:00\",\"predicted\":99.97976873893994,\"rising_edge\":\"2017-08-16 12:00:00+00:00\"},{\"actual\":91.5702578536728,\"falling_edge\":\"2017-08-16 13:00:00+00:00\",\"predicted\":91.5702578536728,\"rising_edge\":\"2017-08-16 12:30:00+00:00\"},{\"actual\":78.42619381124034,\"falling_edge\":\"2017-08-16 13:30:00+00:00\",\"predicted\":78.42619381124034,\"rising_edge\":\"2017-08-16 13:00:00+00:00\"},{\"actual\":69.18371159839943,\"falling_edge\":\"2017-08-16 14:00:00+00:00\",\"predicted\":69.18371159839943,\"rising_edge\":\"2017-08-16 13:30:00+00:00\"},{\"actual\":61.23796368580989,\"falling_edge\":\"2017-08-16 14:30:00+00:00\",\"predicted\":61.23796368580989,\"rising_edge\":\"2017-08-16 14:00:00+00:00\"},{\"actual\":55.45261361763604,\"falling_edge\":\"2017-08-16 15:00:00+00:00\",\"predicted\":55.45261361763604,\"rising_edge\":\"2017-08-16 14:30:00+00:00\"},{\"actual\":51.11510368022427,\"falling_edge\":\"2017-08-16 15:30:00+00:00\",\"predicted\":51.11510368022427,\"rising_edge\":\"2017-08-16 15:00:00+00:00\"},{\"actual\":49.18244449537888,\"falling_edge\":\"2017-08-16 16:00:00+00:00\",\"predicted\":49.18244449537888,\"rising_edge\":\"2017-08-16 15:30:00+00:00\"},{\"actual\":47.54804613363595,\"falling_edge\":\"2017-08-16 16:30:00+00:00\",\"predicted\":47.54804613363595,\"rising_edge\":\"2017-08-16 16:00:00+00:00\"},{\"actual\":47.19974380544478,\"falling_edge\":\"2017-08-16 17:00:00+00:00\",\"predicted\":47.19974380544478,\"rising_edge\":\"2017-08-16 16:30:00+00:00\"},{\"actual\":48.02836231708202,\"falling_edge\":\"2017-08-16 17:30:00+00:00\",\"predicted\":48.02836231708202,\"rising_edge\":\"2017-08-16 17:00:00+00:00\"},{\"actual\":47.39089483878679,\"falling_edge\":\"2017-08-16 18:00:00+00:00\",\"predicted\":47.39089483878679,\"rising_edge\":\"2017-08-16 17:30:00+00:00\"},{\"actual\":46.51110653357058,\"falling_edge\":\"2017-08-16 18:30:00+00:00\",\"predicted\":46.51110653357058,\"rising_edge\":\"2017-08-16 18:00:00+00:00\"},{\"actual\":45.92397583045244,\"falling_edge\":\"2017-08-16 19:00:00+00:00\",\"predicted\":45.92397583045244,\"rising_edge\":\"2017-08-16 18:30:00+00:00\"},{\"actual\":45.55801581385789,\"falling_edge\":\"2017-08-16 19:30:00+00:00\",\"predicted\":45.55801581385789,\"rising_edge\":\"2017-08-16 19:00:00+00:00\"},{\"actual\":45.670398982397614,\"falling_edge\":\"2017-08-16 20:00:00+00:00\",\"predicted\":45.670398982397614,\"rising_edge\":\"2017-08-16 19:30:00+00:00\"},{\"actual\":46.771694525730915,\"falling_edge\":\"2017-08-16 20:30:00+00:00\",\"predicted\":46.771694525730915,\"rising_edge\":\"2017-08-16 20:00:00+00:00\"},{\"actual\":51.662963042670334,\"falling_edge\":\"2017-08-16 21:00:00+00:00\",\"predicted\":51.662963042670334,\"rising_edge\":\"2017-08-16 20:30:00+00:00\"},{\"actual\":70.15026499937325,\"falling_edge\":\"2017-08-16 21:30:00+00:00\",\"predicted\":70.15026499937325,\"rising_edge\":\"2017-08-16 21:00:00+00:00\"},{\"actual\":102.74408059743243,\"falling_edge\":\"2017-08-16 22:00:00+00:00\",\"predicted\":102.74408059743243,\"rising_edge\":\"2017-08-16 21:30:00+00:00\"},{\"actual\":102.92667668150065,\"falling_edge\":\"2017-08-16 22:30:00+00:00\",\"predicted\":102.92667668150065,\"rising_edge\":\"2017-08-16 22:00:00+00:00\"},{\"actual\":124.68224725236412,\"falling_edge\":\"2017-08-16 23:00:00+00:00\",\"predicted\":124.68224725236412,\"rising_edge\":\"2017-08-16 22:30:00+00:00\"},{\"actual\":164.026308616838,\"falling_edge\":\"2017-08-16 23:30:00+00:00\",\"predicted\":164.026308616838,\"rising_edge\":\"2017-08-16 23:00:00+00:00\"},{\"actual\":201.80509856833464,\"falling_edge\":\"2017-08-17 00:00:00+00:00\",\"predicted\":201.80509856833464,\"rising_edge\":\"2017-08-16 23:30:00+00:00\"},{\"actual\":210.70827408142253,\"falling_edge\":\"2017-08-17 00:30:00+00:00\",\"predicted\":210.70827408142253,\"rising_edge\":\"2017-08-17 00:00:00+00:00\"},{\"actual\":206.42256130743658,\"falling_edge\":\"2017-08-17 01:00:00+00:00\",\"predicted\":206.42256130743658,\"rising_edge\":\"2017-08-17 00:30:00+00:00\"},{\"actual\":214.00911859866068,\"falling_edge\":\"2017-08-17 01:30:00+00:00\",\"predicted\":214.00911859866068,\"rising_edge\":\"2017-08-17 01:00:00+00:00\"},{\"actual\":217.03196444314844,\"falling_edge\":\"2017-08-17 02:00:00+00:00\",\"predicted\":217.03196444314844,\"rising_edge\":\"2017-08-17 01:30:00+00:00\"},{\"actual\":221.29422849247027,\"falling_edge\":\"2017-08-17 02:30:00+00:00\",\"predicted\":221.29422849247027,\"rising_edge\":\"2017-08-17 02:00:00+00:00\"},{\"actual\":214.34722783038745,\"falling_edge\":\"2017-08-17 03:00:00+00:00\",\"predicted\":214.34722783038745,\"rising_edge\":\"2017-08-17 02:30:00+00:00\"},{\"actual\":212.7239998248889,\"falling_edge\":\"2017-08-17 03:30:00+00:00\",\"predicted\":212.7239998248889,\"rising_edge\":\"2017-08-17 03:00:00+00:00\"},{\"actual\":204.56128176181957,\"falling_edge\":\"2017-08-17 04:00:00+00:00\",\"predicted\":204.56128176181957,\"rising_edge\":\"2017-08-17 03:30:00+00:00\"},{\"actual\":213.86255614396325,\"falling_edge\":\"2017-08-17 04:30:00+00:00\",\"predicted\":213.86255614396325,\"rising_edge\":\"2017-08-17 04:00:00+00:00\"},{\"actual\":213.99502799069685,\"falling_edge\":\"2017-08-17 05:00:00+00:00\",\"predicted\":213.99502799069685,\"rising_edge\":\"2017-08-17 04:30:00+00:00\"},{\"actual\":214.71928159884266,\"falling_edge\":\"2017-08-17 05:30:00+00:00\",\"predicted\":214.71928159884266,\"rising_edge\":\"2017-08-17 05:00:00+00:00\"},{\"actual\":224.18779617986533,\"falling_edge\":\"2017-08-17 06:00:00+00:00\",\"predicted\":224.18779617986533,\"rising_edge\":\"2017-08-17 05:30:00+00:00\"},{\"actual\":222.08759044084962,\"falling_edge\":\"2017-08-17 06:30:00+00:00\",\"predicted\":222.08759044084962,\"rising_edge\":\"2017-08-17 06:00:00+00:00\"},{\"actual\":227.66723227364858,\"falling_edge\":\"2017-08-17 07:00:00+00:00\",\"predicted\":227.66723227364858,\"rising_edge\":\"2017-08-17 06:30:00+00:00\"},{\"actual\":226.340365251805,\"falling_edge\":\"2017-08-17 07:30:00+00:00\",\"predicted\":226.340365251805,\"rising_edge\":\"2017-08-17 07:00:00+00:00\"},{\"actual\":222.88645406736774,\"falling_edge\":\"2017-08-17 08:00:00+00:00\",\"predicted\":222.88645406736774,\"rising_edge\":\"2017-08-17 07:30:00+00:00\"},{\"actual\":220.60803891527786,\"falling_edge\":\"2017-08-17 08:30:00+00:00\",\"predicted\":220.60803891527786,\"rising_edge\":\"2017-08-17 08:00:00+00:00\"},{\"actual\":208.08620677993062,\"falling_edge\":\"2017-08-17 09:00:00+00:00\",\"predicted\":208.08620677993062,\"rising_edge\":\"2017-08-17 08:30:00+00:00\"},{\"actual\":185.4723843389947,\"falling_edge\":\"2017-08-17 09:30:00+00:00\",\"predicted\":185.4723843389947,\"rising_edge\":\"2017-08-17 09:00:00+00:00\"},{\"actual\":167.42697886188955,\"falling_edge\":\"2017-08-17 10:00:00+00:00\",\"predicted\":167.42697886188955,\"rising_edge\":\"2017-08-17 09:30:00+00:00\"},{\"actual\":142.05842626413386,\"falling_edge\":\"2017-08-17 10:30:00+00:00\",\"predicted\":142.05842626413386,\"rising_edge\":\"2017-08-17 10:00:00+00:00\"},{\"actual\":137.34299471447565,\"falling_edge\":\"2017-08-17 11:00:00+00:00\",\"predicted\":137.34299471447565,\"rising_edge\":\"2017-08-17 10:30:00+00:00\"},{\"actual\":130.588676468772,\"falling_edge\":\"2017-08-17 11:30:00+00:00\",\"predicted\":130.588676468772,\"rising_edge\":\"2017-08-17 11:00:00+00:00\"},{\"actual\":119.15168350566867,\"falling_edge\":\"2017-08-17 12:00:00+00:00\",\"predicted\":119.15168350566867,\"rising_edge\":\"2017-08-17 11:30:00+00:00\"},{\"actual\":108.26379826185983,\"falling_edge\":\"2017-08-17 12:30:00+00:00\",\"predicted\":108.26379826185983,\"rising_edge\":\"2017-08-17 12:00:00+00:00\"},{\"actual\":97.03157549039915,\"falling_edge\":\"2017-08-17 13:00:00+00:00\",\"predicted\":97.03157549039915,\"rising_edge\":\"2017-08-17 12:30:00+00:00\"},{\"actual\":84.52803476038189,\"falling_edge\":\"2017-08-17 13:30:00+00:00\",\"predicted\":84.52803476038189,\"rising_edge\":\"2017-08-17 13:00:00+00:00\"},{\"actual\":74.49312098110914,\"falling_edge\":\"2017-08-17 14:00:00+00:00\",\"predicted\":74.49312098110914,\"rising_edge\":\"2017-08-17 13:30:00+00:00\"},{\"actual\":68.26062275829032,\"falling_edge\":\"2017-08-17 14:30:00+00:00\",\"predicted\":68.26062275829032,\"rising_edge\":\"2017-08-17 14:00:00+00:00\"},{\"actual\":60.708284937718346,\"falling_edge\":\"2017-08-17 15:00:00+00:00\",\"predicted\":60.708284937718346,\"rising_edge\":\"2017-08-17 14:30:00+00:00\"},{\"actual\":52.99304525034161,\"falling_edge\":\"2017-08-17 15:30:00+00:00\",\"predicted\":52.99304525034161,\"rising_edge\":\"2017-08-17 15:00:00+00:00\"},{\"actual\":48.54606941263905,\"falling_edge\":\"2017-08-17 16:00:00+00:00\",\"predicted\":48.54606941263905,\"rising_edge\":\"2017-08-17 15:30:00+00:00\"},{\"actual\":46.977435302639364,\"falling_edge\":\"2017-08-17 16:30:00+00:00\",\"predicted\":46.977435302639364,\"rising_edge\":\"2017-08-17 16:00:00+00:00\"},{\"actual\":47.68211735588635,\"falling_edge\":\"2017-08-17 17:00:00+00:00\",\"predicted\":47.68211735588635,\"rising_edge\":\"2017-08-17 16:30:00+00:00\"},{\"actual\":47.59819729488121,\"falling_edge\":\"2017-08-17 17:30:00+00:00\",\"predicted\":47.59819729488121,\"rising_edge\":\"2017-08-17 17:00:00+00:00\"},{\"actual\":46.2321568516392,\"falling_edge\":\"2017-08-17 18:00:00+00:00\",\"predicted\":46.2321568516392,\"rising_edge\":\"2017-08-17 17:30:00+00:00\"},{\"actual\":46.777472772083556,\"falling_edge\":\"2017-08-17 18:30:00+00:00\",\"predicted\":46.777472772083556,\"rising_edge\":\"2017-08-17 18:00:00+00:00\"},{\"actual\":46.3178803957191,\"falling_edge\":\"2017-08-17 19:00:00+00:00\",\"predicted\":46.3178803957191,\"rising_edge\":\"2017-08-17 18:30:00+00:00\"},{\"actual\":47.21274588680047,\"falling_edge\":\"2017-08-17 19:30:00+00:00\",\"predicted\":47.21274588680047,\"rising_edge\":\"2017-08-17 19:00:00+00:00\"},{\"actual\":46.20709427593958,\"falling_edge\":\"2017-08-17 20:00:00+00:00\",\"predicted\":46.20709427593958,\"rising_edge\":\"2017-08-17 19:30:00+00:00\"},{\"actual\":48.1123798761588,\"falling_edge\":\"2017-08-17 20:30:00+00:00\",\"predicted\":48.1123798761588,\"rising_edge\":\"2017-08-17 20:00:00+00:00\"},{\"actual\":52.479894587714554,\"falling_edge\":\"2017-08-17 21:00:00+00:00\",\"predicted\":52.479894587714554,\"rising_edge\":\"2017-08-17 20:30:00+00:00\"},{\"actual\":68.60769244569806,\"falling_edge\":\"2017-08-17 21:30:00+00:00\",\"predicted\":68.60769244569806,\"rising_edge\":\"2017-08-17 21:00:00+00:00\"},{\"actual\":107.27006932391907,\"falling_edge\":\"2017-08-17 22:00:00+00:00\",\"predicted\":107.27006932391907,\"rising_edge\":\"2017-08-17 21:30:00+00:00\"},{\"actual\":103.13210455597797,\"falling_edge\":\"2017-08-17 22:30:00+00:00\",\"predicted\":103.13210455597797,\"rising_edge\":\"2017-08-17 22:00:00+00:00\"},{\"actual\":122.71196840695627,\"falling_edge\":\"2017-08-17 23:00:00+00:00\",\"predicted\":122.71196840695627,\"rising_edge\":\"2017-08-17 22:30:00+00:00\"},{\"actual\":155.24032296065172,\"falling_edge\":\"2017-08-17 23:30:00+00:00\",\"predicted\":155.24032296065172,\"rising_edge\":\"2017-08-17 23:00:00+00:00\"},{\"actual\":201.38553486191327,\"falling_edge\":\"2017-08-18 00:00:00+00:00\",\"predicted\":201.38553486191327,\"rising_edge\":\"2017-08-17 23:30:00+00:00\"},{\"actual\":214.58835997248812,\"falling_edge\":\"2017-08-18 00:30:00+00:00\",\"predicted\":214.58835997248812,\"rising_edge\":\"2017-08-18 00:00:00+00:00\"},{\"actual\":214.97798387577734,\"falling_edge\":\"2017-08-18 01:00:00+00:00\",\"predicted\":214.97798387577734,\"rising_edge\":\"2017-08-18 00:30:00+00:00\"},{\"actual\":222.84042101787318,\"falling_edge\":\"2017-08-18 01:30:00+00:00\",\"predicted\":222.84042101787318,\"rising_edge\":\"2017-08-18 01:00:00+00:00\"},{\"actual\":221.48725003911113,\"falling_edge\":\"2017-08-18 02:00:00+00:00\",\"predicted\":221.48725003911113,\"rising_edge\":\"2017-08-18 01:30:00+00:00\"},{\"actual\":217.5492370815103,\"falling_edge\":\"2017-08-18 02:30:00+00:00\",\"predicted\":217.5492370815103,\"rising_edge\":\"2017-08-18 02:00:00+00:00\"},{\"actual\":212.14203479768608,\"falling_edge\":\"2017-08-18 03:00:00+00:00\",\"predicted\":212.14203479768608,\"rising_edge\":\"2017-08-18 02:30:00+00:00\"},{\"actual\":207.89686210423895,\"falling_edge\":\"2017-08-18 03:30:00+00:00\",\"predicted\":207.89686210423895,\"rising_edge\":\"2017-08-18 03:00:00+00:00\"},{\"actual\":190.85500797368783,\"falling_edge\":\"2017-08-18 04:00:00+00:00\",\"predicted\":190.85500797368783,\"rising_edge\":\"2017-08-18 03:30:00+00:00\"},{\"actual\":206.74926621026583,\"falling_edge\":\"2017-08-18 04:30:00+00:00\",\"predicted\":206.74926621026583,\"rising_edge\":\"2017-08-18 04:00:00+00:00\"},{\"actual\":211.54615740869934,\"falling_edge\":\"2017-08-18 05:00:00+00:00\",\"predicted\":211.54615740869934,\"rising_edge\":\"2017-08-18 04:30:00+00:00\"},{\"actual\":205.73140072088515,\"falling_edge\":\"2017-08-18 05:30:00+00:00\",\"predicted\":205.73140072088515,\"rising_edge\":\"2017-08-18 05:00:00+00:00\"},{\"actual\":207.48463220704886,\"falling_edge\":\"2017-08-18 06:00:00+00:00\",\"predicted\":207.48463220704886,\"rising_edge\":\"2017-08-18 05:30:00+00:00\"},{\"actual\":208.2734364613314,\"falling_edge\":\"2017-08-18 06:30:00+00:00\",\"predicted\":208.2734364613314,\"rising_edge\":\"2017-08-18 06:00:00+00:00\"},{\"actual\":214.27831659876915,\"falling_edge\":\"2017-08-18 07:00:00+00:00\",\"predicted\":214.27831659876915,\"rising_edge\":\"2017-08-18 06:30:00+00:00\"},{\"actual\":212.34666346952983,\"falling_edge\":\"2017-08-18 07:30:00+00:00\",\"predicted\":212.34666346952983,\"rising_edge\":\"2017-08-18 07:00:00+00:00\"},{\"actual\":216.18317609644436,\"falling_edge\":\"2017-08-18 08:00:00+00:00\",\"predicted\":216.18317609644436,\"rising_edge\":\"2017-08-18 07:30:00+00:00\"},{\"actual\":223.72591373252453,\"falling_edge\":\"2017-08-18 08:30:00+00:00\",\"predicted\":223.72591373252453,\"rising_edge\":\"2017-08-18 08:00:00+00:00\"},{\"actual\":207.16168122108328,\"falling_edge\":\"2017-08-18 09:00:00+00:00\",\"predicted\":207.16168122108328,\"rising_edge\":\"2017-08-18 08:30:00+00:00\"},{\"actual\":182.51303470692767,\"falling_edge\":\"2017-08-18 09:30:00+00:00\",\"predicted\":182.51303470692767,\"rising_edge\":\"2017-08-18 09:00:00+00:00\"},{\"actual\":157.8973184496208,\"falling_edge\":\"2017-08-18 10:00:00+00:00\",\"predicted\":157.8973184496208,\"rising_edge\":\"2017-08-18 09:30:00+00:00\"},{\"actual\":132.08753023620017,\"falling_edge\":\"2017-08-18 10:30:00+00:00\",\"predicted\":132.08753023620017,\"rising_edge\":\"2017-08-18 10:00:00+00:00\"},{\"actual\":124.18617867230817,\"falling_edge\":\"2017-08-18 11:00:00+00:00\",\"predicted\":124.18617867230817,\"rising_edge\":\"2017-08-18 10:30:00+00:00\"},{\"actual\":112.06651338716757,\"falling_edge\":\"2017-08-18 11:30:00+00:00\",\"predicted\":112.06651338716757,\"rising_edge\":\"2017-08-18 11:00:00+00:00\"},{\"actual\":102.30835719966363,\"falling_edge\":\"2017-08-18 12:00:00+00:00\",\"predicted\":102.30835719966363,\"rising_edge\":\"2017-08-18 11:30:00+00:00\"},{\"actual\":91.67200837097808,\"falling_edge\":\"2017-08-18 12:30:00+00:00\",\"predicted\":91.67200837097808,\"rising_edge\":\"2017-08-18 12:00:00+00:00\"},{\"actual\":82.0828673350127,\"falling_edge\":\"2017-08-18 13:00:00+00:00\",\"predicted\":82.0828673350127,\"rising_edge\":\"2017-08-18 12:30:00+00:00\"},{\"actual\":74.79377140360795,\"falling_edge\":\"2017-08-18 13:30:00+00:00\",\"predicted\":74.79377140360795,\"rising_edge\":\"2017-08-18 13:00:00+00:00\"},{\"actual\":69.52017115707453,\"falling_edge\":\"2017-08-18 14:00:00+00:00\",\"predicted\":69.52017115707453,\"rising_edge\":\"2017-08-18 13:30:00+00:00\"},{\"actual\":60.276768411446426,\"falling_edge\":\"2017-08-18 14:30:00+00:00\",\"predicted\":60.276768411446426,\"rising_edge\":\"2017-08-18 14:00:00+00:00\"},{\"actual\":56.10397585867292,\"falling_edge\":\"2017-08-18 15:00:00+00:00\",\"predicted\":56.10397585867292,\"rising_edge\":\"2017-08-18 14:30:00+00:00\"},{\"actual\":50.03234034986765,\"falling_edge\":\"2017-08-18 15:30:00+00:00\",\"predicted\":50.03234034986765,\"rising_edge\":\"2017-08-18 15:00:00+00:00\"},{\"actual\":46.94412283434011,\"falling_edge\":\"2017-08-18 16:00:00+00:00\",\"predicted\":46.94412283434011,\"rising_edge\":\"2017-08-18 15:30:00+00:00\"},{\"actual\":47.50121253725921,\"falling_edge\":\"2017-08-18 16:30:00+00:00\",\"predicted\":47.50121253725921,\"rising_edge\":\"2017-08-18 16:00:00+00:00\"},{\"actual\":46.688722142824716,\"falling_edge\":\"2017-08-18 17:00:00+00:00\",\"predicted\":46.688722142824716,\"rising_edge\":\"2017-08-18 16:30:00+00:00\"},{\"actual\":46.66371552520828,\"falling_edge\":\"2017-08-18 17:30:00+00:00\",\"predicted\":46.66371552520828,\"rising_edge\":\"2017-08-18 17:00:00+00:00\"},{\"actual\":45.76228894822732,\"falling_edge\":\"2017-08-18 18:00:00+00:00\",\"predicted\":45.76228894822732,\"rising_edge\":\"2017-08-18 17:30:00+00:00\"},{\"actual\":47.1692043567471,\"falling_edge\":\"2017-08-18 18:30:00+00:00\",\"predicted\":47.1692043567471,\"rising_edge\":\"2017-08-18 18:00:00+00:00\"},{\"actual\":48.04023361784429,\"falling_edge\":\"2017-08-18 19:00:00+00:00\",\"predicted\":48.04023361784429,\"rising_edge\":\"2017-08-18 18:30:00+00:00\"},{\"actual\":48.57304793252186,\"falling_edge\":\"2017-08-18 19:30:00+00:00\",\"predicted\":48.57304793252186,\"rising_edge\":\"2017-08-18 19:00:00+00:00\"},{\"actual\":47.63466988832237,\"falling_edge\":\"2017-08-18 20:00:00+00:00\",\"predicted\":47.63466988832237,\"rising_edge\":\"2017-08-18 19:30:00+00:00\"},{\"actual\":48.096135845556624,\"falling_edge\":\"2017-08-18 20:30:00+00:00\",\"predicted\":48.096135845556624,\"rising_edge\":\"2017-08-18 20:00:00+00:00\"},{\"actual\":50.75963986564991,\"falling_edge\":\"2017-08-18 21:00:00+00:00\",\"predicted\":50.75963986564991,\"rising_edge\":\"2017-08-18 20:30:00+00:00\"},{\"actual\":59.511190109681806,\"falling_edge\":\"2017-08-18 21:30:00+00:00\",\"predicted\":59.511190109681806,\"rising_edge\":\"2017-08-18 21:00:00+00:00\"},{\"actual\":62.61266096566612,\"falling_edge\":\"2017-08-18 22:00:00+00:00\",\"predicted\":62.61266096566612,\"rising_edge\":\"2017-08-18 21:30:00+00:00\"},{\"actual\":62.931527323122985,\"falling_edge\":\"2017-08-18 22:30:00+00:00\",\"predicted\":62.931527323122985,\"rising_edge\":\"2017-08-18 22:00:00+00:00\"},{\"actual\":63.838485158161,\"falling_edge\":\"2017-08-18 23:00:00+00:00\",\"predicted\":63.838485158161,\"rising_edge\":\"2017-08-18 22:30:00+00:00\"},{\"actual\":67.21464115949625,\"falling_edge\":\"2017-08-18 23:30:00+00:00\",\"predicted\":67.21464115949625,\"rising_edge\":\"2017-08-18 23:00:00+00:00\"},{\"actual\":72.36901898055109,\"falling_edge\":\"2017-08-19 00:00:00+00:00\",\"predicted\":72.36901898055109,\"rising_edge\":\"2017-08-18 23:30:00+00:00\"},{\"actual\":82.75287263559342,\"falling_edge\":\"2017-08-19 00:30:00+00:00\",\"predicted\":82.75287263559342,\"rising_edge\":\"2017-08-19 00:00:00+00:00\"},{\"actual\":90.88524621777292,\"falling_edge\":\"2017-08-19 01:00:00+00:00\",\"predicted\":90.88524621777292,\"rising_edge\":\"2017-08-19 00:30:00+00:00\"},{\"actual\":90.3075513997582,\"falling_edge\":\"2017-08-19 01:30:00+00:00\",\"predicted\":90.3075513997582,\"rising_edge\":\"2017-08-19 01:00:00+00:00\"},{\"actual\":87.27773636554338,\"falling_edge\":\"2017-08-19 02:00:00+00:00\",\"predicted\":87.27773636554338,\"rising_edge\":\"2017-08-19 01:30:00+00:00\"},{\"actual\":87.44778837015403,\"falling_edge\":\"2017-08-19 02:30:00+00:00\",\"predicted\":87.44778837015403,\"rising_edge\":\"2017-08-19 02:00:00+00:00\"},{\"actual\":91.45841951665396,\"falling_edge\":\"2017-08-19 03:00:00+00:00\",\"predicted\":91.45841951665396,\"rising_edge\":\"2017-08-19 02:30:00+00:00\"},{\"actual\":87.52168277190036,\"falling_edge\":\"2017-08-19 03:30:00+00:00\",\"predicted\":87.52168277190036,\"rising_edge\":\"2017-08-19 03:00:00+00:00\"},{\"actual\":87.07383311469235,\"falling_edge\":\"2017-08-19 04:00:00+00:00\",\"predicted\":87.07383311469235,\"rising_edge\":\"2017-08-19 03:30:00+00:00\"},{\"actual\":94.90723308594981,\"falling_edge\":\"2017-08-19 04:30:00+00:00\",\"predicted\":94.90723308594981,\"rising_edge\":\"2017-08-19 04:00:00+00:00\"},{\"actual\":92.51395874508519,\"falling_edge\":\"2017-08-19 05:00:00+00:00\",\"predicted\":92.51395874508519,\"rising_edge\":\"2017-08-19 04:30:00+00:00\"},{\"actual\":95.22307412805483,\"falling_edge\":\"2017-08-19 05:30:00+00:00\",\"predicted\":95.22307412805483,\"rising_edge\":\"2017-08-19 05:00:00+00:00\"},{\"actual\":90.8606324129045,\"falling_edge\":\"2017-08-19 06:00:00+00:00\",\"predicted\":90.8606324129045,\"rising_edge\":\"2017-08-19 05:30:00+00:00\"},{\"actual\":90.94504213806917,\"falling_edge\":\"2017-08-19 06:30:00+00:00\",\"predicted\":90.94504213806917,\"rising_edge\":\"2017-08-19 06:00:00+00:00\"},{\"actual\":92.75306688135954,\"falling_edge\":\"2017-08-19 07:00:00+00:00\",\"predicted\":92.75306688135954,\"rising_edge\":\"2017-08-19 06:30:00+00:00\"},{\"actual\":94.21000506373996,\"falling_edge\":\"2017-08-19 07:30:00+00:00\",\"predicted\":94.21000506373996,\"rising_edge\":\"2017-08-19 07:00:00+00:00\"},{\"actual\":92.6633544670912,\"falling_edge\":\"2017-08-19 08:00:00+00:00\",\"predicted\":92.6633544670912,\"rising_edge\":\"2017-08-19 07:30:00+00:00\"},{\"actual\":91.21665767383271,\"falling_edge\":\"2017-08-19 08:30:00+00:00\",\"predicted\":91.21665767383271,\"rising_edge\":\"2017-08-19 08:00:00+00:00\"},{\"actual\":83.45885204364761,\"falling_edge\":\"2017-08-19 09:00:00+00:00\",\"predicted\":83.45885204364761,\"rising_edge\":\"2017-08-19 08:30:00+00:00\"},{\"actual\":72.56014356710287,\"falling_edge\":\"2017-08-19 09:30:00+00:00\",\"predicted\":72.56014356710287,\"rising_edge\":\"2017-08-19 09:00:00+00:00\"},{\"actual\":70.84458781825653,\"falling_edge\":\"2017-08-19 10:00:00+00:00\",\"predicted\":70.84458781825653,\"rising_edge\":\"2017-08-19 09:30:00+00:00\"},{\"actual\":67.69511590308991,\"falling_edge\":\"2017-08-19 10:30:00+00:00\",\"predicted\":67.69511590308991,\"rising_edge\":\"2017-08-19 10:00:00+00:00\"},{\"actual\":64.48280047238798,\"falling_edge\":\"2017-08-19 11:00:00+00:00\",\"predicted\":64.48280047238798,\"rising_edge\":\"2017-08-19 10:30:00+00:00\"},{\"actual\":63.8094944554007,\"falling_edge\":\"2017-08-19 11:30:00+00:00\",\"predicted\":63.8094944554007,\"rising_edge\":\"2017-08-19 11:00:00+00:00\"},{\"actual\":61.254723531605016,\"falling_edge\":\"2017-08-19 12:00:00+00:00\",\"predicted\":61.254723531605016,\"rising_edge\":\"2017-08-19 11:30:00+00:00\"},{\"actual\":56.531326397281134,\"falling_edge\":\"2017-08-19 12:30:00+00:00\",\"predicted\":56.531326397281134,\"rising_edge\":\"2017-08-19 12:00:00+00:00\"},{\"actual\":56.19541771009065,\"falling_edge\":\"2017-08-19 13:00:00+00:00\",\"predicted\":56.19541771009065,\"rising_edge\":\"2017-08-19 12:30:00+00:00\"},{\"actual\":54.67493674523082,\"falling_edge\":\"2017-08-19 13:30:00+00:00\",\"predicted\":54.67493674523082,\"rising_edge\":\"2017-08-19 13:00:00+00:00\"},{\"actual\":54.389388575090045,\"falling_edge\":\"2017-08-19 14:00:00+00:00\",\"predicted\":54.389388575090045,\"rising_edge\":\"2017-08-19 13:30:00+00:00\"},{\"actual\":51.246368654330574,\"falling_edge\":\"2017-08-19 14:30:00+00:00\",\"predicted\":51.246368654330574,\"rising_edge\":\"2017-08-19 14:00:00+00:00\"},{\"actual\":50.5631686670717,\"falling_edge\":\"2017-08-19 15:00:00+00:00\",\"predicted\":50.5631686670717,\"rising_edge\":\"2017-08-19 14:30:00+00:00\"},{\"actual\":50.57332957984823,\"falling_edge\":\"2017-08-19 15:30:00+00:00\",\"predicted\":50.57332957984823,\"rising_edge\":\"2017-08-19 15:00:00+00:00\"},{\"actual\":47.89024786277053,\"falling_edge\":\"2017-08-19 16:00:00+00:00\",\"predicted\":47.89024786277053,\"rising_edge\":\"2017-08-19 15:30:00+00:00\"},{\"actual\":48.04091248009773,\"falling_edge\":\"2017-08-19 16:30:00+00:00\",\"predicted\":48.04091248009773,\"rising_edge\":\"2017-08-19 16:00:00+00:00\"},{\"actual\":47.047539653473315,\"falling_edge\":\"2017-08-19 17:00:00+00:00\",\"predicted\":47.047539653473315,\"rising_edge\":\"2017-08-19 16:30:00+00:00\"},{\"actual\":47.59049905518837,\"falling_edge\":\"2017-08-19 17:30:00+00:00\",\"predicted\":47.59049905518837,\"rising_edge\":\"2017-08-19 17:00:00+00:00\"},{\"actual\":47.12958536712267,\"falling_edge\":\"2017-08-19 18:00:00+00:00\",\"predicted\":47.12958536712267,\"rising_edge\":\"2017-08-19 17:30:00+00:00\"},{\"actual\":47.77166379936976,\"falling_edge\":\"2017-08-19 18:30:00+00:00\",\"predicted\":47.77166379936976,\"rising_edge\":\"2017-08-19 18:00:00+00:00\"},{\"actual\":47.06124030851306,\"falling_edge\":\"2017-08-19 19:00:00+00:00\",\"predicted\":47.06124030851306,\"rising_edge\":\"2017-08-19 18:30:00+00:00\"},{\"actual\":46.56817222274265,\"falling_edge\":\"2017-08-19 19:30:00+00:00\",\"predicted\":46.56817222274265,\"rising_edge\":\"2017-08-19 19:00:00+00:00\"},{\"actual\":47.15408859180901,\"falling_edge\":\"2017-08-19 20:00:00+00:00\",\"predicted\":47.15408859180901,\"rising_edge\":\"2017-08-19 19:30:00+00:00\"},{\"actual\":46.715497662105015,\"falling_edge\":\"2017-08-19 20:30:00+00:00\",\"predicted\":46.715497662105015,\"rising_edge\":\"2017-08-19 20:00:00+00:00\"},{\"actual\":47.89464793773185,\"falling_edge\":\"2017-08-19 21:00:00+00:00\",\"predicted\":47.89464793773185,\"rising_edge\":\"2017-08-19 20:30:00+00:00\"},{\"actual\":48.46144971478173,\"falling_edge\":\"2017-08-19 21:30:00+00:00\",\"predicted\":48.46144971478173,\"rising_edge\":\"2017-08-19 21:00:00+00:00\"},{\"actual\":51.587073421447364,\"falling_edge\":\"2017-08-19 22:00:00+00:00\",\"predicted\":51.587073421447364,\"rising_edge\":\"2017-08-19 21:30:00+00:00\"},{\"actual\":53.512029794741785,\"falling_edge\":\"2017-08-19 22:30:00+00:00\",\"predicted\":53.512029794741785,\"rising_edge\":\"2017-08-19 22:00:00+00:00\"},{\"actual\":54.17651932184508,\"falling_edge\":\"2017-08-19 23:00:00+00:00\",\"predicted\":54.17651932184508,\"rising_edge\":\"2017-08-19 22:30:00+00:00\"},{\"actual\":58.47288823827958,\"falling_edge\":\"2017-08-19 23:30:00+00:00\",\"predicted\":58.47288823827958,\"rising_edge\":\"2017-08-19 23:00:00+00:00\"},{\"actual\":62.53703710813934,\"falling_edge\":\"2017-08-20 00:00:00+00:00\",\"predicted\":62.53703710813934,\"rising_edge\":\"2017-08-19 23:30:00+00:00\"},{\"actual\":68.96464972803798,\"falling_edge\":\"2017-08-20 00:30:00+00:00\",\"predicted\":68.96464972803798,\"rising_edge\":\"2017-08-20 00:00:00+00:00\"},{\"actual\":70.79544407016552,\"falling_edge\":\"2017-08-20 01:00:00+00:00\",\"predicted\":70.79544407016552,\"rising_edge\":\"2017-08-20 00:30:00+00:00\"},{\"actual\":71.00251675167247,\"falling_edge\":\"2017-08-20 01:30:00+00:00\",\"predicted\":71.00251675167247,\"rising_edge\":\"2017-08-20 01:00:00+00:00\"},{\"actual\":71.22551018974934,\"falling_edge\":\"2017-08-20 02:00:00+00:00\",\"predicted\":71.22551018974934,\"rising_edge\":\"2017-08-20 01:30:00+00:00\"},{\"actual\":72.05607142428103,\"falling_edge\":\"2017-08-20 02:30:00+00:00\",\"predicted\":72.05607142428103,\"rising_edge\":\"2017-08-20 02:00:00+00:00\"},{\"actual\":72.98552001876897,\"falling_edge\":\"2017-08-20 03:00:00+00:00\",\"predicted\":72.98552001876897,\"rising_edge\":\"2017-08-20 02:30:00+00:00\"},{\"actual\":72.26527701789496,\"falling_edge\":\"2017-08-20 03:30:00+00:00\",\"predicted\":72.26527701789496,\"rising_edge\":\"2017-08-20 03:00:00+00:00\"},{\"actual\":72.94551424889875,\"falling_edge\":\"2017-08-20 04:00:00+00:00\",\"predicted\":72.94551424889875,\"rising_edge\":\"2017-08-20 03:30:00+00:00\"},{\"actual\":77.57633277558344,\"falling_edge\":\"2017-08-20 04:30:00+00:00\",\"predicted\":77.57633277558344,\"rising_edge\":\"2017-08-20 04:00:00+00:00\"},{\"actual\":76.75200982556942,\"falling_edge\":\"2017-08-20 05:00:00+00:00\",\"predicted\":76.75200982556942,\"rising_edge\":\"2017-08-20 04:30:00+00:00\"},{\"actual\":78.21608317453345,\"falling_edge\":\"2017-08-20 05:30:00+00:00\",\"predicted\":78.21608317453345,\"rising_edge\":\"2017-08-20 05:00:00+00:00\"},{\"actual\":78.19550904318189,\"falling_edge\":\"2017-08-20 06:00:00+00:00\",\"predicted\":78.19550904318189,\"rising_edge\":\"2017-08-20 05:30:00+00:00\"},{\"actual\":80.9789292766028,\"falling_edge\":\"2017-08-20 06:30:00+00:00\",\"predicted\":80.9789292766028,\"rising_edge\":\"2017-08-20 06:00:00+00:00\"},{\"actual\":82.51862236280186,\"falling_edge\":\"2017-08-20 07:00:00+00:00\",\"predicted\":82.51862236280186,\"rising_edge\":\"2017-08-20 06:30:00+00:00\"},{\"actual\":84.48423504387804,\"falling_edge\":\"2017-08-20 07:30:00+00:00\",\"predicted\":84.48423504387804,\"rising_edge\":\"2017-08-20 07:00:00+00:00\"},{\"actual\":79.55365935246779,\"falling_edge\":\"2017-08-20 08:00:00+00:00\",\"predicted\":79.55365935246779,\"rising_edge\":\"2017-08-20 07:30:00+00:00\"},{\"actual\":76.90817039103558,\"falling_edge\":\"2017-08-20 08:30:00+00:00\",\"predicted\":76.90817039103558,\"rising_edge\":\"2017-08-20 08:00:00+00:00\"},{\"actual\":72.796089295964,\"falling_edge\":\"2017-08-20 09:00:00+00:00\",\"predicted\":72.796089295964,\"rising_edge\":\"2017-08-20 08:30:00+00:00\"},{\"actual\":65.99219528269568,\"falling_edge\":\"2017-08-20 09:30:00+00:00\",\"predicted\":65.99219528269568,\"rising_edge\":\"2017-08-20 09:00:00+00:00\"},{\"actual\":64.050351268755,\"falling_edge\":\"2017-08-20 10:00:00+00:00\",\"predicted\":64.050351268755,\"rising_edge\":\"2017-08-20 09:30:00+00:00\"},{\"actual\":60.55995579952238,\"falling_edge\":\"2017-08-20 10:30:00+00:00\",\"predicted\":60.55995579952238,\"rising_edge\":\"2017-08-20 10:00:00+00:00\"},{\"actual\":60.44839482985264,\"falling_edge\":\"2017-08-20 11:00:00+00:00\",\"predicted\":60.44839482985264,\"rising_edge\":\"2017-08-20 10:30:00+00:00\"},{\"actual\":59.64729322719295,\"falling_edge\":\"2017-08-20 11:30:00+00:00\",\"predicted\":59.64729322719295,\"rising_edge\":\"2017-08-20 11:00:00+00:00\"},{\"actual\":59.764840597022506,\"falling_edge\":\"2017-08-20 12:00:00+00:00\",\"predicted\":59.764840597022506,\"rising_edge\":\"2017-08-20 11:30:00+00:00\"},{\"actual\":55.72113578867496,\"falling_edge\":\"2017-08-20 12:30:00+00:00\",\"predicted\":55.72113578867496,\"rising_edge\":\"2017-08-20 12:00:00+00:00\"},{\"actual\":54.18535731249013,\"falling_edge\":\"2017-08-20 13:00:00+00:00\",\"predicted\":54.18535731249013,\"rising_edge\":\"2017-08-20 12:30:00+00:00\"},{\"actual\":52.93682958984641,\"falling_edge\":\"2017-08-20 13:30:00+00:00\",\"predicted\":52.93682958984641,\"rising_edge\":\"2017-08-20 13:00:00+00:00\"},{\"actual\":50.54702143597513,\"falling_edge\":\"2017-08-20 14:00:00+00:00\",\"predicted\":50.54702143597513,\"rising_edge\":\"2017-08-20 13:30:00+00:00\"},{\"actual\":51.75061830652007,\"falling_edge\":\"2017-08-20 14:30:00+00:00\",\"predicted\":51.75061830652007,\"rising_edge\":\"2017-08-20 14:00:00+00:00\"},{\"actual\":49.7954881675818,\"falling_edge\":\"2017-08-20 15:00:00+00:00\",\"predicted\":49.7954881675818,\"rising_edge\":\"2017-08-20 14:30:00+00:00\"},{\"actual\":49.7698133410026,\"falling_edge\":\"2017-08-20 15:30:00+00:00\",\"predicted\":49.7698133410026,\"rising_edge\":\"2017-08-20 15:00:00+00:00\"},{\"actual\":49.02673898960009,\"falling_edge\":\"2017-08-20 16:00:00+00:00\",\"predicted\":49.02673898960009,\"rising_edge\":\"2017-08-20 15:30:00+00:00\"},{\"actual\":50.08649554600898,\"falling_edge\":\"2017-08-20 16:30:00+00:00\",\"predicted\":50.08649554600898,\"rising_edge\":\"2017-08-20 16:00:00+00:00\"},{\"actual\":48.43425466169822,\"falling_edge\":\"2017-08-20 17:00:00+00:00\",\"predicted\":48.43425466169822,\"rising_edge\":\"2017-08-20 16:30:00+00:00\"},{\"actual\":47.6297940467916,\"falling_edge\":\"2017-08-20 17:30:00+00:00\",\"predicted\":47.6297940467916,\"rising_edge\":\"2017-08-20 17:00:00+00:00\"},{\"actual\":48.79709696810554,\"falling_edge\":\"2017-08-20 18:00:00+00:00\",\"predicted\":48.79709696810554,\"rising_edge\":\"2017-08-20 17:30:00+00:00\"},{\"actual\":47.714017463160786,\"falling_edge\":\"2017-08-20 18:30:00+00:00\",\"predicted\":47.714017463160786,\"rising_edge\":\"2017-08-20 18:00:00+00:00\"},{\"actual\":48.29561902471489,\"falling_edge\":\"2017-08-20 19:00:00+00:00\",\"predicted\":48.29561902471489,\"rising_edge\":\"2017-08-20 18:30:00+00:00\"},{\"actual\":47.49584316859576,\"falling_edge\":\"2017-08-20 19:30:00+00:00\",\"predicted\":47.49584316859576,\"rising_edge\":\"2017-08-20 19:00:00+00:00\"},{\"actual\":48.3854711651553,\"falling_edge\":\"2017-08-20 20:00:00+00:00\",\"predicted\":48.3854711651553,\"rising_edge\":\"2017-08-20 19:30:00+00:00\"},{\"actual\":48.97339264059526,\"falling_edge\":\"2017-08-20 20:30:00+00:00\",\"predicted\":48.97339264059526,\"rising_edge\":\"2017-08-20 20:00:00+00:00\"},{\"actual\":54.075303363562774,\"falling_edge\":\"2017-08-20 21:00:00+00:00\",\"predicted\":54.075303363562774,\"rising_edge\":\"2017-08-20 20:30:00+00:00\"},{\"actual\":71.7178730746807,\"falling_edge\":\"2017-08-20 21:30:00+00:00\",\"predicted\":71.7178730746807,\"rising_edge\":\"2017-08-20 21:00:00+00:00\"},{\"actual\":134.26089608536603,\"falling_edge\":\"2017-08-20 22:00:00+00:00\",\"predicted\":134.26089608536603,\"rising_edge\":\"2017-08-20 21:30:00+00:00\"},{\"actual\":119.9451715695183,\"falling_edge\":\"2017-08-20 22:30:00+00:00\",\"predicted\":119.9451715695183,\"rising_edge\":\"2017-08-20 22:00:00+00:00\"},{\"actual\":141.809652429279,\"falling_edge\":\"2017-08-20 23:00:00+00:00\",\"predicted\":141.809652429279,\"rising_edge\":\"2017-08-20 22:30:00+00:00\"},{\"actual\":178.73070737172566,\"falling_edge\":\"2017-08-20 23:30:00+00:00\",\"predicted\":178.73070737172566,\"rising_edge\":\"2017-08-20 23:00:00+00:00\"},{\"actual\":219.71685287013358,\"falling_edge\":\"2017-08-21 00:00:00+00:00\",\"predicted\":219.71685287013358,\"rising_edge\":\"2017-08-20 23:30:00+00:00\"},{\"actual\":228.96396334560066,\"falling_edge\":\"2017-08-21 00:30:00+00:00\",\"predicted\":228.96396334560066,\"rising_edge\":\"2017-08-21 00:00:00+00:00\"},{\"actual\":244.79858900110526,\"falling_edge\":\"2017-08-21 01:00:00+00:00\",\"predicted\":244.79858900110526,\"rising_edge\":\"2017-08-21 00:30:00+00:00\"},{\"actual\":254.5578773365205,\"falling_edge\":\"2017-08-21 01:30:00+00:00\",\"predicted\":254.5578773365205,\"rising_edge\":\"2017-08-21 01:00:00+00:00\"},{\"actual\":256.6510098568977,\"falling_edge\":\"2017-08-21 02:00:00+00:00\",\"predicted\":256.6510098568977,\"rising_edge\":\"2017-08-21 01:30:00+00:00\"},{\"actual\":241.26877275223165,\"falling_edge\":\"2017-08-21 02:30:00+00:00\",\"predicted\":241.26877275223165,\"rising_edge\":\"2017-08-21 02:00:00+00:00\"},{\"actual\":239.5095279328234,\"falling_edge\":\"2017-08-21 03:00:00+00:00\",\"predicted\":239.5095279328234,\"rising_edge\":\"2017-08-21 02:30:00+00:00\"},{\"actual\":238.2409003583941,\"falling_edge\":\"2017-08-21 03:30:00+00:00\",\"predicted\":238.2409003583941,\"rising_edge\":\"2017-08-21 03:00:00+00:00\"},{\"actual\":223.82572997930635,\"falling_edge\":\"2017-08-21 04:00:00+00:00\",\"predicted\":223.82572997930635,\"rising_edge\":\"2017-08-21 03:30:00+00:00\"},{\"actual\":232.75336278379848,\"falling_edge\":\"2017-08-21 04:30:00+00:00\",\"predicted\":232.75336278379848,\"rising_edge\":\"2017-08-21 04:00:00+00:00\"},{\"actual\":233.0060838862599,\"falling_edge\":\"2017-08-21 05:00:00+00:00\",\"predicted\":233.0060838862599,\"rising_edge\":\"2017-08-21 04:30:00+00:00\"},{\"actual\":226.57152628355013,\"falling_edge\":\"2017-08-21 05:30:00+00:00\",\"predicted\":226.57152628355013,\"rising_edge\":\"2017-08-21 05:00:00+00:00\"},{\"actual\":234.51704966286667,\"falling_edge\":\"2017-08-21 06:00:00+00:00\",\"predicted\":234.51704966286667,\"rising_edge\":\"2017-08-21 05:30:00+00:00\"},{\"actual\":238.16318121958432,\"falling_edge\":\"2017-08-21 06:30:00+00:00\",\"predicted\":238.16318121958432,\"rising_edge\":\"2017-08-21 06:00:00+00:00\"},{\"actual\":231.64606901385858,\"falling_edge\":\"2017-08-21 07:00:00+00:00\",\"predicted\":231.64606901385858,\"rising_edge\":\"2017-08-21 06:30:00+00:00\"},{\"actual\":230.4465340071954,\"falling_edge\":\"2017-08-21 07:30:00+00:00\",\"predicted\":230.4465340071954,\"rising_edge\":\"2017-08-21 07:00:00+00:00\"},{\"actual\":225.35883729366222,\"falling_edge\":\"2017-08-21 08:00:00+00:00\",\"predicted\":225.35883729366222,\"rising_edge\":\"2017-08-21 07:30:00+00:00\"},{\"actual\":219.89203996695122,\"falling_edge\":\"2017-08-21 08:30:00+00:00\",\"predicted\":219.89203996695122,\"rising_edge\":\"2017-08-21 08:00:00+00:00\"},{\"actual\":206.0442627118794,\"falling_edge\":\"2017-08-21 09:00:00+00:00\",\"predicted\":206.0442627118794,\"rising_edge\":\"2017-08-21 08:30:00+00:00\"},{\"actual\":176.27494091338613,\"falling_edge\":\"2017-08-21 09:30:00+00:00\",\"predicted\":176.27494091338613,\"rising_edge\":\"2017-08-21 09:00:00+00:00\"},{\"actual\":162.56717673919715,\"falling_edge\":\"2017-08-21 10:00:00+00:00\",\"predicted\":162.56717673919715,\"rising_edge\":\"2017-08-21 09:30:00+00:00\"},{\"actual\":139.74615650431753,\"falling_edge\":\"2017-08-21 10:30:00+00:00\",\"predicted\":139.74615650431753,\"rising_edge\":\"2017-08-21 10:00:00+00:00\"},{\"actual\":137.67035678974358,\"falling_edge\":\"2017-08-21 11:00:00+00:00\",\"predicted\":137.67035678974358,\"rising_edge\":\"2017-08-21 10:30:00+00:00\"},{\"actual\":129.23642921201034,\"falling_edge\":\"2017-08-21 11:30:00+00:00\",\"predicted\":129.23642921201034,\"rising_edge\":\"2017-08-21 11:00:00+00:00\"},{\"actual\":116.43282621116552,\"falling_edge\":\"2017-08-21 12:00:00+00:00\",\"predicted\":116.43282621116552,\"rising_edge\":\"2017-08-21 11:30:00+00:00\"},{\"actual\":105.57611635022926,\"falling_edge\":\"2017-08-21 12:30:00+00:00\",\"predicted\":105.57611635022926,\"rising_edge\":\"2017-08-21 12:00:00+00:00\"},{\"actual\":97.66996373456249,\"falling_edge\":\"2017-08-21 13:00:00+00:00\",\"predicted\":97.66996373456249,\"rising_edge\":\"2017-08-21 12:30:00+00:00\"},{\"actual\":88.99308774316597,\"falling_edge\":\"2017-08-21 13:30:00+00:00\",\"predicted\":88.99308774316597,\"rising_edge\":\"2017-08-21 13:00:00+00:00\"},{\"actual\":76.73977245289467,\"falling_edge\":\"2017-08-21 14:00:00+00:00\",\"predicted\":76.73977245289467,\"rising_edge\":\"2017-08-21 13:30:00+00:00\"},{\"actual\":66.39719287853224,\"falling_edge\":\"2017-08-21 14:30:00+00:00\",\"predicted\":66.39719287853224,\"rising_edge\":\"2017-08-21 14:00:00+00:00\"},{\"actual\":59.2419571470056,\"falling_edge\":\"2017-08-21 15:00:00+00:00\",\"predicted\":59.2419571470056,\"rising_edge\":\"2017-08-21 14:30:00+00:00\"},{\"actual\":53.568314276086866,\"falling_edge\":\"2017-08-21 15:30:00+00:00\",\"predicted\":53.568314276086866,\"rising_edge\":\"2017-08-21 15:00:00+00:00\"},{\"actual\":48.65769105594772,\"falling_edge\":\"2017-08-21 16:00:00+00:00\",\"predicted\":48.65769105594772,\"rising_edge\":\"2017-08-21 15:30:00+00:00\"},{\"actual\":48.1610245342573,\"falling_edge\":\"2017-08-21 16:30:00+00:00\",\"predicted\":48.1610245342573,\"rising_edge\":\"2017-08-21 16:00:00+00:00\"},{\"actual\":48.26883859826425,\"falling_edge\":\"2017-08-21 17:00:00+00:00\",\"predicted\":48.26883859826425,\"rising_edge\":\"2017-08-21 16:30:00+00:00\"},{\"actual\":48.06817665051483,\"falling_edge\":\"2017-08-21 17:30:00+00:00\",\"predicted\":48.06817665051483,\"rising_edge\":\"2017-08-21 17:00:00+00:00\"},{\"actual\":46.755633066098234,\"falling_edge\":\"2017-08-21 18:00:00+00:00\",\"predicted\":46.755633066098234,\"rising_edge\":\"2017-08-21 17:30:00+00:00\"},{\"actual\":46.60752204487037,\"falling_edge\":\"2017-08-21 18:30:00+00:00\",\"predicted\":46.60752204487037,\"rising_edge\":\"2017-08-21 18:00:00+00:00\"},{\"actual\":46.27697928967649,\"falling_edge\":\"2017-08-21 19:00:00+00:00\",\"predicted\":46.27697928967649,\"rising_edge\":\"2017-08-21 18:30:00+00:00\"},{\"actual\":46.326282369074846,\"falling_edge\":\"2017-08-21 19:30:00+00:00\",\"predicted\":46.326282369074846,\"rising_edge\":\"2017-08-21 19:00:00+00:00\"},{\"actual\":45.61875629265384,\"falling_edge\":\"2017-08-21 20:00:00+00:00\",\"predicted\":45.61875629265384,\"rising_edge\":\"2017-08-21 19:30:00+00:00\"},{\"actual\":48.14890695285554,\"falling_edge\":\"2017-08-21 20:30:00+00:00\",\"predicted\":48.14890695285554,\"rising_edge\":\"2017-08-21 20:00:00+00:00\"},{\"actual\":52.8670679183288,\"falling_edge\":\"2017-08-21 21:00:00+00:00\",\"predicted\":52.8670679183288,\"rising_edge\":\"2017-08-21 20:30:00+00:00\"},{\"actual\":69.45051330263318,\"falling_edge\":\"2017-08-21 21:30:00+00:00\",\"predicted\":69.45051330263318,\"rising_edge\":\"2017-08-21 21:00:00+00:00\"},{\"actual\":116.45412880588032,\"falling_edge\":\"2017-08-21 22:00:00+00:00\",\"predicted\":116.45412880588032,\"rising_edge\":\"2017-08-21 21:30:00+00:00\"},{\"actual\":119.65359720856654,\"falling_edge\":\"2017-08-21 22:30:00+00:00\",\"predicted\":119.65359720856654,\"rising_edge\":\"2017-08-21 22:00:00+00:00\"},{\"actual\":143.95719814118948,\"falling_edge\":\"2017-08-21 23:00:00+00:00\",\"predicted\":143.95719814118948,\"rising_edge\":\"2017-08-21 22:30:00+00:00\"},{\"actual\":179.5599246175226,\"falling_edge\":\"2017-08-21 23:30:00+00:00\",\"predicted\":179.5599246175226,\"rising_edge\":\"2017-08-21 23:00:00+00:00\"},{\"actual\":217.26244219670042,\"falling_edge\":\"2017-08-22 00:00:00+00:00\",\"predicted\":217.26244219670042,\"rising_edge\":\"2017-08-21 23:30:00+00:00\"},{\"actual\":234.71326422888924,\"falling_edge\":\"2017-08-22 00:30:00+00:00\",\"predicted\":234.71326422888924,\"rising_edge\":\"2017-08-22 00:00:00+00:00\"},{\"actual\":236.52758982423487,\"falling_edge\":\"2017-08-22 01:00:00+00:00\",\"predicted\":236.52758982423487,\"rising_edge\":\"2017-08-22 00:30:00+00:00\"},{\"actual\":240.23516431056422,\"falling_edge\":\"2017-08-22 01:30:00+00:00\",\"predicted\":240.23516431056422,\"rising_edge\":\"2017-08-22 01:00:00+00:00\"},{\"actual\":245.7677350245932,\"falling_edge\":\"2017-08-22 02:00:00+00:00\",\"predicted\":245.7677350245932,\"rising_edge\":\"2017-08-22 01:30:00+00:00\"},{\"actual\":240.0269266037571,\"falling_edge\":\"2017-08-22 02:30:00+00:00\",\"predicted\":240.0269266037571,\"rising_edge\":\"2017-08-22 02:00:00+00:00\"},{\"actual\":230.006701485951,\"falling_edge\":\"2017-08-22 03:00:00+00:00\",\"predicted\":230.006701485951,\"rising_edge\":\"2017-08-22 02:30:00+00:00\"},{\"actual\":219.93270811432035,\"falling_edge\":\"2017-08-22 03:30:00+00:00\",\"predicted\":219.93270811432035,\"rising_edge\":\"2017-08-22 03:00:00+00:00\"},{\"actual\":217.94415454684338,\"falling_edge\":\"2017-08-22 04:00:00+00:00\",\"predicted\":217.94415454684338,\"rising_edge\":\"2017-08-22 03:30:00+00:00\"},{\"actual\":225.4772386549695,\"falling_edge\":\"2017-08-22 04:30:00+00:00\",\"predicted\":225.4772386549695,\"rising_edge\":\"2017-08-22 04:00:00+00:00\"},{\"actual\":222.5536517143126,\"falling_edge\":\"2017-08-22 05:00:00+00:00\",\"predicted\":222.5536517143126,\"rising_edge\":\"2017-08-22 04:30:00+00:00\"},{\"actual\":225.13765346588494,\"falling_edge\":\"2017-08-22 05:30:00+00:00\",\"predicted\":225.13765346588494,\"rising_edge\":\"2017-08-22 05:00:00+00:00\"},{\"actual\":237.6528839990453,\"falling_edge\":\"2017-08-22 06:00:00+00:00\",\"predicted\":237.6528839990453,\"rising_edge\":\"2017-08-22 05:30:00+00:00\"},{\"actual\":240.82643778841526,\"falling_edge\":\"2017-08-22 06:30:00+00:00\",\"predicted\":240.82643778841526,\"rising_edge\":\"2017-08-22 06:00:00+00:00\"},{\"actual\":230.510155207148,\"falling_edge\":\"2017-08-22 07:00:00+00:00\",\"predicted\":230.510155207148,\"rising_edge\":\"2017-08-22 06:30:00+00:00\"},{\"actual\":225.17277011247012,\"falling_edge\":\"2017-08-22 07:30:00+00:00\",\"predicted\":225.17277011247012,\"rising_edge\":\"2017-08-22 07:00:00+00:00\"},{\"actual\":219.6806345722554,\"falling_edge\":\"2017-08-22 08:00:00+00:00\",\"predicted\":219.6806345722554,\"rising_edge\":\"2017-08-22 07:30:00+00:00\"},{\"actual\":222.9131413978648,\"falling_edge\":\"2017-08-22 08:30:00+00:00\",\"predicted\":222.9131413978648,\"rising_edge\":\"2017-08-22 08:00:00+00:00\"},{\"actual\":216.5149470546197,\"falling_edge\":\"2017-08-22 09:00:00+00:00\",\"predicted\":216.5149470546197,\"rising_edge\":\"2017-08-22 08:30:00+00:00\"},{\"actual\":187.6260293944933,\"falling_edge\":\"2017-08-22 09:30:00+00:00\",\"predicted\":187.6260293944933,\"rising_edge\":\"2017-08-22 09:00:00+00:00\"},{\"actual\":170.84358331865468,\"falling_edge\":\"2017-08-22 10:00:00+00:00\",\"predicted\":170.84358331865468,\"rising_edge\":\"2017-08-22 09:30:00+00:00\"},{\"actual\":150.02515403513206,\"falling_edge\":\"2017-08-22 10:30:00+00:00\",\"predicted\":150.02515403513206,\"rising_edge\":\"2017-08-22 10:00:00+00:00\"},{\"actual\":149.08986616281965,\"falling_edge\":\"2017-08-22 11:00:00+00:00\",\"predicted\":149.08986616281965,\"rising_edge\":\"2017-08-22 10:30:00+00:00\"},{\"actual\":140.7499143892708,\"falling_edge\":\"2017-08-22 11:30:00+00:00\",\"predicted\":140.7499143892708,\"rising_edge\":\"2017-08-22 11:00:00+00:00\"},{\"actual\":129.94761449808527,\"falling_edge\":\"2017-08-22 12:00:00+00:00\",\"predicted\":129.94761449808527,\"rising_edge\":\"2017-08-22 11:30:00+00:00\"},{\"actual\":118.60856739514368,\"falling_edge\":\"2017-08-22 12:30:00+00:00\",\"predicted\":118.60856739514368,\"rising_edge\":\"2017-08-22 12:00:00+00:00\"},{\"actual\":106.41044099377481,\"falling_edge\":\"2017-08-22 13:00:00+00:00\",\"predicted\":106.41044099377481,\"rising_edge\":\"2017-08-22 12:30:00+00:00\"},{\"actual\":95.92016171637175,\"falling_edge\":\"2017-08-22 13:30:00+00:00\",\"predicted\":95.92016171637175,\"rising_edge\":\"2017-08-22 13:00:00+00:00\"},{\"actual\":80.637896392412,\"falling_edge\":\"2017-08-22 14:00:00+00:00\",\"predicted\":80.637896392412,\"rising_edge\":\"2017-08-22 13:30:00+00:00\"},{\"actual\":68.54996904270143,\"falling_edge\":\"2017-08-22 14:30:00+00:00\",\"predicted\":68.54996904270143,\"rising_edge\":\"2017-08-22 14:00:00+00:00\"},{\"actual\":60.46595074389639,\"falling_edge\":\"2017-08-22 15:00:00+00:00\",\"predicted\":60.46595074389639,\"rising_edge\":\"2017-08-22 14:30:00+00:00\"},{\"actual\":55.958068864021854,\"falling_edge\":\"2017-08-22 15:30:00+00:00\",\"predicted\":55.958068864021854,\"rising_edge\":\"2017-08-22 15:00:00+00:00\"},{\"actual\":53.31367054732095,\"falling_edge\":\"2017-08-22 16:00:00+00:00\",\"predicted\":53.31367054732095,\"rising_edge\":\"2017-08-22 15:30:00+00:00\"},{\"actual\":55.89346082272261,\"falling_edge\":\"2017-08-22 16:30:00+00:00\",\"predicted\":55.89346082272261,\"rising_edge\":\"2017-08-22 16:00:00+00:00\"},{\"actual\":53.01433426677705,\"falling_edge\":\"2017-08-22 17:00:00+00:00\",\"predicted\":53.01433426677705,\"rising_edge\":\"2017-08-22 16:30:00+00:00\"},{\"actual\":51.14660084297665,\"falling_edge\":\"2017-08-22 17:30:00+00:00\",\"predicted\":51.14660084297665,\"rising_edge\":\"2017-08-22 17:00:00+00:00\"},{\"actual\":50.35380118505304,\"falling_edge\":\"2017-08-22 18:00:00+00:00\",\"predicted\":50.35380118505304,\"rising_edge\":\"2017-08-22 17:30:00+00:00\"},{\"actual\":47.67085370667175,\"falling_edge\":\"2017-08-22 18:30:00+00:00\",\"predicted\":47.67085370667175,\"rising_edge\":\"2017-08-22 18:00:00+00:00\"},{\"actual\":46.96739548648855,\"falling_edge\":\"2017-08-22 19:00:00+00:00\",\"predicted\":46.96739548648855,\"rising_edge\":\"2017-08-22 18:30:00+00:00\"},{\"actual\":48.341082223779274,\"falling_edge\":\"2017-08-22 19:30:00+00:00\",\"predicted\":48.341082223779274,\"rising_edge\":\"2017-08-22 19:00:00+00:00\"},{\"actual\":48.077896445967426,\"falling_edge\":\"2017-08-22 20:00:00+00:00\",\"predicted\":48.077896445967426,\"rising_edge\":\"2017-08-22 19:30:00+00:00\"},{\"actual\":49.38074559067251,\"falling_edge\":\"2017-08-22 20:30:00+00:00\",\"predicted\":49.38074559067251,\"rising_edge\":\"2017-08-22 20:00:00+00:00\"},{\"actual\":55.01803099605362,\"falling_edge\":\"2017-08-22 21:00:00+00:00\",\"predicted\":55.01803099605362,\"rising_edge\":\"2017-08-22 20:30:00+00:00\"},{\"actual\":72.28809933680401,\"falling_edge\":\"2017-08-22 21:30:00+00:00\",\"predicted\":72.28809933680401,\"rising_edge\":\"2017-08-22 21:00:00+00:00\"},{\"actual\":112.54407452274333,\"falling_edge\":\"2017-08-22 22:00:00+00:00\",\"predicted\":112.54407452274333,\"rising_edge\":\"2017-08-22 21:30:00+00:00\"},{\"actual\":109.75511310084832,\"falling_edge\":\"2017-08-22 22:30:00+00:00\",\"predicted\":109.75511310084832,\"rising_edge\":\"2017-08-22 22:00:00+00:00\"},{\"actual\":136.23496922781177,\"falling_edge\":\"2017-08-22 23:00:00+00:00\",\"predicted\":136.23496922781177,\"rising_edge\":\"2017-08-22 22:30:00+00:00\"},{\"actual\":187.90053576245677,\"falling_edge\":\"2017-08-22 23:30:00+00:00\",\"predicted\":187.90053576245677,\"rising_edge\":\"2017-08-22 23:00:00+00:00\"},{\"actual\":230.58856101899767,\"falling_edge\":\"2017-08-23 00:00:00+00:00\",\"predicted\":230.58856101899767,\"rising_edge\":\"2017-08-22 23:30:00+00:00\"},{\"actual\":233.33121371140868,\"falling_edge\":\"2017-08-23 00:30:00+00:00\",\"predicted\":233.33121371140868,\"rising_edge\":\"2017-08-23 00:00:00+00:00\"},{\"actual\":246.24749142278216,\"falling_edge\":\"2017-08-23 01:00:00+00:00\",\"predicted\":246.24749142278216,\"rising_edge\":\"2017-08-23 00:30:00+00:00\"},{\"actual\":246.49442248548482,\"falling_edge\":\"2017-08-23 01:30:00+00:00\",\"predicted\":246.49442248548482,\"rising_edge\":\"2017-08-23 01:00:00+00:00\"},{\"actual\":250.43707685061491,\"falling_edge\":\"2017-08-23 02:00:00+00:00\",\"predicted\":250.43707685061491,\"rising_edge\":\"2017-08-23 01:30:00+00:00\"},{\"actual\":243.7916765655197,\"falling_edge\":\"2017-08-23 02:30:00+00:00\",\"predicted\":243.7916765655197,\"rising_edge\":\"2017-08-23 02:00:00+00:00\"},{\"actual\":248.51518358870862,\"falling_edge\":\"2017-08-23 03:00:00+00:00\",\"predicted\":248.51518358870862,\"rising_edge\":\"2017-08-23 02:30:00+00:00\"},{\"actual\":224.92904103600875,\"falling_edge\":\"2017-08-23 03:30:00+00:00\",\"predicted\":224.92904103600875,\"rising_edge\":\"2017-08-23 03:00:00+00:00\"},{\"actual\":221.52095872701273,\"falling_edge\":\"2017-08-23 04:00:00+00:00\",\"predicted\":221.52095872701273,\"rising_edge\":\"2017-08-23 03:30:00+00:00\"},{\"actual\":226.33421570365627,\"falling_edge\":\"2017-08-23 04:30:00+00:00\",\"predicted\":226.33421570365627,\"rising_edge\":\"2017-08-23 04:00:00+00:00\"},{\"actual\":232.57422024807266,\"falling_edge\":\"2017-08-23 05:00:00+00:00\",\"predicted\":232.57422024807266,\"rising_edge\":\"2017-08-23 04:30:00+00:00\"},{\"actual\":228.97337555732042,\"falling_edge\":\"2017-08-23 05:30:00+00:00\",\"predicted\":228.97337555732042,\"rising_edge\":\"2017-08-23 05:00:00+00:00\"},{\"actual\":241.74256160328272,\"falling_edge\":\"2017-08-23 06:00:00+00:00\",\"predicted\":241.74256160328272,\"rising_edge\":\"2017-08-23 05:30:00+00:00\"},{\"actual\":250.27778048484197,\"falling_edge\":\"2017-08-23 06:30:00+00:00\",\"predicted\":250.27778048484197,\"rising_edge\":\"2017-08-23 06:00:00+00:00\"},{\"actual\":243.3286530620398,\"falling_edge\":\"2017-08-23 07:00:00+00:00\",\"predicted\":243.3286530620398,\"rising_edge\":\"2017-08-23 06:30:00+00:00\"},{\"actual\":241.90788061364043,\"falling_edge\":\"2017-08-23 07:30:00+00:00\",\"predicted\":241.90788061364043,\"rising_edge\":\"2017-08-23 07:00:00+00:00\"},{\"actual\":241.92209995779245,\"falling_edge\":\"2017-08-23 08:00:00+00:00\",\"predicted\":241.92209995779245,\"rising_edge\":\"2017-08-23 07:30:00+00:00\"},{\"actual\":242.076717636515,\"falling_edge\":\"2017-08-23 08:30:00+00:00\",\"predicted\":242.076717636515,\"rising_edge\":\"2017-08-23 08:00:00+00:00\"},{\"actual\":214.72651051792255,\"falling_edge\":\"2017-08-23 09:00:00+00:00\",\"predicted\":214.72651051792255,\"rising_edge\":\"2017-08-23 08:30:00+00:00\"},{\"actual\":176.89030390630944,\"falling_edge\":\"2017-08-23 09:30:00+00:00\",\"predicted\":176.89030390630944,\"rising_edge\":\"2017-08-23 09:00:00+00:00\"},{\"actual\":154.2489469037693,\"falling_edge\":\"2017-08-23 10:00:00+00:00\",\"predicted\":154.2489469037693,\"rising_edge\":\"2017-08-23 09:30:00+00:00\"},{\"actual\":125.55204825992028,\"falling_edge\":\"2017-08-23 10:30:00+00:00\",\"predicted\":125.55204825992028,\"rising_edge\":\"2017-08-23 10:00:00+00:00\"},{\"actual\":119.88235703947318,\"falling_edge\":\"2017-08-23 11:00:00+00:00\",\"predicted\":119.88235703947318,\"rising_edge\":\"2017-08-23 10:30:00+00:00\"},{\"actual\":111.78757669800585,\"falling_edge\":\"2017-08-23 11:30:00+00:00\",\"predicted\":111.78757669800585,\"rising_edge\":\"2017-08-23 11:00:00+00:00\"},{\"actual\":106.6278311528915,\"falling_edge\":\"2017-08-23 12:00:00+00:00\",\"predicted\":106.6278311528915,\"rising_edge\":\"2017-08-23 11:30:00+00:00\"},{\"actual\":101.20433589374395,\"falling_edge\":\"2017-08-23 12:30:00+00:00\",\"predicted\":101.20433589374395,\"rising_edge\":\"2017-08-23 12:00:00+00:00\"},{\"actual\":93.01543263512967,\"falling_edge\":\"2017-08-23 13:00:00+00:00\",\"predicted\":93.01543263512967,\"rising_edge\":\"2017-08-23 12:30:00+00:00\"},{\"actual\":79.49431867609884,\"falling_edge\":\"2017-08-23 13:30:00+00:00\",\"predicted\":79.49431867609884,\"rising_edge\":\"2017-08-23 13:00:00+00:00\"},{\"actual\":69.89088064122589,\"falling_edge\":\"2017-08-23 14:00:00+00:00\",\"predicted\":69.89088064122589,\"rising_edge\":\"2017-08-23 13:30:00+00:00\"},{\"actual\":62.21634276626863,\"falling_edge\":\"2017-08-23 14:30:00+00:00\",\"predicted\":62.21634276626863,\"rising_edge\":\"2017-08-23 14:00:00+00:00\"},{\"actual\":55.9448071289387,\"falling_edge\":\"2017-08-23 15:00:00+00:00\",\"predicted\":55.9448071289387,\"rising_edge\":\"2017-08-23 14:30:00+00:00\"},{\"actual\":51.726747984905096,\"falling_edge\":\"2017-08-23 15:30:00+00:00\",\"predicted\":51.726747984905096,\"rising_edge\":\"2017-08-23 15:00:00+00:00\"},{\"actual\":49.64956469603807,\"falling_edge\":\"2017-08-23 16:00:00+00:00\",\"predicted\":49.64956469603807,\"rising_edge\":\"2017-08-23 15:30:00+00:00\"},{\"actual\":48.05754588878204,\"falling_edge\":\"2017-08-23 16:30:00+00:00\",\"predicted\":48.05754588878204,\"rising_edge\":\"2017-08-23 16:00:00+00:00\"},{\"actual\":47.82390627401296,\"falling_edge\":\"2017-08-23 17:00:00+00:00\",\"predicted\":47.82390627401296,\"rising_edge\":\"2017-08-23 16:30:00+00:00\"},{\"actual\":48.36252535502485,\"falling_edge\":\"2017-08-23 17:30:00+00:00\",\"predicted\":48.36252535502485,\"rising_edge\":\"2017-08-23 17:00:00+00:00\"},{\"actual\":47.96248496064657,\"falling_edge\":\"2017-08-23 18:00:00+00:00\",\"predicted\":47.96248496064657,\"rising_edge\":\"2017-08-23 17:30:00+00:00\"},{\"actual\":47.22651265318574,\"falling_edge\":\"2017-08-23 18:30:00+00:00\",\"predicted\":47.22651265318574,\"rising_edge\":\"2017-08-23 18:00:00+00:00\"},{\"actual\":46.77555845677217,\"falling_edge\":\"2017-08-23 19:00:00+00:00\",\"predicted\":46.77555845677217,\"rising_edge\":\"2017-08-23 18:30:00+00:00\"},{\"actual\":46.179518257957156,\"falling_edge\":\"2017-08-23 19:30:00+00:00\",\"predicted\":46.179518257957156,\"rising_edge\":\"2017-08-23 19:00:00+00:00\"},{\"actual\":46.53469182782241,\"falling_edge\":\"2017-08-23 20:00:00+00:00\",\"predicted\":46.53469182782241,\"rising_edge\":\"2017-08-23 19:30:00+00:00\"},{\"actual\":47.362406582463706,\"falling_edge\":\"2017-08-23 20:30:00+00:00\",\"predicted\":47.362406582463706,\"rising_edge\":\"2017-08-23 20:00:00+00:00\"},{\"actual\":52.88696789035689,\"falling_edge\":\"2017-08-23 21:00:00+00:00\",\"predicted\":52.88696789035689,\"rising_edge\":\"2017-08-23 20:30:00+00:00\"},{\"actual\":71.97076854229805,\"falling_edge\":\"2017-08-23 21:30:00+00:00\",\"predicted\":71.97076854229805,\"rising_edge\":\"2017-08-23 21:00:00+00:00\"},{\"actual\":108.96072124417996,\"falling_edge\":\"2017-08-23 22:00:00+00:00\",\"predicted\":108.96072124417996,\"rising_edge\":\"2017-08-23 21:30:00+00:00\"},{\"actual\":110.3032271830057,\"falling_edge\":\"2017-08-23 22:30:00+00:00\",\"predicted\":110.3032271830057,\"rising_edge\":\"2017-08-23 22:00:00+00:00\"},{\"actual\":137.37201838327786,\"falling_edge\":\"2017-08-23 23:00:00+00:00\",\"predicted\":137.37201838327786,\"rising_edge\":\"2017-08-23 22:30:00+00:00\"},{\"actual\":180.45779614733442,\"falling_edge\":\"2017-08-23 23:30:00+00:00\",\"predicted\":180.45779614733442,\"rising_edge\":\"2017-08-23 23:00:00+00:00\"},{\"actual\":231.59125744537022,\"falling_edge\":\"2017-08-24 00:00:00+00:00\",\"predicted\":231.59125744537022,\"rising_edge\":\"2017-08-23 23:30:00+00:00\"},{\"actual\":241.53770003200157,\"falling_edge\":\"2017-08-24 00:30:00+00:00\",\"predicted\":241.53770003200157,\"rising_edge\":\"2017-08-24 00:00:00+00:00\"},{\"actual\":240.8482149625205,\"falling_edge\":\"2017-08-24 01:00:00+00:00\",\"predicted\":240.8482149625205,\"rising_edge\":\"2017-08-24 00:30:00+00:00\"},{\"actual\":255.37413926440183,\"falling_edge\":\"2017-08-24 01:30:00+00:00\",\"predicted\":255.37413926440183,\"rising_edge\":\"2017-08-24 01:00:00+00:00\"},{\"actual\":254.59250999954003,\"falling_edge\":\"2017-08-24 02:00:00+00:00\",\"predicted\":254.59250999954003,\"rising_edge\":\"2017-08-24 01:30:00+00:00\"},{\"actual\":251.07519596194732,\"falling_edge\":\"2017-08-24 02:30:00+00:00\",\"predicted\":251.07519596194732,\"rising_edge\":\"2017-08-24 02:00:00+00:00\"},{\"actual\":248.77982382830018,\"falling_edge\":\"2017-08-24 03:00:00+00:00\",\"predicted\":248.77982382830018,\"rising_edge\":\"2017-08-24 02:30:00+00:00\"},{\"actual\":241.4668961167791,\"falling_edge\":\"2017-08-24 03:30:00+00:00\",\"predicted\":241.4668961167791,\"rising_edge\":\"2017-08-24 03:00:00+00:00\"},{\"actual\":230.8813689350076,\"falling_edge\":\"2017-08-24 04:00:00+00:00\",\"predicted\":230.8813689350076,\"rising_edge\":\"2017-08-24 03:30:00+00:00\"},{\"actual\":238.26201666433684,\"falling_edge\":\"2017-08-24 04:30:00+00:00\",\"predicted\":238.26201666433684,\"rising_edge\":\"2017-08-24 04:00:00+00:00\"},{\"actual\":240.39066070266523,\"falling_edge\":\"2017-08-24 05:00:00+00:00\",\"predicted\":240.39066070266523,\"rising_edge\":\"2017-08-24 04:30:00+00:00\"},{\"actual\":235.10289753980663,\"falling_edge\":\"2017-08-24 05:30:00+00:00\",\"predicted\":235.10289753980663,\"rising_edge\":\"2017-08-24 05:00:00+00:00\"},{\"actual\":240.17691572385274,\"falling_edge\":\"2017-08-24 06:00:00+00:00\",\"predicted\":240.17691572385274,\"rising_edge\":\"2017-08-24 05:30:00+00:00\"},{\"actual\":243.6523247193495,\"falling_edge\":\"2017-08-24 06:30:00+00:00\",\"predicted\":243.6523247193495,\"rising_edge\":\"2017-08-24 06:00:00+00:00\"},{\"actual\":259.1225607739112,\"falling_edge\":\"2017-08-24 07:00:00+00:00\",\"predicted\":259.1225607739112,\"rising_edge\":\"2017-08-24 06:30:00+00:00\"},{\"actual\":250.68285157226487,\"falling_edge\":\"2017-08-24 07:30:00+00:00\",\"predicted\":250.68285157226487,\"rising_edge\":\"2017-08-24 07:00:00+00:00\"},{\"actual\":247.53530159396303,\"falling_edge\":\"2017-08-24 08:00:00+00:00\",\"predicted\":247.53530159396303,\"rising_edge\":\"2017-08-24 07:30:00+00:00\"},{\"actual\":239.21441302328518,\"falling_edge\":\"2017-08-24 08:30:00+00:00\",\"predicted\":239.21441302328518,\"rising_edge\":\"2017-08-24 08:00:00+00:00\"},{\"actual\":227.7914419078212,\"falling_edge\":\"2017-08-24 09:00:00+00:00\",\"predicted\":227.7914419078212,\"rising_edge\":\"2017-08-24 08:30:00+00:00\"},{\"actual\":197.51875006708102,\"falling_edge\":\"2017-08-24 09:30:00+00:00\",\"predicted\":197.51875006708102,\"rising_edge\":\"2017-08-24 09:00:00+00:00\"},{\"actual\":177.0996231379843,\"falling_edge\":\"2017-08-24 10:00:00+00:00\",\"predicted\":177.0996231379843,\"rising_edge\":\"2017-08-24 09:30:00+00:00\"},{\"actual\":149.26982488267024,\"falling_edge\":\"2017-08-24 10:30:00+00:00\",\"predicted\":149.26982488267024,\"rising_edge\":\"2017-08-24 10:00:00+00:00\"},{\"actual\":144.15277071199,\"falling_edge\":\"2017-08-24 11:00:00+00:00\",\"predicted\":144.15277071199,\"rising_edge\":\"2017-08-24 10:30:00+00:00\"},{\"actual\":136.19545125599953,\"falling_edge\":\"2017-08-24 11:30:00+00:00\",\"predicted\":136.19545125599953,\"rising_edge\":\"2017-08-24 11:00:00+00:00\"},{\"actual\":123.41156446485586,\"falling_edge\":\"2017-08-24 12:00:00+00:00\",\"predicted\":123.41156446485586,\"rising_edge\":\"2017-08-24 11:30:00+00:00\"},{\"actual\":112.1541562798666,\"falling_edge\":\"2017-08-24 12:30:00+00:00\",\"predicted\":112.1541562798666,\"rising_edge\":\"2017-08-24 12:00:00+00:00\"},{\"actual\":99.58275476412473,\"falling_edge\":\"2017-08-24 13:00:00+00:00\",\"predicted\":99.58275476412473,\"rising_edge\":\"2017-08-24 12:30:00+00:00\"},{\"actual\":86.53700170636336,\"falling_edge\":\"2017-08-24 13:30:00+00:00\",\"predicted\":86.53700170636336,\"rising_edge\":\"2017-08-24 13:00:00+00:00\"},{\"actual\":76.21920343239324,\"falling_edge\":\"2017-08-24 14:00:00+00:00\",\"predicted\":76.21920343239324,\"rising_edge\":\"2017-08-24 13:30:00+00:00\"},{\"actual\":70.03246291131575,\"falling_edge\":\"2017-08-24 14:30:00+00:00\",\"predicted\":70.03246291131575,\"rising_edge\":\"2017-08-24 14:00:00+00:00\"},{\"actual\":62.489041785346004,\"falling_edge\":\"2017-08-24 15:00:00+00:00\",\"predicted\":62.489041785346004,\"rising_edge\":\"2017-08-24 14:30:00+00:00\"},{\"actual\":54.64308943804317,\"falling_edge\":\"2017-08-24 15:30:00+00:00\",\"predicted\":54.64308943804317,\"rising_edge\":\"2017-08-24 15:00:00+00:00\"},{\"actual\":49.930728506158786,\"falling_edge\":\"2017-08-24 16:00:00+00:00\",\"predicted\":49.930728506158786,\"rising_edge\":\"2017-08-24 15:30:00+00:00\"},{\"actual\":48.176134752473466,\"falling_edge\":\"2017-08-24 16:30:00+00:00\",\"predicted\":48.176134752473466,\"rising_edge\":\"2017-08-24 16:00:00+00:00\"},{\"actual\":48.74926032060059,\"falling_edge\":\"2017-08-24 17:00:00+00:00\",\"predicted\":48.74926032060059,\"rising_edge\":\"2017-08-24 16:30:00+00:00\"},{\"actual\":48.2039603296167,\"falling_edge\":\"2017-08-24 17:30:00+00:00\",\"predicted\":48.2039603296167,\"rising_edge\":\"2017-08-24 17:00:00+00:00\"},{\"actual\":46.56726767169574,\"falling_edge\":\"2017-08-24 18:00:00+00:00\",\"predicted\":46.56726767169574,\"rising_edge\":\"2017-08-24 17:30:00+00:00\"},{\"actual\":47.27787587685194,\"falling_edge\":\"2017-08-24 18:30:00+00:00\",\"predicted\":47.27787587685194,\"rising_edge\":\"2017-08-24 18:00:00+00:00\"},{\"actual\":46.967225028670406,\"falling_edge\":\"2017-08-24 19:00:00+00:00\",\"predicted\":46.967225028670406,\"rising_edge\":\"2017-08-24 18:30:00+00:00\"},{\"actual\":47.85691120535328,\"falling_edge\":\"2017-08-24 19:30:00+00:00\",\"predicted\":47.85691120535328,\"rising_edge\":\"2017-08-24 19:00:00+00:00\"},{\"actual\":46.58454688324614,\"falling_edge\":\"2017-08-24 20:00:00+00:00\",\"predicted\":46.58454688324614,\"rising_edge\":\"2017-08-24 19:30:00+00:00\"},{\"actual\":48.58539897601122,\"falling_edge\":\"2017-08-24 20:30:00+00:00\",\"predicted\":48.58539897601122,\"rising_edge\":\"2017-08-24 20:00:00+00:00\"},{\"actual\":53.22854749842335,\"falling_edge\":\"2017-08-24 21:00:00+00:00\",\"predicted\":53.22854749842335,\"rising_edge\":\"2017-08-24 20:30:00+00:00\"},{\"actual\":69.79138643064003,\"falling_edge\":\"2017-08-24 21:30:00+00:00\",\"predicted\":69.79138643064003,\"rising_edge\":\"2017-08-24 21:00:00+00:00\"},{\"actual\":113.77380597639694,\"falling_edge\":\"2017-08-24 22:00:00+00:00\",\"predicted\":113.77380597639694,\"rising_edge\":\"2017-08-24 21:30:00+00:00\"},{\"actual\":121.50003038944092,\"falling_edge\":\"2017-08-24 22:30:00+00:00\",\"predicted\":121.50003038944092,\"rising_edge\":\"2017-08-24 22:00:00+00:00\"},{\"actual\":135.0422306372602,\"falling_edge\":\"2017-08-24 23:00:00+00:00\",\"predicted\":135.0422306372602,\"rising_edge\":\"2017-08-24 22:30:00+00:00\"},{\"actual\":175.66406743208546,\"falling_edge\":\"2017-08-24 23:30:00+00:00\",\"predicted\":175.66406743208546,\"rising_edge\":\"2017-08-24 23:00:00+00:00\"},{\"actual\":224.50079758657535,\"falling_edge\":\"2017-08-25 00:00:00+00:00\",\"predicted\":224.50079758657535,\"rising_edge\":\"2017-08-24 23:30:00+00:00\"},{\"actual\":233.42877488004345,\"falling_edge\":\"2017-08-25 00:30:00+00:00\",\"predicted\":233.42877488004345,\"rising_edge\":\"2017-08-25 00:00:00+00:00\"},{\"actual\":236.97421872808428,\"falling_edge\":\"2017-08-25 01:00:00+00:00\",\"predicted\":236.97421872808428,\"rising_edge\":\"2017-08-25 00:30:00+00:00\"},{\"actual\":243.12642865431445,\"falling_edge\":\"2017-08-25 01:30:00+00:00\",\"predicted\":243.12642865431445,\"rising_edge\":\"2017-08-25 01:00:00+00:00\"},{\"actual\":243.14284613199533,\"falling_edge\":\"2017-08-25 02:00:00+00:00\",\"predicted\":243.14284613199533,\"rising_edge\":\"2017-08-25 01:30:00+00:00\"},{\"actual\":234.44557846622158,\"falling_edge\":\"2017-08-25 02:30:00+00:00\",\"predicted\":234.44557846622158,\"rising_edge\":\"2017-08-25 02:00:00+00:00\"},{\"actual\":231.52665423146783,\"falling_edge\":\"2017-08-25 03:00:00+00:00\",\"predicted\":231.52665423146783,\"rising_edge\":\"2017-08-25 02:30:00+00:00\"},{\"actual\":228.13630724309255,\"falling_edge\":\"2017-08-25 03:30:00+00:00\",\"predicted\":228.13630724309255,\"rising_edge\":\"2017-08-25 03:00:00+00:00\"},{\"actual\":221.0693771750899,\"falling_edge\":\"2017-08-25 04:00:00+00:00\",\"predicted\":221.0693771750899,\"rising_edge\":\"2017-08-25 03:30:00+00:00\"},{\"actual\":222.39054296095526,\"falling_edge\":\"2017-08-25 04:30:00+00:00\",\"predicted\":222.39054296095526,\"rising_edge\":\"2017-08-25 04:00:00+00:00\"},{\"actual\":228.49273344400504,\"falling_edge\":\"2017-08-25 05:00:00+00:00\",\"predicted\":228.49273344400504,\"rising_edge\":\"2017-08-25 04:30:00+00:00\"},{\"actual\":220.5635196449913,\"falling_edge\":\"2017-08-25 05:30:00+00:00\",\"predicted\":220.5635196449913,\"rising_edge\":\"2017-08-25 05:00:00+00:00\"},{\"actual\":227.3440366108437,\"falling_edge\":\"2017-08-25 06:00:00+00:00\",\"predicted\":227.3440366108437,\"rising_edge\":\"2017-08-25 05:30:00+00:00\"},{\"actual\":236.85706789500225,\"falling_edge\":\"2017-08-25 06:30:00+00:00\",\"predicted\":236.85706789500225,\"rising_edge\":\"2017-08-25 06:00:00+00:00\"},{\"actual\":240.1897671069759,\"falling_edge\":\"2017-08-25 07:00:00+00:00\",\"predicted\":240.1897671069759,\"rising_edge\":\"2017-08-25 06:30:00+00:00\"},{\"actual\":238.02131250329927,\"falling_edge\":\"2017-08-25 07:30:00+00:00\",\"predicted\":238.02131250329927,\"rising_edge\":\"2017-08-25 07:00:00+00:00\"},{\"actual\":237.495251851486,\"falling_edge\":\"2017-08-25 08:00:00+00:00\",\"predicted\":237.495251851486,\"rising_edge\":\"2017-08-25 07:30:00+00:00\"},{\"actual\":232.76798121020195,\"falling_edge\":\"2017-08-25 08:30:00+00:00\",\"predicted\":232.76798121020195,\"rising_edge\":\"2017-08-25 08:00:00+00:00\"},{\"actual\":221.96784985992318,\"falling_edge\":\"2017-08-25 09:00:00+00:00\",\"predicted\":221.96784985992318,\"rising_edge\":\"2017-08-25 08:30:00+00:00\"},{\"actual\":184.0824445626709,\"falling_edge\":\"2017-08-25 09:30:00+00:00\",\"predicted\":184.0824445626709,\"rising_edge\":\"2017-08-25 09:00:00+00:00\"},{\"actual\":164.75529845919027,\"falling_edge\":\"2017-08-25 10:00:00+00:00\",\"predicted\":164.75529845919027,\"rising_edge\":\"2017-08-25 09:30:00+00:00\"},{\"actual\":134.39781958795407,\"falling_edge\":\"2017-08-25 10:30:00+00:00\",\"predicted\":134.39781958795407,\"rising_edge\":\"2017-08-25 10:00:00+00:00\"},{\"actual\":126.61398476249236,\"falling_edge\":\"2017-08-25 11:00:00+00:00\",\"predicted\":126.61398476249236,\"rising_edge\":\"2017-08-25 10:30:00+00:00\"},{\"actual\":114.92342484552022,\"falling_edge\":\"2017-08-25 11:30:00+00:00\",\"predicted\":114.92342484552022,\"rising_edge\":\"2017-08-25 11:00:00+00:00\"},{\"actual\":104.28991070109532,\"falling_edge\":\"2017-08-25 12:00:00+00:00\",\"predicted\":104.28991070109532,\"rising_edge\":\"2017-08-25 11:30:00+00:00\"},{\"actual\":92.62503686585758,\"falling_edge\":\"2017-08-25 12:30:00+00:00\",\"predicted\":92.62503686585758,\"rising_edge\":\"2017-08-25 12:00:00+00:00\"},{\"actual\":83.08339968889892,\"falling_edge\":\"2017-08-25 13:00:00+00:00\",\"predicted\":83.08339968889892,\"rising_edge\":\"2017-08-25 12:30:00+00:00\"},{\"actual\":75.650273973978,\"falling_edge\":\"2017-08-25 13:30:00+00:00\",\"predicted\":75.650273973978,\"rising_edge\":\"2017-08-25 13:00:00+00:00\"},{\"actual\":71.69597241200051,\"falling_edge\":\"2017-08-25 14:00:00+00:00\",\"predicted\":71.69597241200051,\"rising_edge\":\"2017-08-25 13:30:00+00:00\"},{\"actual\":61.33182278836684,\"falling_edge\":\"2017-08-25 14:30:00+00:00\",\"predicted\":61.33182278836684,\"rising_edge\":\"2017-08-25 14:00:00+00:00\"},{\"actual\":57.663369572164655,\"falling_edge\":\"2017-08-25 15:00:00+00:00\",\"predicted\":57.663369572164655,\"rising_edge\":\"2017-08-25 14:30:00+00:00\"},{\"actual\":50.96228500332693,\"falling_edge\":\"2017-08-25 15:30:00+00:00\",\"predicted\":50.96228500332693,\"rising_edge\":\"2017-08-25 15:00:00+00:00\"},{\"actual\":47.758329467468364,\"falling_edge\":\"2017-08-25 16:00:00+00:00\",\"predicted\":47.758329467468364,\"rising_edge\":\"2017-08-25 15:30:00+00:00\"},{\"actual\":48.97895837502632,\"falling_edge\":\"2017-08-25 16:30:00+00:00\",\"predicted\":48.97895837502632,\"rising_edge\":\"2017-08-25 16:00:00+00:00\"},{\"actual\":48.003385812233276,\"falling_edge\":\"2017-08-25 17:00:00+00:00\",\"predicted\":48.003385812233276,\"rising_edge\":\"2017-08-25 16:30:00+00:00\"},{\"actual\":48.54219252750607,\"falling_edge\":\"2017-08-25 17:30:00+00:00\",\"predicted\":48.54219252750607,\"rising_edge\":\"2017-08-25 17:00:00+00:00\"},{\"actual\":46.94358096170771,\"falling_edge\":\"2017-08-25 18:00:00+00:00\",\"predicted\":46.94358096170771,\"rising_edge\":\"2017-08-25 17:30:00+00:00\"},{\"actual\":48.81619414863874,\"falling_edge\":\"2017-08-25 18:30:00+00:00\",\"predicted\":48.81619414863874,\"rising_edge\":\"2017-08-25 18:00:00+00:00\"},{\"actual\":50.70450275270199,\"falling_edge\":\"2017-08-25 19:00:00+00:00\",\"predicted\":50.70450275270199,\"rising_edge\":\"2017-08-25 18:30:00+00:00\"},{\"actual\":50.858805827804574,\"falling_edge\":\"2017-08-25 19:30:00+00:00\",\"predicted\":50.858805827804574,\"rising_edge\":\"2017-08-25 19:00:00+00:00\"},{\"actual\":49.209759148241346,\"falling_edge\":\"2017-08-25 20:00:00+00:00\",\"predicted\":49.209759148241346,\"rising_edge\":\"2017-08-25 19:30:00+00:00\"},{\"actual\":49.67167764951064,\"falling_edge\":\"2017-08-25 20:30:00+00:00\",\"predicted\":49.67167764951064,\"rising_edge\":\"2017-08-25 20:00:00+00:00\"},{\"actual\":50.60698475163703,\"falling_edge\":\"2017-08-25 21:00:00+00:00\",\"predicted\":50.60698475163703,\"rising_edge\":\"2017-08-25 20:30:00+00:00\"},{\"actual\":59.08217177974717,\"falling_edge\":\"2017-08-25 21:30:00+00:00\",\"predicted\":59.08217177974717,\"rising_edge\":\"2017-08-25 21:00:00+00:00\"},{\"actual\":62.3165793810723,\"falling_edge\":\"2017-08-25 22:00:00+00:00\",\"predicted\":62.3165793810723,\"rising_edge\":\"2017-08-25 21:30:00+00:00\"},{\"actual\":62.085116557687584,\"falling_edge\":\"2017-08-25 22:30:00+00:00\",\"predicted\":62.085116557687584,\"rising_edge\":\"2017-08-25 22:00:00+00:00\"},{\"actual\":61.24161721901523,\"falling_edge\":\"2017-08-25 23:00:00+00:00\",\"predicted\":61.24161721901523,\"rising_edge\":\"2017-08-25 22:30:00+00:00\"},{\"actual\":62.54360822482756,\"falling_edge\":\"2017-08-25 23:30:00+00:00\",\"predicted\":62.54360822482756,\"rising_edge\":\"2017-08-25 23:00:00+00:00\"},{\"actual\":66.68078377134027,\"falling_edge\":\"2017-08-26 00:00:00+00:00\",\"predicted\":66.68078377134027,\"rising_edge\":\"2017-08-25 23:30:00+00:00\"},{\"actual\":72.85217182466425,\"falling_edge\":\"2017-08-26 00:30:00+00:00\",\"predicted\":72.85217182466425,\"rising_edge\":\"2017-08-26 00:00:00+00:00\"},{\"actual\":77.48634190173243,\"falling_edge\":\"2017-08-26 01:00:00+00:00\",\"predicted\":77.48634190173243,\"rising_edge\":\"2017-08-26 00:30:00+00:00\"},{\"actual\":77.59211270179308,\"falling_edge\":\"2017-08-26 01:30:00+00:00\",\"predicted\":77.59211270179308,\"rising_edge\":\"2017-08-26 01:00:00+00:00\"},{\"actual\":79.32401408084314,\"falling_edge\":\"2017-08-26 02:00:00+00:00\",\"predicted\":79.32401408084314,\"rising_edge\":\"2017-08-26 01:30:00+00:00\"},{\"actual\":78.2873505951933,\"falling_edge\":\"2017-08-26 02:30:00+00:00\",\"predicted\":78.2873505951933,\"rising_edge\":\"2017-08-26 02:00:00+00:00\"},{\"actual\":79.91047116094619,\"falling_edge\":\"2017-08-26 03:00:00+00:00\",\"predicted\":79.91047116094619,\"rising_edge\":\"2017-08-26 02:30:00+00:00\"},{\"actual\":80.9137337268733,\"falling_edge\":\"2017-08-26 03:30:00+00:00\",\"predicted\":80.9137337268733,\"rising_edge\":\"2017-08-26 03:00:00+00:00\"},{\"actual\":80.89758112314233,\"falling_edge\":\"2017-08-26 04:00:00+00:00\",\"predicted\":80.89758112314233,\"rising_edge\":\"2017-08-26 03:30:00+00:00\"},{\"actual\":83.50691626978868,\"falling_edge\":\"2017-08-26 04:30:00+00:00\",\"predicted\":83.50691626978868,\"rising_edge\":\"2017-08-26 04:00:00+00:00\"},{\"actual\":83.53419586891147,\"falling_edge\":\"2017-08-26 05:00:00+00:00\",\"predicted\":83.53419586891147,\"rising_edge\":\"2017-08-26 04:30:00+00:00\"},{\"actual\":82.06970342096608,\"falling_edge\":\"2017-08-26 05:30:00+00:00\",\"predicted\":82.06970342096608,\"rising_edge\":\"2017-08-26 05:00:00+00:00\"},{\"actual\":81.29197059018803,\"falling_edge\":\"2017-08-26 06:00:00+00:00\",\"predicted\":81.29197059018803,\"rising_edge\":\"2017-08-26 05:30:00+00:00\"},{\"actual\":83.17090285609159,\"falling_edge\":\"2017-08-26 06:30:00+00:00\",\"predicted\":83.17090285609159,\"rising_edge\":\"2017-08-26 06:00:00+00:00\"},{\"actual\":84.6775293432803,\"falling_edge\":\"2017-08-26 07:00:00+00:00\",\"predicted\":84.6775293432803,\"rising_edge\":\"2017-08-26 06:30:00+00:00\"},{\"actual\":85.0037554582271,\"falling_edge\":\"2017-08-26 07:30:00+00:00\",\"predicted\":85.0037554582271,\"rising_edge\":\"2017-08-26 07:00:00+00:00\"},{\"actual\":82.58486863699045,\"falling_edge\":\"2017-08-26 08:00:00+00:00\",\"predicted\":82.58486863699045,\"rising_edge\":\"2017-08-26 07:30:00+00:00\"},{\"actual\":81.9987901821271,\"falling_edge\":\"2017-08-26 08:30:00+00:00\",\"predicted\":81.9987901821271,\"rising_edge\":\"2017-08-26 08:00:00+00:00\"},{\"actual\":76.17649141597977,\"falling_edge\":\"2017-08-26 09:00:00+00:00\",\"predicted\":76.17649141597977,\"rising_edge\":\"2017-08-26 08:30:00+00:00\"},{\"actual\":68.32923397897878,\"falling_edge\":\"2017-08-26 09:30:00+00:00\",\"predicted\":68.32923397897878,\"rising_edge\":\"2017-08-26 09:00:00+00:00\"},{\"actual\":66.9617546346988,\"falling_edge\":\"2017-08-26 10:00:00+00:00\",\"predicted\":66.9617546346988,\"rising_edge\":\"2017-08-26 09:30:00+00:00\"},{\"actual\":64.53479100396072,\"falling_edge\":\"2017-08-26 10:30:00+00:00\",\"predicted\":64.53479100396072,\"rising_edge\":\"2017-08-26 10:00:00+00:00\"},{\"actual\":62.10031854643941,\"falling_edge\":\"2017-08-26 11:00:00+00:00\",\"predicted\":62.10031854643941,\"rising_edge\":\"2017-08-26 10:30:00+00:00\"},{\"actual\":61.4842305458131,\"falling_edge\":\"2017-08-26 11:30:00+00:00\",\"predicted\":61.4842305458131,\"rising_edge\":\"2017-08-26 11:00:00+00:00\"},{\"actual\":59.25578531512499,\"falling_edge\":\"2017-08-26 12:00:00+00:00\",\"predicted\":59.25578531512499,\"rising_edge\":\"2017-08-26 11:30:00+00:00\"},{\"actual\":54.9275211459996,\"falling_edge\":\"2017-08-26 12:30:00+00:00\",\"predicted\":54.9275211459996,\"rising_edge\":\"2017-08-26 12:00:00+00:00\"},{\"actual\":53.48372094343743,\"falling_edge\":\"2017-08-26 13:00:00+00:00\",\"predicted\":53.48372094343743,\"rising_edge\":\"2017-08-26 12:30:00+00:00\"},{\"actual\":52.74780513488866,\"falling_edge\":\"2017-08-26 13:30:00+00:00\",\"predicted\":52.74780513488866,\"rising_edge\":\"2017-08-26 13:00:00+00:00\"},{\"actual\":52.06274223120345,\"falling_edge\":\"2017-08-26 14:00:00+00:00\",\"predicted\":52.06274223120345,\"rising_edge\":\"2017-08-26 13:30:00+00:00\"},{\"actual\":49.793261954829546,\"falling_edge\":\"2017-08-26 14:30:00+00:00\",\"predicted\":49.793261954829546,\"rising_edge\":\"2017-08-26 14:00:00+00:00\"},{\"actual\":48.64906737867296,\"falling_edge\":\"2017-08-26 15:00:00+00:00\",\"predicted\":48.64906737867296,\"rising_edge\":\"2017-08-26 14:30:00+00:00\"},{\"actual\":48.54802912738517,\"falling_edge\":\"2017-08-26 15:30:00+00:00\",\"predicted\":48.54802912738517,\"rising_edge\":\"2017-08-26 15:00:00+00:00\"},{\"actual\":46.562505720319734,\"falling_edge\":\"2017-08-26 16:00:00+00:00\",\"predicted\":46.562505720319734,\"rising_edge\":\"2017-08-26 15:30:00+00:00\"},{\"actual\":46.688722544585204,\"falling_edge\":\"2017-08-26 16:30:00+00:00\",\"predicted\":46.688722544585204,\"rising_edge\":\"2017-08-26 16:00:00+00:00\"},{\"actual\":46.23307963984327,\"falling_edge\":\"2017-08-26 17:00:00+00:00\",\"predicted\":46.23307963984327,\"rising_edge\":\"2017-08-26 16:30:00+00:00\"},{\"actual\":46.67401002105915,\"falling_edge\":\"2017-08-26 17:30:00+00:00\",\"predicted\":46.67401002105915,\"rising_edge\":\"2017-08-26 17:00:00+00:00\"},{\"actual\":46.18330210646805,\"falling_edge\":\"2017-08-26 18:00:00+00:00\",\"predicted\":46.18330210646805,\"rising_edge\":\"2017-08-26 17:30:00+00:00\"},{\"actual\":46.56640361682772,\"falling_edge\":\"2017-08-26 18:30:00+00:00\",\"predicted\":46.56640361682772,\"rising_edge\":\"2017-08-26 18:00:00+00:00\"},{\"actual\":46.006606676644424,\"falling_edge\":\"2017-08-26 19:00:00+00:00\",\"predicted\":46.006606676644424,\"rising_edge\":\"2017-08-26 18:30:00+00:00\"},{\"actual\":45.210339986119216,\"falling_edge\":\"2017-08-26 19:30:00+00:00\",\"predicted\":45.210339986119216,\"rising_edge\":\"2017-08-26 19:00:00+00:00\"},{\"actual\":45.739054470426524,\"falling_edge\":\"2017-08-26 20:00:00+00:00\",\"predicted\":45.739054470426524,\"rising_edge\":\"2017-08-26 19:30:00+00:00\"},{\"actual\":45.36200363180318,\"falling_edge\":\"2017-08-26 20:30:00+00:00\",\"predicted\":45.36200363180318,\"rising_edge\":\"2017-08-26 20:00:00+00:00\"},{\"actual\":46.42421948837546,\"falling_edge\":\"2017-08-26 21:00:00+00:00\",\"predicted\":46.42421948837546,\"rising_edge\":\"2017-08-26 20:30:00+00:00\"},{\"actual\":47.26407788048688,\"falling_edge\":\"2017-08-26 21:30:00+00:00\",\"predicted\":47.26407788048688,\"rising_edge\":\"2017-08-26 21:00:00+00:00\"},{\"actual\":49.639982000968686,\"falling_edge\":\"2017-08-26 22:00:00+00:00\",\"predicted\":49.639982000968686,\"rising_edge\":\"2017-08-26 21:30:00+00:00\"},{\"actual\":52.063665580011055,\"falling_edge\":\"2017-08-26 22:30:00+00:00\",\"predicted\":52.063665580011055,\"rising_edge\":\"2017-08-26 22:00:00+00:00\"},{\"actual\":52.17406699634041,\"falling_edge\":\"2017-08-26 23:00:00+00:00\",\"predicted\":52.17406699634041,\"rising_edge\":\"2017-08-26 22:30:00+00:00\"},{\"actual\":56.04627013202364,\"falling_edge\":\"2017-08-26 23:30:00+00:00\",\"predicted\":56.04627013202364,\"rising_edge\":\"2017-08-26 23:00:00+00:00\"},{\"actual\":61.49510214532531,\"falling_edge\":\"2017-08-27 00:00:00+00:00\",\"predicted\":61.49510214532531,\"rising_edge\":\"2017-08-26 23:30:00+00:00\"},{\"actual\":67.08147858129624,\"falling_edge\":\"2017-08-27 00:30:00+00:00\",\"predicted\":67.08147858129624,\"rising_edge\":\"2017-08-27 00:00:00+00:00\"},{\"actual\":70.3872044724828,\"falling_edge\":\"2017-08-27 01:00:00+00:00\",\"predicted\":70.3872044724828,\"rising_edge\":\"2017-08-27 00:30:00+00:00\"},{\"actual\":70.07689925397294,\"falling_edge\":\"2017-08-27 01:30:00+00:00\",\"predicted\":70.07689925397294,\"rising_edge\":\"2017-08-27 01:00:00+00:00\"},{\"actual\":68.28006234154641,\"falling_edge\":\"2017-08-27 02:00:00+00:00\",\"predicted\":68.28006234154641,\"rising_edge\":\"2017-08-27 01:30:00+00:00\"},{\"actual\":70.1365143208309,\"falling_edge\":\"2017-08-27 02:30:00+00:00\",\"predicted\":70.1365143208309,\"rising_edge\":\"2017-08-27 02:00:00+00:00\"},{\"actual\":70.93923238124118,\"falling_edge\":\"2017-08-27 03:00:00+00:00\",\"predicted\":70.93923238124118,\"rising_edge\":\"2017-08-27 02:30:00+00:00\"},{\"actual\":70.13241800877181,\"falling_edge\":\"2017-08-27 03:30:00+00:00\",\"predicted\":70.13241800877181,\"rising_edge\":\"2017-08-27 03:00:00+00:00\"},{\"actual\":70.71564695669288,\"falling_edge\":\"2017-08-27 04:00:00+00:00\",\"predicted\":70.71564695669288,\"rising_edge\":\"2017-08-27 03:30:00+00:00\"},{\"actual\":77.19016977109575,\"falling_edge\":\"2017-08-27 04:30:00+00:00\",\"predicted\":77.19016977109575,\"rising_edge\":\"2017-08-27 04:00:00+00:00\"},{\"actual\":76.96121449914237,\"falling_edge\":\"2017-08-27 05:00:00+00:00\",\"predicted\":76.96121449914237,\"rising_edge\":\"2017-08-27 04:30:00+00:00\"},{\"actual\":77.24371949424845,\"falling_edge\":\"2017-08-27 05:30:00+00:00\",\"predicted\":77.24371949424845,\"rising_edge\":\"2017-08-27 05:00:00+00:00\"},{\"actual\":77.22897311526162,\"falling_edge\":\"2017-08-27 06:00:00+00:00\",\"predicted\":77.22897311526162,\"rising_edge\":\"2017-08-27 05:30:00+00:00\"},{\"actual\":80.32010159729037,\"falling_edge\":\"2017-08-27 06:30:00+00:00\",\"predicted\":80.32010159729037,\"rising_edge\":\"2017-08-27 06:00:00+00:00\"},{\"actual\":81.22886258327215,\"falling_edge\":\"2017-08-27 07:00:00+00:00\",\"predicted\":81.22886258327215,\"rising_edge\":\"2017-08-27 06:30:00+00:00\"},{\"actual\":79.84597351852292,\"falling_edge\":\"2017-08-27 07:30:00+00:00\",\"predicted\":79.84597351852292,\"rising_edge\":\"2017-08-27 07:00:00+00:00\"},{\"actual\":78.8268131286161,\"falling_edge\":\"2017-08-27 08:00:00+00:00\",\"predicted\":78.8268131286161,\"rising_edge\":\"2017-08-27 07:30:00+00:00\"},{\"actual\":77.34057663746307,\"falling_edge\":\"2017-08-27 08:30:00+00:00\",\"predicted\":77.34057663746307,\"rising_edge\":\"2017-08-27 08:00:00+00:00\"},{\"actual\":74.18400595368315,\"falling_edge\":\"2017-08-27 09:00:00+00:00\",\"predicted\":74.18400595368315,\"rising_edge\":\"2017-08-27 08:30:00+00:00\"},{\"actual\":68.1435437112664,\"falling_edge\":\"2017-08-27 09:30:00+00:00\",\"predicted\":68.1435437112664,\"rising_edge\":\"2017-08-27 09:00:00+00:00\"},{\"actual\":64.52418315857481,\"falling_edge\":\"2017-08-27 10:00:00+00:00\",\"predicted\":64.52418315857481,\"rising_edge\":\"2017-08-27 09:30:00+00:00\"},{\"actual\":61.8312039171997,\"falling_edge\":\"2017-08-27 10:30:00+00:00\",\"predicted\":61.8312039171997,\"rising_edge\":\"2017-08-27 10:00:00+00:00\"},{\"actual\":61.175705023081825,\"falling_edge\":\"2017-08-27 11:00:00+00:00\",\"predicted\":61.175705023081825,\"rising_edge\":\"2017-08-27 10:30:00+00:00\"},{\"actual\":59.64729322719295,\"falling_edge\":\"2017-08-27 11:30:00+00:00\",\"predicted\":59.64729322719295,\"rising_edge\":\"2017-08-27 11:00:00+00:00\"},{\"actual\":58.88587758001058,\"falling_edge\":\"2017-08-27 12:00:00+00:00\",\"predicted\":58.88587758001058,\"rising_edge\":\"2017-08-27 11:30:00+00:00\"},{\"actual\":55.03788243387727,\"falling_edge\":\"2017-08-27 12:30:00+00:00\",\"predicted\":55.03788243387727,\"rising_edge\":\"2017-08-27 12:00:00+00:00\"},{\"actual\":52.87925202493206,\"falling_edge\":\"2017-08-27 13:00:00+00:00\",\"predicted\":52.87925202493206,\"rising_edge\":\"2017-08-27 12:30:00+00:00\"},{\"actual\":52.118881658565094,\"falling_edge\":\"2017-08-27 13:30:00+00:00\",\"predicted\":52.118881658565094,\"rising_edge\":\"2017-08-27 13:00:00+00:00\"},{\"actual\":50.201289920879006,\"falling_edge\":\"2017-08-27 14:00:00+00:00\",\"predicted\":50.201289920879006,\"rising_edge\":\"2017-08-27 13:30:00+00:00\"},{\"actual\":51.19394591011561,\"falling_edge\":\"2017-08-27 14:30:00+00:00\",\"predicted\":51.19394591011561,\"rising_edge\":\"2017-08-27 14:00:00+00:00\"},{\"actual\":49.364650625380364,\"falling_edge\":\"2017-08-27 15:00:00+00:00\",\"predicted\":49.364650625380364,\"rising_edge\":\"2017-08-27 14:30:00+00:00\"},{\"actual\":48.94627028724958,\"falling_edge\":\"2017-08-27 15:30:00+00:00\",\"predicted\":48.94627028724958,\"rising_edge\":\"2017-08-27 15:00:00+00:00\"},{\"actual\":48.56793532115857,\"falling_edge\":\"2017-08-27 16:00:00+00:00\",\"predicted\":48.56793532115857,\"rising_edge\":\"2017-08-27 15:30:00+00:00\"},{\"actual\":49.292689871310124,\"falling_edge\":\"2017-08-27 16:30:00+00:00\",\"predicted\":49.292689871310124,\"rising_edge\":\"2017-08-27 16:00:00+00:00\"},{\"actual\":47.606945959854386,\"falling_edge\":\"2017-08-27 17:00:00+00:00\",\"predicted\":47.606945959854386,\"rising_edge\":\"2017-08-27 16:30:00+00:00\"},{\"actual\":46.63334836509177,\"falling_edge\":\"2017-08-27 17:30:00+00:00\",\"predicted\":46.63334836509177,\"rising_edge\":\"2017-08-27 17:00:00+00:00\"},{\"actual\":47.38886498921942,\"falling_edge\":\"2017-08-27 18:00:00+00:00\",\"predicted\":47.38886498921942,\"rising_edge\":\"2017-08-27 17:30:00+00:00\"},{\"actual\":46.66787789611666,\"falling_edge\":\"2017-08-27 18:30:00+00:00\",\"predicted\":46.66787789611666,\"rising_edge\":\"2017-08-27 18:00:00+00:00\"},{\"actual\":46.95401820872757,\"falling_edge\":\"2017-08-27 19:00:00+00:00\",\"predicted\":46.95401820872757,\"rising_edge\":\"2017-08-27 18:30:00+00:00\"},{\"actual\":46.29208391806045,\"falling_edge\":\"2017-08-27 19:30:00+00:00\",\"predicted\":46.29208391806045,\"rising_edge\":\"2017-08-27 19:00:00+00:00\"},{\"actual\":47.112584288709954,\"falling_edge\":\"2017-08-27 20:00:00+00:00\",\"predicted\":47.112584288709954,\"rising_edge\":\"2017-08-27 19:30:00+00:00\"},{\"actual\":47.83862170602993,\"falling_edge\":\"2017-08-27 20:30:00+00:00\",\"predicted\":47.83862170602993,\"rising_edge\":\"2017-08-27 20:00:00+00:00\"},{\"actual\":53.15775680011349,\"falling_edge\":\"2017-08-27 21:00:00+00:00\",\"predicted\":53.15775680011349,\"rising_edge\":\"2017-08-27 20:30:00+00:00\"},{\"actual\":70.97252671075805,\"falling_edge\":\"2017-08-27 21:30:00+00:00\",\"predicted\":70.97252671075805,\"rising_edge\":\"2017-08-27 21:00:00+00:00\"},{\"actual\":130.56681239337854,\"falling_edge\":\"2017-08-27 22:00:00+00:00\",\"predicted\":130.56681239337854,\"rising_edge\":\"2017-08-27 21:30:00+00:00\"},{\"actual\":116.82654782313554,\"falling_edge\":\"2017-08-27 22:30:00+00:00\",\"predicted\":116.82654782313554,\"rising_edge\":\"2017-08-27 22:00:00+00:00\"},{\"actual\":137.03165543228664,\"falling_edge\":\"2017-08-27 23:00:00+00:00\",\"predicted\":137.03165543228664,\"rising_edge\":\"2017-08-27 22:30:00+00:00\"},{\"actual\":171.665509303965,\"falling_edge\":\"2017-08-27 23:30:00+00:00\",\"predicted\":171.665509303965,\"rising_edge\":\"2017-08-27 23:00:00+00:00\"},{\"actual\":216.3620956853549,\"falling_edge\":\"2017-08-28 00:00:00+00:00\",\"predicted\":216.3620956853549,\"rising_edge\":\"2017-08-27 23:30:00+00:00\"},{\"actual\":223.8972606468126,\"falling_edge\":\"2017-08-28 00:30:00+00:00\",\"predicted\":223.8972606468126,\"rising_edge\":\"2017-08-28 00:00:00+00:00\"},{\"actual\":233.72676631446345,\"falling_edge\":\"2017-08-28 01:00:00+00:00\",\"predicted\":233.72676631446345,\"rising_edge\":\"2017-08-28 00:30:00+00:00\"},{\"actual\":239.0093196079246,\"falling_edge\":\"2017-08-28 01:30:00+00:00\",\"predicted\":239.0093196079246,\"rising_edge\":\"2017-08-28 01:00:00+00:00\"},{\"actual\":233.08922466892858,\"falling_edge\":\"2017-08-28 02:00:00+00:00\",\"predicted\":233.08922466892858,\"rising_edge\":\"2017-08-28 01:30:00+00:00\"},{\"actual\":233.74688956207078,\"falling_edge\":\"2017-08-28 02:30:00+00:00\",\"predicted\":233.74688956207078,\"rising_edge\":\"2017-08-28 02:00:00+00:00\"},{\"actual\":225.14315137440016,\"falling_edge\":\"2017-08-28 03:00:00+00:00\",\"predicted\":225.14315137440016,\"rising_edge\":\"2017-08-28 02:30:00+00:00\"},{\"actual\":227.95533548404305,\"falling_edge\":\"2017-08-28 03:30:00+00:00\",\"predicted\":227.95533548404305,\"rising_edge\":\"2017-08-28 03:00:00+00:00\"},{\"actual\":215.8481332263646,\"falling_edge\":\"2017-08-28 04:00:00+00:00\",\"predicted\":215.8481332263646,\"rising_edge\":\"2017-08-28 03:30:00+00:00\"},{\"actual\":224.35211292621005,\"falling_edge\":\"2017-08-28 04:30:00+00:00\",\"predicted\":224.35211292621005,\"rising_edge\":\"2017-08-28 04:00:00+00:00\"},{\"actual\":220.94561744382864,\"falling_edge\":\"2017-08-28 05:00:00+00:00\",\"predicted\":220.94561744382864,\"rising_edge\":\"2017-08-28 04:30:00+00:00\"},{\"actual\":218.50152737848782,\"falling_edge\":\"2017-08-28 05:30:00+00:00\",\"predicted\":218.50152737848782,\"rising_edge\":\"2017-08-28 05:00:00+00:00\"},{\"actual\":214.08042632927894,\"falling_edge\":\"2017-08-28 06:00:00+00:00\",\"predicted\":214.08042632927894,\"rising_edge\":\"2017-08-28 05:30:00+00:00\"},{\"actual\":219.57018852134794,\"falling_edge\":\"2017-08-28 06:30:00+00:00\",\"predicted\":219.57018852134794,\"rising_edge\":\"2017-08-28 06:00:00+00:00\"},{\"actual\":219.07862450996197,\"falling_edge\":\"2017-08-28 07:00:00+00:00\",\"predicted\":219.07862450996197,\"rising_edge\":\"2017-08-28 06:30:00+00:00\"},{\"actual\":221.74374816292075,\"falling_edge\":\"2017-08-28 07:30:00+00:00\",\"predicted\":221.74374816292075,\"rising_edge\":\"2017-08-28 07:00:00+00:00\"},{\"actual\":216.13813059628032,\"falling_edge\":\"2017-08-28 08:00:00+00:00\",\"predicted\":216.13813059628032,\"rising_edge\":\"2017-08-28 07:30:00+00:00\"},{\"actual\":216.05483689411807,\"falling_edge\":\"2017-08-28 08:30:00+00:00\",\"predicted\":216.05483689411807,\"rising_edge\":\"2017-08-28 08:00:00+00:00\"},{\"actual\":203.5654609291023,\"falling_edge\":\"2017-08-28 09:00:00+00:00\",\"predicted\":203.5654609291023,\"rising_edge\":\"2017-08-28 08:30:00+00:00\"},{\"actual\":173.39458723936818,\"falling_edge\":\"2017-08-28 09:30:00+00:00\",\"predicted\":173.39458723936818,\"rising_edge\":\"2017-08-28 09:00:00+00:00\"},{\"actual\":159.88207230071205,\"falling_edge\":\"2017-08-28 10:00:00+00:00\",\"predicted\":159.88207230071205,\"rising_edge\":\"2017-08-28 09:30:00+00:00\"},{\"actual\":137.9559108785642,\"falling_edge\":\"2017-08-28 10:30:00+00:00\",\"predicted\":137.9559108785642,\"rising_edge\":\"2017-08-28 10:00:00+00:00\"},{\"actual\":134.08544626884918,\"falling_edge\":\"2017-08-28 11:00:00+00:00\",\"predicted\":134.08544626884918,\"rising_edge\":\"2017-08-28 10:30:00+00:00\"},{\"actual\":125.6791672097238,\"falling_edge\":\"2017-08-28 11:30:00+00:00\",\"predicted\":125.6791672097238,\"rising_edge\":\"2017-08-28 11:00:00+00:00\"},{\"actual\":114.11878620761766,\"falling_edge\":\"2017-08-28 12:00:00+00:00\",\"predicted\":114.11878620761766,\"rising_edge\":\"2017-08-28 11:30:00+00:00\"},{\"actual\":103.19690473090515,\"falling_edge\":\"2017-08-28 12:30:00+00:00\",\"predicted\":103.19690473090515,\"rising_edge\":\"2017-08-28 12:00:00+00:00\"},{\"actual\":95.80591347825622,\"falling_edge\":\"2017-08-28 13:00:00+00:00\",\"predicted\":95.80591347825622,\"rising_edge\":\"2017-08-28 12:30:00+00:00\"},{\"actual\":87.8384252501844,\"falling_edge\":\"2017-08-28 13:30:00+00:00\",\"predicted\":87.8384252501844,\"rising_edge\":\"2017-08-28 13:00:00+00:00\"},{\"actual\":76.61400397730246,\"falling_edge\":\"2017-08-28 14:00:00+00:00\",\"predicted\":76.61400397730246,\"rising_edge\":\"2017-08-28 13:30:00+00:00\"},{\"actual\":65.83322849806915,\"falling_edge\":\"2017-08-28 14:30:00+00:00\",\"predicted\":65.83322849806915,\"rising_edge\":\"2017-08-28 14:00:00+00:00\"},{\"actual\":58.8170323627074,\"falling_edge\":\"2017-08-28 15:00:00+00:00\",\"predicted\":58.8170323627074,\"rising_edge\":\"2017-08-28 14:30:00+00:00\"},{\"actual\":52.98806862041048,\"falling_edge\":\"2017-08-28 15:30:00+00:00\",\"predicted\":52.98806862041048,\"rising_edge\":\"2017-08-28 15:00:00+00:00\"},{\"actual\":48.349435429842266,\"falling_edge\":\"2017-08-28 16:00:00+00:00\",\"predicted\":48.349435429842266,\"rising_edge\":\"2017-08-28 15:30:00+00:00\"},{\"actual\":47.600787642936744,\"falling_edge\":\"2017-08-28 16:30:00+00:00\",\"predicted\":47.600787642936744,\"rising_edge\":\"2017-08-28 16:00:00+00:00\"},{\"actual\":47.60316900763263,\"falling_edge\":\"2017-08-28 17:00:00+00:00\",\"predicted\":47.60316900763263,\"rising_edge\":\"2017-08-28 16:30:00+00:00\"},{\"actual\":47.50867467688474,\"falling_edge\":\"2017-08-28 17:30:00+00:00\",\"predicted\":47.50867467688474,\"rising_edge\":\"2017-08-28 17:00:00+00:00\"},{\"actual\":46.34722021989913,\"falling_edge\":\"2017-08-28 18:00:00+00:00\",\"predicted\":46.34722021989913,\"rising_edge\":\"2017-08-28 17:30:00+00:00\"},{\"actual\":46.158627953182325,\"falling_edge\":\"2017-08-28 18:30:00+00:00\",\"predicted\":46.158627953182325,\"rising_edge\":\"2017-08-28 18:00:00+00:00\"},{\"actual\":45.60882615402432,\"falling_edge\":\"2017-08-28 19:00:00+00:00\",\"predicted\":45.60882615402432,\"rising_edge\":\"2017-08-28 18:30:00+00:00\"},{\"actual\":45.89170859147767,\"falling_edge\":\"2017-08-28 19:30:00+00:00\",\"predicted\":45.89170859147767,\"rising_edge\":\"2017-08-28 19:00:00+00:00\"},{\"actual\":44.98751060426954,\"falling_edge\":\"2017-08-28 20:00:00+00:00\",\"predicted\":44.98751060426954,\"rising_edge\":\"2017-08-28 19:30:00+00:00\"},{\"actual\":47.137936702280506,\"falling_edge\":\"2017-08-28 20:30:00+00:00\",\"predicted\":47.137936702280506,\"rising_edge\":\"2017-08-28 20:00:00+00:00\"},{\"actual\":52.23166919318614,\"falling_edge\":\"2017-08-28 21:00:00+00:00\",\"predicted\":52.23166919318614,\"rising_edge\":\"2017-08-28 20:30:00+00:00\"},{\"actual\":68.81005874370354,\"falling_edge\":\"2017-08-28 21:30:00+00:00\",\"predicted\":68.81005874370354,\"rising_edge\":\"2017-08-28 21:00:00+00:00\"},{\"actual\":110.53891521609471,\"falling_edge\":\"2017-08-28 22:00:00+00:00\",\"predicted\":110.53891521609471,\"rising_edge\":\"2017-08-28 21:30:00+00:00\"},{\"actual\":113.38821943679599,\"falling_edge\":\"2017-08-28 22:30:00+00:00\",\"predicted\":113.38821943679599,\"rising_edge\":\"2017-08-28 22:00:00+00:00\"},{\"actual\":139.33682975703925,\"falling_edge\":\"2017-08-28 23:00:00+00:00\",\"predicted\":139.33682975703925,\"rising_edge\":\"2017-08-28 22:30:00+00:00\"},{\"actual\":176.6999472426274,\"falling_edge\":\"2017-08-28 23:30:00+00:00\",\"predicted\":176.6999472426274,\"rising_edge\":\"2017-08-28 23:00:00+00:00\"},{\"actual\":218.23816278351714,\"falling_edge\":\"2017-08-29 00:00:00+00:00\",\"predicted\":218.23816278351714,\"rising_edge\":\"2017-08-28 23:30:00+00:00\"},{\"actual\":227.63291834992643,\"falling_edge\":\"2017-08-29 00:30:00+00:00\",\"predicted\":227.63291834992643,\"rising_edge\":\"2017-08-29 00:00:00+00:00\"},{\"actual\":238.71139928792874,\"falling_edge\":\"2017-08-29 01:00:00+00:00\",\"predicted\":238.71139928792874,\"rising_edge\":\"2017-08-29 00:30:00+00:00\"},{\"actual\":239.17528628164885,\"falling_edge\":\"2017-08-29 01:30:00+00:00\",\"predicted\":239.17528628164885,\"rising_edge\":\"2017-08-29 01:00:00+00:00\"},{\"actual\":241.45503841484992,\"falling_edge\":\"2017-08-29 02:00:00+00:00\",\"predicted\":241.45503841484992,\"rising_edge\":\"2017-08-29 01:30:00+00:00\"},{\"actual\":238.9866426449217,\"falling_edge\":\"2017-08-29 02:30:00+00:00\",\"predicted\":238.9866426449217,\"rising_edge\":\"2017-08-29 02:00:00+00:00\"},{\"actual\":239.03893220199026,\"falling_edge\":\"2017-08-29 03:00:00+00:00\",\"predicted\":239.03893220199026,\"rising_edge\":\"2017-08-29 02:30:00+00:00\"},{\"actual\":227.59352456964933,\"falling_edge\":\"2017-08-29 03:30:00+00:00\",\"predicted\":227.59352456964933,\"rising_edge\":\"2017-08-29 03:00:00+00:00\"},{\"actual\":224.2513217040057,\"falling_edge\":\"2017-08-29 04:00:00+00:00\",\"predicted\":224.2513217040057,\"rising_edge\":\"2017-08-29 03:30:00+00:00\"},{\"actual\":237.2229043640622,\"falling_edge\":\"2017-08-29 04:30:00+00:00\",\"predicted\":237.2229043640622,\"rising_edge\":\"2017-08-29 04:00:00+00:00\"},{\"actual\":233.8614422313151,\"falling_edge\":\"2017-08-29 05:00:00+00:00\",\"predicted\":233.8614422313151,\"rising_edge\":\"2017-08-29 04:30:00+00:00\"},{\"actual\":228.39349890207887,\"falling_edge\":\"2017-08-29 05:30:00+00:00\",\"predicted\":228.39349890207887,\"rising_edge\":\"2017-08-29 05:00:00+00:00\"},{\"actual\":239.56026593660195,\"falling_edge\":\"2017-08-29 06:00:00+00:00\",\"predicted\":239.56026593660195,\"rising_edge\":\"2017-08-29 05:30:00+00:00\"},{\"actual\":238.0890384846819,\"falling_edge\":\"2017-08-29 06:30:00+00:00\",\"predicted\":238.0890384846819,\"rising_edge\":\"2017-08-29 06:00:00+00:00\"},{\"actual\":235.64933930670972,\"falling_edge\":\"2017-08-29 07:00:00+00:00\",\"predicted\":235.64933930670972,\"rising_edge\":\"2017-08-29 06:30:00+00:00\"},{\"actual\":233.4489756015393,\"falling_edge\":\"2017-08-29 07:30:00+00:00\",\"predicted\":233.4489756015393,\"rising_edge\":\"2017-08-29 07:00:00+00:00\"},{\"actual\":224.98054573676473,\"falling_edge\":\"2017-08-29 08:00:00+00:00\",\"predicted\":224.98054573676473,\"rising_edge\":\"2017-08-29 07:30:00+00:00\"},{\"actual\":227.73646227474515,\"falling_edge\":\"2017-08-29 08:30:00+00:00\",\"predicted\":227.73646227474515,\"rising_edge\":\"2017-08-29 08:00:00+00:00\"},{\"actual\":217.97292347033198,\"falling_edge\":\"2017-08-29 09:00:00+00:00\",\"predicted\":217.97292347033198,\"rising_edge\":\"2017-08-29 08:30:00+00:00\"},{\"actual\":186.53120754784635,\"falling_edge\":\"2017-08-29 09:30:00+00:00\",\"predicted\":186.53120754784635,\"rising_edge\":\"2017-08-29 09:00:00+00:00\"},{\"actual\":169.43942090251048,\"falling_edge\":\"2017-08-29 10:00:00+00:00\",\"predicted\":169.43942090251048,\"rising_edge\":\"2017-08-29 09:30:00+00:00\"},{\"actual\":149.2239860535773,\"falling_edge\":\"2017-08-29 10:30:00+00:00\",\"predicted\":149.2239860535773,\"rising_edge\":\"2017-08-29 10:00:00+00:00\"},{\"actual\":146.27078053290023,\"falling_edge\":\"2017-08-29 11:00:00+00:00\",\"predicted\":146.27078053290023,\"rising_edge\":\"2017-08-29 10:30:00+00:00\"},{\"actual\":139.34265608305415,\"falling_edge\":\"2017-08-29 11:30:00+00:00\",\"predicted\":139.34265608305415,\"rising_edge\":\"2017-08-29 11:00:00+00:00\"},{\"actual\":129.5237402463715,\"falling_edge\":\"2017-08-29 12:00:00+00:00\",\"predicted\":129.5237402463715,\"rising_edge\":\"2017-08-29 11:30:00+00:00\"},{\"actual\":118.23326264857914,\"falling_edge\":\"2017-08-29 12:30:00+00:00\",\"predicted\":118.23326264857914,\"rising_edge\":\"2017-08-29 12:00:00+00:00\"},{\"actual\":105.75704752632885,\"falling_edge\":\"2017-08-29 13:00:00+00:00\",\"predicted\":105.75704752632885,\"rising_edge\":\"2017-08-29 12:30:00+00:00\"},{\"actual\":95.92016171637175,\"falling_edge\":\"2017-08-29 13:30:00+00:00\",\"predicted\":95.92016171637175,\"rising_edge\":\"2017-08-29 13:00:00+00:00\"},{\"actual\":81.21509754134647,\"falling_edge\":\"2017-08-29 14:00:00+00:00\",\"predicted\":81.21509754134647,\"rising_edge\":\"2017-08-29 13:30:00+00:00\"},{\"actual\":68.31754933908493,\"falling_edge\":\"2017-08-29 14:30:00+00:00\",\"predicted\":68.31754933908493,\"rising_edge\":\"2017-08-29 14:00:00+00:00\"},{\"actual\":59.93785412125844,\"falling_edge\":\"2017-08-29 15:00:00+00:00\",\"predicted\":59.93785412125844,\"rising_edge\":\"2017-08-29 14:30:00+00:00\"},{\"actual\":55.48418828534067,\"falling_edge\":\"2017-08-29 15:30:00+00:00\",\"predicted\":55.48418828534067,\"rising_edge\":\"2017-08-29 15:00:00+00:00\"},{\"actual\":52.85063670627772,\"falling_edge\":\"2017-08-29 16:00:00+00:00\",\"predicted\":52.85063670627772,\"rising_edge\":\"2017-08-29 15:30:00+00:00\"},{\"actual\":55.374906531683294,\"falling_edge\":\"2017-08-29 16:30:00+00:00\",\"predicted\":55.374906531683294,\"rising_edge\":\"2017-08-29 16:00:00+00:00\"},{\"actual\":52.55206469446504,\"falling_edge\":\"2017-08-29 17:00:00+00:00\",\"predicted\":52.55206469446504,\"rising_edge\":\"2017-08-29 16:30:00+00:00\"},{\"actual\":50.343140915320944,\"falling_edge\":\"2017-08-29 17:30:00+00:00\",\"predicted\":50.343140915320944,\"rising_edge\":\"2017-08-29 17:00:00+00:00\"},{\"actual\":49.72370126916211,\"falling_edge\":\"2017-08-29 18:00:00+00:00\",\"predicted\":49.72370126916211,\"rising_edge\":\"2017-08-29 17:30:00+00:00\"},{\"actual\":47.15051773220452,\"falling_edge\":\"2017-08-29 18:30:00+00:00\",\"predicted\":47.15051773220452,\"rising_edge\":\"2017-08-29 18:00:00+00:00\"},{\"actual\":46.304602892055726,\"falling_edge\":\"2017-08-29 19:00:00+00:00\",\"predicted\":46.304602892055726,\"rising_edge\":\"2017-08-29 18:30:00+00:00\"},{\"actual\":47.835052227095574,\"falling_edge\":\"2017-08-29 19:30:00+00:00\",\"predicted\":47.835052227095574,\"rising_edge\":\"2017-08-29 19:00:00+00:00\"},{\"actual\":47.87147256592839,\"falling_edge\":\"2017-08-29 20:00:00+00:00\",\"predicted\":47.87147256592839,\"rising_edge\":\"2017-08-29 19:30:00+00:00\"},{\"actual\":48.999943669820816,\"falling_edge\":\"2017-08-29 20:30:00+00:00\",\"predicted\":48.999943669820816,\"rising_edge\":\"2017-08-29 20:00:00+00:00\"},{\"actual\":54.583612410082296,\"falling_edge\":\"2017-08-29 21:00:00+00:00\",\"predicted\":54.583612410082296,\"rising_edge\":\"2017-08-29 20:30:00+00:00\"},{\"actual\":71.47934714586066,\"falling_edge\":\"2017-08-29 21:30:00+00:00\",\"predicted\":71.47934714586066,\"rising_edge\":\"2017-08-29 21:00:00+00:00\"},{\"actual\":107.08586691551488,\"falling_edge\":\"2017-08-29 22:00:00+00:00\",\"predicted\":107.08586691551488,\"rising_edge\":\"2017-08-29 21:30:00+00:00\"},{\"actual\":102.34678599363704,\"falling_edge\":\"2017-08-29 22:30:00+00:00\",\"predicted\":102.34678599363704,\"rising_edge\":\"2017-08-29 22:00:00+00:00\"},{\"actual\":117.35210992155919,\"falling_edge\":\"2017-08-29 23:00:00+00:00\",\"predicted\":117.35210992155919,\"rising_edge\":\"2017-08-29 22:30:00+00:00\"},{\"actual\":161.3142166141603,\"falling_edge\":\"2017-08-29 23:30:00+00:00\",\"predicted\":161.3142166141603,\"rising_edge\":\"2017-08-29 23:00:00+00:00\"},{\"actual\":203.12408998977887,\"falling_edge\":\"2017-08-30 00:00:00+00:00\",\"predicted\":203.12408998977887,\"rising_edge\":\"2017-08-29 23:30:00+00:00\"},{\"actual\":213.24395295298865,\"falling_edge\":\"2017-08-30 00:30:00+00:00\",\"predicted\":213.24395295298865,\"rising_edge\":\"2017-08-30 00:00:00+00:00\"},{\"actual\":213.87732094778593,\"falling_edge\":\"2017-08-30 01:00:00+00:00\",\"predicted\":213.87732094778593,\"rising_edge\":\"2017-08-30 00:30:00+00:00\"},{\"actual\":232.9607135313103,\"falling_edge\":\"2017-08-30 01:30:00+00:00\",\"predicted\":232.9607135313103,\"rising_edge\":\"2017-08-30 01:00:00+00:00\"},{\"actual\":221.5532288572365,\"falling_edge\":\"2017-08-30 02:00:00+00:00\",\"predicted\":221.5532288572365,\"rising_edge\":\"2017-08-30 01:30:00+00:00\"},{\"actual\":224.79592079532648,\"falling_edge\":\"2017-08-30 02:30:00+00:00\",\"predicted\":224.79592079532648,\"rising_edge\":\"2017-08-30 02:00:00+00:00\"},{\"actual\":220.97278606536915,\"falling_edge\":\"2017-08-30 03:00:00+00:00\",\"predicted\":220.97278606536915,\"rising_edge\":\"2017-08-30 02:30:00+00:00\"},{\"actual\":212.49496617718708,\"falling_edge\":\"2017-08-30 03:30:00+00:00\",\"predicted\":212.49496617718708,\"rising_edge\":\"2017-08-30 03:00:00+00:00\"},{\"actual\":207.3281254619544,\"falling_edge\":\"2017-08-30 04:00:00+00:00\",\"predicted\":207.3281254619544,\"rising_edge\":\"2017-08-30 03:30:00+00:00\"},{\"actual\":217.58485105137433,\"falling_edge\":\"2017-08-30 04:30:00+00:00\",\"predicted\":217.58485105137433,\"rising_edge\":\"2017-08-30 04:00:00+00:00\"},{\"actual\":223.71855075151453,\"falling_edge\":\"2017-08-30 05:00:00+00:00\",\"predicted\":223.71855075151453,\"rising_edge\":\"2017-08-30 04:30:00+00:00\"},{\"actual\":223.78824455398612,\"falling_edge\":\"2017-08-30 05:30:00+00:00\",\"predicted\":223.78824455398612,\"rising_edge\":\"2017-08-30 05:00:00+00:00\"},{\"actual\":225.37667187024604,\"falling_edge\":\"2017-08-30 06:00:00+00:00\",\"predicted\":225.37667187024604,\"rising_edge\":\"2017-08-30 05:30:00+00:00\"},{\"actual\":225.06419064139703,\"falling_edge\":\"2017-08-30 06:30:00+00:00\",\"predicted\":225.06419064139703,\"rising_edge\":\"2017-08-30 06:00:00+00:00\"},{\"actual\":223.41073294656252,\"falling_edge\":\"2017-08-30 07:00:00+00:00\",\"predicted\":223.41073294656252,\"rising_edge\":\"2017-08-30 06:30:00+00:00\"},{\"actual\":224.04258777571442,\"falling_edge\":\"2017-08-30 07:30:00+00:00\",\"predicted\":224.04258777571442,\"rising_edge\":\"2017-08-30 07:00:00+00:00\"},{\"actual\":216.48058736643975,\"falling_edge\":\"2017-08-30 08:00:00+00:00\",\"predicted\":216.48058736643975,\"rising_edge\":\"2017-08-30 07:30:00+00:00\"},{\"actual\":212.34343559137875,\"falling_edge\":\"2017-08-30 08:30:00+00:00\",\"predicted\":212.34343559137875,\"rising_edge\":\"2017-08-30 08:00:00+00:00\"},{\"actual\":200.79428085260778,\"falling_edge\":\"2017-08-30 09:00:00+00:00\",\"predicted\":200.79428085260778,\"rising_edge\":\"2017-08-30 08:30:00+00:00\"},{\"actual\":167.95668530842795,\"falling_edge\":\"2017-08-30 09:30:00+00:00\",\"predicted\":167.95668530842795,\"rising_edge\":\"2017-08-30 09:00:00+00:00\"},{\"actual\":149.64987943582682,\"falling_edge\":\"2017-08-30 10:00:00+00:00\",\"predicted\":149.64987943582682,\"rising_edge\":\"2017-08-30 09:30:00+00:00\"},{\"actual\":122.73517927214134,\"falling_edge\":\"2017-08-30 10:30:00+00:00\",\"predicted\":122.73517927214134,\"rising_edge\":\"2017-08-30 10:00:00+00:00\"},{\"actual\":116.34447499618285,\"falling_edge\":\"2017-08-30 11:00:00+00:00\",\"predicted\":116.34447499618285,\"rising_edge\":\"2017-08-30 10:30:00+00:00\"},{\"actual\":108.65085450593054,\"falling_edge\":\"2017-08-30 11:30:00+00:00\",\"predicted\":108.65085450593054,\"rising_edge\":\"2017-08-30 11:00:00+00:00\"},{\"actual\":102.13924321076708,\"falling_edge\":\"2017-08-30 12:00:00+00:00\",\"predicted\":102.13924321076708,\"rising_edge\":\"2017-08-30 11:30:00+00:00\"},{\"actual\":95.53999176442598,\"falling_edge\":\"2017-08-30 12:30:00+00:00\",\"predicted\":95.53999176442598,\"rising_edge\":\"2017-08-30 12:00:00+00:00\"},{\"actual\":88.25162653057592,\"falling_edge\":\"2017-08-30 13:00:00+00:00\",\"predicted\":88.25162653057592,\"rising_edge\":\"2017-08-30 12:30:00+00:00\"},{\"actual\":75.85156058048831,\"falling_edge\":\"2017-08-30 13:30:00+00:00\",\"predicted\":75.85156058048831,\"rising_edge\":\"2017-08-30 13:00:00+00:00\"},{\"actual\":67.59498720071574,\"falling_edge\":\"2017-08-30 14:00:00+00:00\",\"predicted\":67.59498720071574,\"rising_edge\":\"2017-08-30 13:30:00+00:00\"},{\"actual\":59.97930034224666,\"falling_edge\":\"2017-08-30 14:30:00+00:00\",\"predicted\":59.97930034224666,\"rising_edge\":\"2017-08-30 14:00:00+00:00\"},{\"actual\":54.51208195451208,\"falling_edge\":\"2017-08-30 15:00:00+00:00\",\"predicted\":54.51208195451208,\"rising_edge\":\"2017-08-30 14:30:00+00:00\"},{\"actual\":50.420447332801,\"falling_edge\":\"2017-08-30 15:30:00+00:00\",\"predicted\":50.420447332801,\"rising_edge\":\"2017-08-30 15:00:00+00:00\"},{\"actual\":48.50046422313588,\"falling_edge\":\"2017-08-30 16:00:00+00:00\",\"predicted\":48.50046422313588,\"rising_edge\":\"2017-08-30 15:30:00+00:00\"},{\"actual\":46.52473285912675,\"falling_edge\":\"2017-08-30 16:30:00+00:00\",\"predicted\":46.52473285912675,\"rising_edge\":\"2017-08-30 16:00:00+00:00\"},{\"actual\":46.0995685419462,\"falling_edge\":\"2017-08-30 17:00:00+00:00\",\"predicted\":46.0995685419462,\"rising_edge\":\"2017-08-30 16:30:00+00:00\"},{\"actual\":46.541813032013984,\"falling_edge\":\"2017-08-30 17:30:00+00:00\",\"predicted\":46.541813032013984,\"rising_edge\":\"2017-08-30 17:00:00+00:00\"},{\"actual\":46.25414144681234,\"falling_edge\":\"2017-08-30 18:00:00+00:00\",\"predicted\":46.25414144681234,\"rising_edge\":\"2017-08-30 17:30:00+00:00\"},{\"actual\":45.56932064482285,\"falling_edge\":\"2017-08-30 18:30:00+00:00\",\"predicted\":45.56932064482285,\"rising_edge\":\"2017-08-30 18:00:00+00:00\"},{\"actual\":45.256157114510124,\"falling_edge\":\"2017-08-30 19:00:00+00:00\",\"predicted\":45.256157114510124,\"rising_edge\":\"2017-08-30 18:30:00+00:00\"},{\"actual\":44.838463318516936,\"falling_edge\":\"2017-08-30 19:30:00+00:00\",\"predicted\":44.838463318516936,\"rising_edge\":\"2017-08-30 19:00:00+00:00\"},{\"actual\":45.06475637598762,\"falling_edge\":\"2017-08-30 20:00:00+00:00\",\"predicted\":45.06475637598762,\"rising_edge\":\"2017-08-30 19:30:00+00:00\"},{\"actual\":46.09363863409076,\"falling_edge\":\"2017-08-30 20:30:00+00:00\",\"predicted\":46.09363863409076,\"rising_edge\":\"2017-08-30 20:00:00+00:00\"},{\"actual\":50.70457392763327,\"falling_edge\":\"2017-08-30 21:00:00+00:00\",\"predicted\":50.70457392763327,\"rising_edge\":\"2017-08-30 20:30:00+00:00\"},{\"actual\":69.00102178114534,\"falling_edge\":\"2017-08-30 21:30:00+00:00\",\"predicted\":69.00102178114534,\"rising_edge\":\"2017-08-30 21:00:00+00:00\"},{\"actual\":98.33020303809533,\"falling_edge\":\"2017-08-30 22:00:00+00:00\",\"predicted\":98.33020303809533,\"rising_edge\":\"2017-08-30 21:30:00+00:00\"},{\"actual\":96.80099386131518,\"falling_edge\":\"2017-08-30 22:30:00+00:00\",\"predicted\":96.80099386131518,\"rising_edge\":\"2017-08-30 22:00:00+00:00\"},{\"actual\":118.53536466031017,\"falling_edge\":\"2017-08-30 23:00:00+00:00\",\"predicted\":118.53536466031017,\"rising_edge\":\"2017-08-30 22:30:00+00:00\"},{\"actual\":164.026308616838,\"falling_edge\":\"2017-08-30 23:30:00+00:00\",\"predicted\":164.026308616838,\"rising_edge\":\"2017-08-30 23:00:00+00:00\"},{\"actual\":201.80509856833504,\"falling_edge\":\"2017-08-31 00:00:00+00:00\",\"predicted\":201.80509856833504,\"rising_edge\":\"2017-08-30 23:30:00+00:00\"},{\"actual\":223.24768495732542,\"falling_edge\":\"2017-08-31 00:30:00+00:00\",\"predicted\":223.24768495732542,\"rising_edge\":\"2017-08-31 00:00:00+00:00\"},{\"actual\":217.3273424149589,\"falling_edge\":\"2017-08-31 01:00:00+00:00\",\"predicted\":217.3273424149589,\"rising_edge\":\"2017-08-31 00:30:00+00:00\"},{\"actual\":225.50373278849048,\"falling_edge\":\"2017-08-31 01:30:00+00:00\",\"predicted\":225.50373278849048,\"rising_edge\":\"2017-08-31 01:00:00+00:00\"},{\"actual\":236.9373957634939,\"falling_edge\":\"2017-08-31 02:00:00+00:00\",\"predicted\":236.9373957634939,\"rising_edge\":\"2017-08-31 01:30:00+00:00\"},{\"actual\":226.94528871999387,\"falling_edge\":\"2017-08-31 02:30:00+00:00\",\"predicted\":226.94528871999387,\"rising_edge\":\"2017-08-31 02:00:00+00:00\"},{\"actual\":220.92745309823496,\"falling_edge\":\"2017-08-31 03:00:00+00:00\",\"predicted\":220.92745309823496,\"rising_edge\":\"2017-08-31 02:30:00+00:00\"},{\"actual\":215.52780973782404,\"falling_edge\":\"2017-08-31 03:30:00+00:00\",\"predicted\":215.52780973782404,\"rising_edge\":\"2017-08-31 03:00:00+00:00\"},{\"actual\":207.04183013866438,\"falling_edge\":\"2017-08-31 04:00:00+00:00\",\"predicted\":207.04183013866438,\"rising_edge\":\"2017-08-31 03:30:00+00:00\"},{\"actual\":217.33796311319384,\"falling_edge\":\"2017-08-31 04:30:00+00:00\",\"predicted\":217.33796311319384,\"rising_edge\":\"2017-08-31 04:00:00+00:00\"},{\"actual\":216.35235439381592,\"falling_edge\":\"2017-08-31 05:00:00+00:00\",\"predicted\":216.35235439381592,\"rising_edge\":\"2017-08-31 04:30:00+00:00\"},{\"actual\":215.3733770405934,\"falling_edge\":\"2017-08-31 05:30:00+00:00\",\"predicted\":215.3733770405934,\"rising_edge\":\"2017-08-31 05:00:00+00:00\"},{\"actual\":219.13924159069083,\"falling_edge\":\"2017-08-31 06:00:00+00:00\",\"predicted\":219.13924159069083,\"rising_edge\":\"2017-08-31 05:30:00+00:00\"},{\"actual\":222.83824213368737,\"falling_edge\":\"2017-08-31 06:30:00+00:00\",\"predicted\":222.83824213368737,\"rising_edge\":\"2017-08-31 06:00:00+00:00\"},{\"actual\":220.3638146436531,\"falling_edge\":\"2017-08-31 07:00:00+00:00\",\"predicted\":220.3638146436531,\"rising_edge\":\"2017-08-31 06:30:00+00:00\"},{\"actual\":218.67593393519283,\"falling_edge\":\"2017-08-31 07:30:00+00:00\",\"predicted\":218.67593393519283,\"rising_edge\":\"2017-08-31 07:00:00+00:00\"},{\"actual\":214.3160437480958,\"falling_edge\":\"2017-08-31 08:00:00+00:00\",\"predicted\":214.3160437480958,\"rising_edge\":\"2017-08-31 07:30:00+00:00\"},{\"actual\":211.60045067351425,\"falling_edge\":\"2017-08-31 08:30:00+00:00\",\"predicted\":211.60045067351425,\"rising_edge\":\"2017-08-31 08:00:00+00:00\"},{\"actual\":198.7107423426917,\"falling_edge\":\"2017-08-31 09:00:00+00:00\",\"predicted\":198.7107423426917,\"rising_edge\":\"2017-08-31 08:30:00+00:00\"},{\"actual\":175.76334817204688,\"falling_edge\":\"2017-08-31 09:30:00+00:00\",\"predicted\":175.76334817204688,\"rising_edge\":\"2017-08-31 09:00:00+00:00\"},{\"actual\":158.8560424215228,\"falling_edge\":\"2017-08-31 10:00:00+00:00\",\"predicted\":158.8560424215228,\"rising_edge\":\"2017-08-31 09:30:00+00:00\"},{\"actual\":135.70154714945997,\"falling_edge\":\"2017-08-31 10:30:00+00:00\",\"predicted\":135.70154714945997,\"rising_edge\":\"2017-08-31 10:00:00+00:00\"},{\"actual\":129.95040079230643,\"falling_edge\":\"2017-08-31 11:00:00+00:00\",\"predicted\":129.95040079230643,\"rising_edge\":\"2017-08-31 10:30:00+00:00\"},{\"actual\":123.1410386355076,\"falling_edge\":\"2017-08-31 11:30:00+00:00\",\"predicted\":123.1410386355076,\"rising_edge\":\"2017-08-31 11:00:00+00:00\"},{\"actual\":113.72735070957384,\"falling_edge\":\"2017-08-31 12:00:00+00:00\",\"predicted\":113.72735070957384,\"rising_edge\":\"2017-08-31 11:30:00+00:00\"},{\"actual\":103.3105252471514,\"falling_edge\":\"2017-08-31 12:30:00+00:00\",\"predicted\":103.3105252471514,\"rising_edge\":\"2017-08-31 12:00:00+00:00\"},{\"actual\":93.47660894253639,\"falling_edge\":\"2017-08-31 13:00:00+00:00\",\"predicted\":93.47660894253639,\"rising_edge\":\"2017-08-31 12:30:00+00:00\"},{\"actual\":82.24025126294356,\"falling_edge\":\"2017-08-31 13:30:00+00:00\",\"predicted\":82.24025126294356,\"rising_edge\":\"2017-08-31 13:00:00+00:00\"},{\"actual\":72.27583898851799,\"falling_edge\":\"2017-08-31 14:00:00+00:00\",\"predicted\":72.27583898851799,\"rising_edge\":\"2017-08-31 13:30:00+00:00\"},{\"actual\":65.4660879635429,\"falling_edge\":\"2017-08-31 14:30:00+00:00\",\"predicted\":65.4660879635429,\"rising_edge\":\"2017-08-31 14:00:00+00:00\"},{\"actual\":58.051664897163405,\"falling_edge\":\"2017-08-31 15:00:00+00:00\",\"predicted\":58.051664897163405,\"rising_edge\":\"2017-08-31 14:30:00+00:00\"},{\"actual\":50.02966901230315,\"falling_edge\":\"2017-08-31 15:30:00+00:00\",\"predicted\":50.02966901230315,\"rising_edge\":\"2017-08-31 15:00:00+00:00\"},{\"actual\":45.828646741283706,\"falling_edge\":\"2017-08-31 16:00:00+00:00\",\"predicted\":45.828646741283706,\"rising_edge\":\"2017-08-31 15:30:00+00:00\"},{\"actual\":44.638274570932985,\"falling_edge\":\"2017-08-31 16:30:00+00:00\",\"predicted\":44.638274570932985,\"rising_edge\":\"2017-08-31 16:00:00+00:00\"},{\"actual\":44.410076032167225,\"falling_edge\":\"2017-08-31 17:00:00+00:00\",\"predicted\":44.410076032167225,\"rising_edge\":\"2017-08-31 16:30:00+00:00\"},{\"actual\":44.31766050335138,\"falling_edge\":\"2017-08-31 17:30:00+00:00\",\"predicted\":44.31766050335138,\"rising_edge\":\"2017-08-31 17:00:00+00:00\"},{\"actual\":43.60816846845904,\"falling_edge\":\"2017-08-31 18:00:00+00:00\",\"predicted\":43.60816846845904,\"rising_edge\":\"2017-08-31 17:30:00+00:00\"},{\"actual\":44.26389112427131,\"falling_edge\":\"2017-08-31 18:30:00+00:00\",\"predicted\":44.26389112427131,\"rising_edge\":\"2017-08-31 18:00:00+00:00\"},{\"actual\":43.78951682992339,\"falling_edge\":\"2017-08-31 19:00:00+00:00\",\"predicted\":43.78951682992339,\"rising_edge\":\"2017-08-31 18:30:00+00:00\"},{\"actual\":44.809294983563476,\"falling_edge\":\"2017-08-31 19:30:00+00:00\",\"predicted\":44.809294983563476,\"rising_edge\":\"2017-08-31 19:00:00+00:00\"},{\"actual\":44.46311094395747,\"falling_edge\":\"2017-08-31 20:00:00+00:00\",\"predicted\":44.46311094395747,\"rising_edge\":\"2017-08-31 19:30:00+00:00\"},{\"actual\":46.48037415826052,\"falling_edge\":\"2017-08-31 20:30:00+00:00\",\"predicted\":46.48037415826052,\"rising_edge\":\"2017-08-31 20:00:00+00:00\"},{\"actual\":50.2584678859032,\"falling_edge\":\"2017-08-31 21:00:00+00:00\",\"predicted\":50.2584678859032,\"rising_edge\":\"2017-08-31 20:30:00+00:00\"},{\"actual\":67.05107556407731,\"falling_edge\":\"2017-08-31 21:30:00+00:00\",\"predicted\":67.05107556407731,\"rising_edge\":\"2017-08-31 21:00:00+00:00\"},{\"actual\":98.04369578644803,\"falling_edge\":\"2017-08-31 22:00:00+00:00\",\"predicted\":98.04369578644803,\"rising_edge\":\"2017-08-31 21:30:00+00:00\"},{\"actual\":93.65667486419719,\"falling_edge\":\"2017-08-31 22:30:00+00:00\",\"predicted\":93.65667486419719,\"rising_edge\":\"2017-08-31 22:00:00+00:00\"},{\"actual\":110.6278582376425,\"falling_edge\":\"2017-08-31 23:00:00+00:00\",\"predicted\":110.6278582376425,\"rising_edge\":\"2017-08-31 22:30:00+00:00\"},{\"actual\":144.08269026808338,\"falling_edge\":\"2017-08-31 23:30:00+00:00\",\"predicted\":144.08269026808338,\"rising_edge\":\"2017-08-31 23:00:00+00:00\"},{\"actual\":190.83707856042065,\"falling_edge\":\"2017-09-01 00:00:00+00:00\",\"predicted\":190.83707856042065,\"rising_edge\":\"2017-08-31 23:30:00+00:00\"},{\"actual\":205.6029533033786,\"falling_edge\":\"2017-09-01 00:30:00+00:00\",\"predicted\":205.6029533033786,\"rising_edge\":\"2017-09-01 00:00:00+00:00\"},{\"actual\":213.4763145612078,\"falling_edge\":\"2017-09-01 01:00:00+00:00\",\"predicted\":213.4763145612078,\"rising_edge\":\"2017-09-01 00:30:00+00:00\"},{\"actual\":217.4131182100183,\"falling_edge\":\"2017-09-01 01:30:00+00:00\",\"predicted\":217.4131182100183,\"rising_edge\":\"2017-09-01 01:00:00+00:00\"},{\"actual\":209.94633048534956,\"falling_edge\":\"2017-09-01 02:00:00+00:00\",\"predicted\":209.94633048534956,\"rising_edge\":\"2017-09-01 01:30:00+00:00\"},{\"actual\":207.94313484804908,\"falling_edge\":\"2017-09-01 02:30:00+00:00\",\"predicted\":207.94313484804908,\"rising_edge\":\"2017-09-01 02:00:00+00:00\"},{\"actual\":207.80684664549023,\"falling_edge\":\"2017-09-01 03:00:00+00:00\",\"predicted\":207.80684664549023,\"rising_edge\":\"2017-09-01 02:30:00+00:00\"},{\"actual\":200.03581515497189,\"falling_edge\":\"2017-09-01 03:30:00+00:00\",\"predicted\":200.03581515497189,\"rising_edge\":\"2017-09-01 03:00:00+00:00\"},{\"actual\":189.3746622266831,\"falling_edge\":\"2017-09-01 04:00:00+00:00\",\"predicted\":189.3746622266831,\"rising_edge\":\"2017-09-01 03:30:00+00:00\"},{\"actual\":207.22354019771737,\"falling_edge\":\"2017-09-01 04:30:00+00:00\",\"predicted\":207.22354019771737,\"rising_edge\":\"2017-09-01 04:00:00+00:00\"},{\"actual\":209.04358874252588,\"falling_edge\":\"2017-09-01 05:00:00+00:00\",\"predicted\":209.04358874252588,\"rising_edge\":\"2017-09-01 04:30:00+00:00\"},{\"actual\":200.91169710753059,\"falling_edge\":\"2017-09-01 05:30:00+00:00\",\"predicted\":200.91169710753059,\"rising_edge\":\"2017-09-01 05:00:00+00:00\"},{\"actual\":202.2481350083064,\"falling_edge\":\"2017-09-01 06:00:00+00:00\",\"predicted\":202.2481350083064,\"rising_edge\":\"2017-09-01 05:30:00+00:00\"},{\"actual\":203.18418021018934,\"falling_edge\":\"2017-09-01 06:30:00+00:00\",\"predicted\":203.18418021018934,\"rising_edge\":\"2017-09-01 06:00:00+00:00\"},{\"actual\":205.1662514419398,\"falling_edge\":\"2017-09-01 07:00:00+00:00\",\"predicted\":205.1662514419398,\"rising_edge\":\"2017-09-01 06:30:00+00:00\"},{\"actual\":200.14712974432643,\"falling_edge\":\"2017-09-01 07:30:00+00:00\",\"predicted\":200.14712974432643,\"rising_edge\":\"2017-09-01 07:00:00+00:00\"},{\"actual\":198.79638451926877,\"falling_edge\":\"2017-09-01 08:00:00+00:00\",\"predicted\":198.79638451926877,\"rising_edge\":\"2017-09-01 07:30:00+00:00\"},{\"actual\":195.46601695065283,\"falling_edge\":\"2017-09-01 08:30:00+00:00\",\"predicted\":195.46601695065283,\"rising_edge\":\"2017-09-01 08:00:00+00:00\"},{\"actual\":184.79329647196445,\"falling_edge\":\"2017-09-01 09:00:00+00:00\",\"predicted\":184.79329647196445,\"rising_edge\":\"2017-09-01 08:30:00+00:00\"},{\"actual\":163.24000625439137,\"falling_edge\":\"2017-09-01 09:30:00+00:00\",\"predicted\":163.24000625439137,\"rising_edge\":\"2017-09-01 09:00:00+00:00\"},{\"actual\":145.12551696883384,\"falling_edge\":\"2017-09-01 10:00:00+00:00\",\"predicted\":145.12551696883384,\"rising_edge\":\"2017-09-01 09:30:00+00:00\"},{\"actual\":122.36951109094652,\"falling_edge\":\"2017-09-01 10:30:00+00:00\",\"predicted\":122.36951109094652,\"rising_edge\":\"2017-09-01 10:00:00+00:00\"},{\"actual\":114.7728572577824,\"falling_edge\":\"2017-09-01 11:00:00+00:00\",\"predicted\":114.7728572577824,\"rising_edge\":\"2017-09-01 10:30:00+00:00\"},{\"actual\":105.64857100742125,\"falling_edge\":\"2017-09-01 11:30:00+00:00\",\"predicted\":105.64857100742125,\"rising_edge\":\"2017-09-01 11:00:00+00:00\"},{\"actual\":97.38441444532162,\"falling_edge\":\"2017-09-01 12:00:00+00:00\",\"predicted\":97.38441444532162,\"rising_edge\":\"2017-09-01 11:30:00+00:00\"},{\"actual\":88.5664483221547,\"falling_edge\":\"2017-09-01 12:30:00+00:00\",\"predicted\":88.5664483221547,\"rising_edge\":\"2017-09-01 12:00:00+00:00\"},{\"actual\":80.02231759103326,\"falling_edge\":\"2017-09-01 13:00:00+00:00\",\"predicted\":80.02231759103326,\"rising_edge\":\"2017-09-01 12:30:00+00:00\"},{\"actual\":73.31356151468212,\"falling_edge\":\"2017-09-01 13:30:00+00:00\",\"predicted\":73.31356151468212,\"rising_edge\":\"2017-09-01 13:00:00+00:00\"},{\"actual\":66.47945618048382,\"falling_edge\":\"2017-09-01 14:00:00+00:00\",\"predicted\":66.47945618048382,\"rising_edge\":\"2017-09-01 13:30:00+00:00\"},{\"actual\":58.880661375814405,\"falling_edge\":\"2017-09-01 14:30:00+00:00\",\"predicted\":58.880661375814405,\"rising_edge\":\"2017-09-01 14:00:00+00:00\"},{\"actual\":54.08327566184613,\"falling_edge\":\"2017-09-01 15:00:00+00:00\",\"predicted\":54.08327566184613,\"rising_edge\":\"2017-09-01 14:30:00+00:00\"},{\"actual\":48.9121773555799,\"falling_edge\":\"2017-09-01 15:30:00+00:00\",\"predicted\":48.9121773555799,\"rising_edge\":\"2017-09-01 15:00:00+00:00\"},{\"actual\":45.7231586149443,\"falling_edge\":\"2017-09-01 16:00:00+00:00\",\"predicted\":45.7231586149443,\"rising_edge\":\"2017-09-01 15:30:00+00:00\"},{\"actual\":45.32230209513062,\"falling_edge\":\"2017-09-01 16:30:00+00:00\",\"predicted\":45.32230209513062,\"rising_edge\":\"2017-09-01 16:00:00+00:00\"},{\"actual\":44.69367919100392,\"falling_edge\":\"2017-09-01 17:00:00+00:00\",\"predicted\":44.69367919100392,\"rising_edge\":\"2017-09-01 16:30:00+00:00\"},{\"actual\":44.79702640910878,\"falling_edge\":\"2017-09-01 17:30:00+00:00\",\"predicted\":44.79702640910878,\"rising_edge\":\"2017-09-01 17:00:00+00:00\"},{\"actual\":43.99552586753569,\"falling_edge\":\"2017-09-01 18:00:00+00:00\",\"predicted\":43.99552586753569,\"rising_edge\":\"2017-09-01 17:30:00+00:00\"},{\"actual\":44.994897375119045,\"falling_edge\":\"2017-09-01 18:30:00+00:00\",\"predicted\":44.994897375119045,\"rising_edge\":\"2017-09-01 18:00:00+00:00\"},{\"actual\":44.896571606683196,\"falling_edge\":\"2017-09-01 19:00:00+00:00\",\"predicted\":44.896571606683196,\"rising_edge\":\"2017-09-01 18:30:00+00:00\"},{\"actual\":45.61170143877896,\"falling_edge\":\"2017-09-01 19:30:00+00:00\",\"predicted\":45.61170143877896,\"rising_edge\":\"2017-09-01 19:00:00+00:00\"},{\"actual\":44.90611132857175,\"falling_edge\":\"2017-09-01 20:00:00+00:00\",\"predicted\":44.90611132857175,\"rising_edge\":\"2017-09-01 19:30:00+00:00\"},{\"actual\":45.71823989824657,\"falling_edge\":\"2017-09-01 20:30:00+00:00\",\"predicted\":45.71823989824657,\"rising_edge\":\"2017-09-01 20:00:00+00:00\"},{\"actual\":48.42491366906053,\"falling_edge\":\"2017-09-01 21:00:00+00:00\",\"predicted\":48.42491366906053,\"rising_edge\":\"2017-09-01 20:30:00+00:00\"},{\"actual\":56.083592464882344,\"falling_edge\":\"2017-09-01 21:30:00+00:00\",\"predicted\":56.083592464882344,\"rising_edge\":\"2017-09-01 21:00:00+00:00\"},{\"actual\":59.941811671749505,\"falling_edge\":\"2017-09-01 22:00:00+00:00\",\"predicted\":59.941811671749505,\"rising_edge\":\"2017-09-01 21:30:00+00:00\"},{\"actual\":59.60112023940781,\"falling_edge\":\"2017-09-01 22:30:00+00:00\",\"predicted\":59.60112023940781,\"rising_edge\":\"2017-09-01 22:00:00+00:00\"},{\"actual\":60.208253159371715,\"falling_edge\":\"2017-09-01 23:00:00+00:00\",\"predicted\":60.208253159371715,\"rising_edge\":\"2017-09-01 22:30:00+00:00\"},{\"actual\":63.45012943974007,\"falling_edge\":\"2017-09-01 23:30:00+00:00\",\"predicted\":63.45012943974007,\"rising_edge\":\"2017-09-01 23:00:00+00:00\"},{\"actual\":67.6237242289411,\"falling_edge\":\"2017-09-02 00:00:00+00:00\",\"predicted\":67.6237242289411,\"rising_edge\":\"2017-09-01 23:30:00+00:00\"},{\"actual\":74.1779084008318,\"falling_edge\":\"2017-09-02 00:30:00+00:00\",\"predicted\":74.1779084008318,\"rising_edge\":\"2017-09-02 00:00:00+00:00\"},{\"actual\":81.08314508114931,\"falling_edge\":\"2017-09-02 01:00:00+00:00\",\"predicted\":81.08314508114931,\"rising_edge\":\"2017-09-02 00:30:00+00:00\"},{\"actual\":81.88661187454618,\"falling_edge\":\"2017-09-02 01:30:00+00:00\",\"predicted\":81.88661187454618,\"rising_edge\":\"2017-09-02 01:00:00+00:00\"},{\"actual\":83.33953361030919,\"falling_edge\":\"2017-09-02 02:00:00+00:00\",\"predicted\":83.33953361030919,\"rising_edge\":\"2017-09-02 01:30:00+00:00\"},{\"actual\":80.72371006906253,\"falling_edge\":\"2017-09-02 02:30:00+00:00\",\"predicted\":80.72371006906253,\"rising_edge\":\"2017-09-02 02:00:00+00:00\"},{\"actual\":83.83006652364712,\"falling_edge\":\"2017-09-02 03:00:00+00:00\",\"predicted\":83.83006652364712,\"rising_edge\":\"2017-09-02 02:30:00+00:00\"},{\"actual\":83.6723372832892,\"falling_edge\":\"2017-09-02 03:30:00+00:00\",\"predicted\":83.6723372832892,\"rising_edge\":\"2017-09-02 03:00:00+00:00\"},{\"actual\":82.09577270937541,\"falling_edge\":\"2017-09-02 04:00:00+00:00\",\"predicted\":82.09577270937541,\"rising_edge\":\"2017-09-02 03:30:00+00:00\"},{\"actual\":86.11831032741566,\"falling_edge\":\"2017-09-02 04:30:00+00:00\",\"predicted\":86.11831032741566,\"rising_edge\":\"2017-09-02 04:00:00+00:00\"},{\"actual\":83.98994734218647,\"falling_edge\":\"2017-09-02 05:00:00+00:00\",\"predicted\":83.98994734218647,\"rising_edge\":\"2017-09-02 04:30:00+00:00\"},{\"actual\":82.50705411324131,\"falling_edge\":\"2017-09-02 05:30:00+00:00\",\"predicted\":82.50705411324131,\"rising_edge\":\"2017-09-02 05:00:00+00:00\"},{\"actual\":81.68334604905094,\"falling_edge\":\"2017-09-02 06:00:00+00:00\",\"predicted\":81.68334604905094,\"rising_edge\":\"2017-09-02 05:30:00+00:00\"},{\"actual\":81.47706410568242,\"falling_edge\":\"2017-09-02 06:30:00+00:00\",\"predicted\":81.47706410568242,\"rising_edge\":\"2017-09-02 06:00:00+00:00\"},{\"actual\":82.43094907599374,\"falling_edge\":\"2017-09-02 07:00:00+00:00\",\"predicted\":82.43094907599374,\"rising_edge\":\"2017-09-02 06:30:00+00:00\"},{\"actual\":81.58021493108622,\"falling_edge\":\"2017-09-02 07:30:00+00:00\",\"predicted\":81.58021493108622,\"rising_edge\":\"2017-09-02 07:00:00+00:00\"},{\"actual\":78.4654196210524,\"falling_edge\":\"2017-09-02 08:00:00+00:00\",\"predicted\":78.4654196210524,\"rising_edge\":\"2017-09-02 07:30:00+00:00\"},{\"actual\":77.7320753578484,\"falling_edge\":\"2017-09-02 08:30:00+00:00\",\"predicted\":77.7320753578484,\"rising_edge\":\"2017-09-02 08:00:00+00:00\"},{\"actual\":72.36401730307065,\"falling_edge\":\"2017-09-02 09:00:00+00:00\",\"predicted\":72.36401730307065,\"rising_edge\":\"2017-09-02 08:30:00+00:00\"},{\"actual\":64.85886975738175,\"falling_edge\":\"2017-09-02 09:30:00+00:00\",\"predicted\":64.85886975738175,\"rising_edge\":\"2017-09-02 09:00:00+00:00\"},{\"actual\":62.78079849545464,\"falling_edge\":\"2017-09-02 10:00:00+00:00\",\"predicted\":62.78079849545464,\"rising_edge\":\"2017-09-02 09:30:00+00:00\"},{\"actual\":60.384517541471425,\"falling_edge\":\"2017-09-02 10:30:00+00:00\",\"predicted\":60.384517541471425,\"rising_edge\":\"2017-09-02 10:00:00+00:00\"},{\"actual\":58.78728321274703,\"falling_edge\":\"2017-09-02 11:00:00+00:00\",\"predicted\":58.78728321274703,\"rising_edge\":\"2017-09-02 10:30:00+00:00\"},{\"actual\":58.03894094653403,\"falling_edge\":\"2017-09-02 11:30:00+00:00\",\"predicted\":58.03894094653403,\"rising_edge\":\"2017-09-02 11:00:00+00:00\"},{\"actual\":56.29327272592667,\"falling_edge\":\"2017-09-02 12:00:00+00:00\",\"predicted\":56.29327272592667,\"rising_edge\":\"2017-09-02 11:30:00+00:00\"},{\"actual\":52.35718484916157,\"falling_edge\":\"2017-09-02 12:30:00+00:00\",\"predicted\":52.35718484916157,\"rising_edge\":\"2017-09-02 12:00:00+00:00\"},{\"actual\":50.553622026500335,\"falling_edge\":\"2017-09-02 13:00:00+00:00\",\"predicted\":50.553622026500335,\"rising_edge\":\"2017-09-02 12:30:00+00:00\"},{\"actual\":49.923285490804055,\"falling_edge\":\"2017-09-02 13:30:00+00:00\",\"predicted\":49.923285490804055,\"rising_edge\":\"2017-09-02 13:00:00+00:00\"},{\"actual\":49.05772273640695,\"falling_edge\":\"2017-09-02 14:00:00+00:00\",\"predicted\":49.05772273640695,\"rising_edge\":\"2017-09-02 13:30:00+00:00\"},{\"actual\":47.34692502242274,\"falling_edge\":\"2017-09-02 14:30:00+00:00\",\"predicted\":47.34692502242274,\"rising_edge\":\"2017-09-02 14:00:00+00:00\"},{\"actual\":46.40184087502746,\"falling_edge\":\"2017-09-02 15:00:00+00:00\",\"predicted\":46.40184087502746,\"rising_edge\":\"2017-09-02 14:30:00+00:00\"}]\n"
  },
  {
    "path": "examples/sankeyChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            width: 100%;\n        }\n\n        .nvd3 {\n            margin-bottom: 50px;\n        }\n\n        pre {\n            padding: 20px;\n            background-color: #ddd;\n            display: inline-block;\n        }\n\n        /* --- Sankey chart styles --- */\n\n        .node rect {\n            cursor: move;\n            fill-opacity: .9;\n            shape-rendering: crispEdges;\n        }\n\n        .node text {\n            pointer-events: none;\n            text-shadow: 0 1px 0 #fff;\n        }\n\n        .link {\n            fill: none;\n            stroke: #000;\n            stroke-opacity: .2;\n        }\n\n        .link:hover {\n            stroke-opacity: .5;\n        }\n\n    </style>\n</head>\n<body>\n<h3>Sankey Chart</h3>\n\n<h6>Basic CSS for Sankey chart:</h6>\n<pre>\n.node rect {\n    cursor: move;\n    fill-opacity: .9;\n    shape-rendering: crispEdges;\n}\n\n.node text {\n    pointer-events: none;\n    text-shadow: 0 1px 0 #fff;\n}\n\n.link {\n    fill: none;\n    stroke: #000;\n    stroke-opacity: .2;\n}\n\n.link:hover {\n    stroke-opacity: .5;\n}\n</pre>\n\n<div id=\"sankey-chart-simple\" class=\"nvd3\"></div>\n<div id=\"sankey-chart-advanced\" class=\"nvd3\"></div>\n\n<script>\n    var width = 800,\n    height = 600;\n    var data = {\n        nodes:\n            [\n                {'node': 1, 'name': 'Test 1'},\n                {'node': 2, 'name': 'Test 2'},\n                {'node': 3, 'name': 'Test 3'},\n                {'node': 4, 'name': 'Test 4'},\n                {'node': 5, 'name': 'Test 5'},\n                {'node': 6, 'name': 'Test 6'}\n            ],\n        links:\n            [\n                {'source': 0, 'target': 1, 'value': 2295},\n                {'source': 0, 'target': 5, 'value': 1199},\n                {'source': 1, 'target': 2, 'value': 1119},\n                {'source': 1, 'target': 5, 'value': 1176},\n                {'source': 2, 'target': 3, 'value': 487},\n                {'source': 2, 'target': 5, 'value': 632},\n                {'source': 3, 'target': 4, 'value': 301},\n                {'source': 3, 'target': 5, 'value': 186}\n            ]\n    };\n\n    nv.addGraph(function() {\n        var chart = nv.models.sankeyChart()\n            .width(width)\n            .height(height)\n            .units('elephants');\n\n        d3.select('#sankey-chart-simple')\n            .attr('width', width)\n            .attr('height', height)\n            .datum(data)\n            .call(chart);\n\n        return chart;\n    });\n\n    nv.addGraph(function() {\n        var units = 'ducks';\n        var chart = nv.models.sankeyChart()\n            .width(width)\n            .height(height)\n            .format(function(d) {\n                return formatNumber(d) + ' ' + units;\n            })\n            .linkTitle(function(d){\n                return d.source.name + ' ----> ' + d.target.name + '\\n' + d.value + ' ' + units;\n            })\n            .nodeStyle({\n                title: function(d){\n                    return d.name + ': ' + d.value + ' ' + units;\n                },\n                fillColor: function(d){\n                    return d3.rgb(d.color).brighter(2);\n                },\n                strokeColor: function(d){\n                    return d3.rgb(d.color).darker(2);\n                }\n            })\n            .nodeWidth(100)\n            .nodePadding(200)\n            .units('ducks')\n            .center(function(node){\n                return node.dy\n            });\n\n        d3.select('#sankey-chart-advanced')\n            .attr('width', width)\n            .attr('height', height)\n            .datum(data)\n            .call(chart);\n\n        return chart;\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/scatter.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<svg id=\"test1\"></svg>\n\n<script>\n\n    nv.addGraph(function() {\n\n        var chart = nv.models.scatter()\n            .margin({top: 20, right: 20, bottom: 20, left: 20})\n            .pointSize(function(d) { return d.z })\n            .useVoronoi(false);\n\n        d3.select('#test1')\n            .datum(randomData())\n            .transition().duration(500)\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n    function randomData() {\n        var data = [];\n\n        for (i = 0; i < 2; i++) {\n            data.push({\n                key: 'Group ' + i,\n                values: []\n            });\n\n            for (j = 0; j < 100; j++) {\n                data[i].values.push({x: Math.random(), y: Math.random(), z: Math.random()});\n            }\n        }\n\n        return data;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/scatterChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #test1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"test1\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    // register our custom symbols to nvd3\n    // make sure your path is valid given any size because size scales if the chart scales.\n    nv.utils.symbolMap.set('thin-x', function(size) {\n        size = Math.sqrt(size);\n        return 'M' + (-size/2) + ',' + (-size/2) +\n                'l' + size + ',' + size +\n                'm0,' + -(size) +\n                'l' + (-size) + ',' + size;\n    });\n\n    // create the chart\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.scatterChart()\n            .showDistX(true)\n            .showDistY(true)\n            .useVoronoi(true)\n            .color(d3.scale.category10().range())\n            .duration(300)\n        ;\n        chart.dispatch.on('renderEnd', function(){\n            console.log('render complete');\n        });\n\n        chart.xAxis.tickFormat(d3.format('.02f'));\n        chart.yAxis.tickFormat(d3.format('.02f'));\n\n        d3.select('#test1 svg')\n            .datum(randomData(4,40))\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        chart.dispatch.on('stateChange', function(e) { ('New State:', JSON.stringify(e)); });\n        return chart;\n    });\n\n\n    function randomData(groups, points) { //# groups,# points per group\n        // smiley and thin-x are our custom symbols!\n        var data = [],\n            shapes = ['thin-x', 'circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],\n            random = d3.random.normal();\n\n        for (i = 0; i < groups; i++) {\n            data.push({\n                key: 'Group ' + i,\n                values: []\n            });\n\n            for (j = 0; j < points; j++) {\n                data[i].values.push({\n                    x: random(),\n                    y: random(),\n                    size: Math.round(Math.random() * 100) / 100,\n                    shape: shapes[j % shapes.length]\n                });\n            }\n        }\n\n        return data;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/scatterPlusLineChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #test1, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<div id=\"test1\" class=\"chartWrap\">\n    <svg></svg>\n</div>\n\n<script>\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.scatterChart()\n            .showDistX(true)\n            .showDistY(true)\n            .duration(300)\n            .color(d3.scale.category10().range());\n\n        chart.dispatch.on('renderEnd', function(){\n            console.log('render complete');\n        });\n\n        chart.xAxis.tickFormat(d3.format('.02f'));\n        chart.yAxis.tickFormat(d3.format('.02f'));\n\n        d3.select('#test1 svg')\n            .datum(nv.log(randomData(4,40)))\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n        chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n        return chart;\n    });\n\n\n    function randomData(groups, points) { //# groups,# points per group\n        var data = [],\n            shapes = ['circle'],\n            random = d3.random.normal();\n\n        for (i = 0; i < groups; i++) {\n            data.push({\n                key: 'Group ' + i,\n                values: [],\n                slope: Math.random() - .01,\n                intercept: Math.random() - .5\n            });\n\n            for (j = 0; j < points; j++) {\n                data[i].values.push({\n                    x: random(),\n                    y: random(),\n                    size: Math.random(),\n                    shape: shapes[j % shapes.length]\n                });\n            }\n        }\n        return data;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/site.html",
    "content": "<!doctype html>\r\n<html>\r\n<head>\r\n    <meta charset=\"utf-8\">\r\n    <meta http-equiv=\"X-UA-Compatible\" content=\"chrome=1\">\r\n    <title>Nvd3 - reusable charts for D3.js</title>\r\n    <link rel=\"stylesheet\" href=\"stylesheets/styles.css\">\r\n    <link rel=\"stylesheet\" href=\"stylesheets/pygment_trac.css\">\r\n    <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></script>\r\n    <script>\r\n        $('body').ready(function() {\r\n            // preload iframe with message\r\n            var iframe = document.getElementById('show');\r\n            var iframedoc = iframe.contentDocument || iframe.contentWindow.document;\r\n            iframedoc.body.innerHTML = ''\r\n                + '<br><br>'\r\n                + '<div style=\"text-align: center; color: #CCC; font-family: arial; font-size: 14px; font-weight:bold;\">'\r\n                + 'Click the links above to load the example here'\r\n                + '</div>';\r\n\r\n            $('.showbases').click(function(evt){\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n                $(evt.target).fadeOut();\r\n                $('.chartlinks').stop().slideUp({complete: function() {\r\n                    $('.showcharts').fadeIn();\r\n                    $('.baselinks').slideDown();\r\n                }});\r\n            });\r\n            $('.showcharts').click(function(evt){\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n                $(evt.target).fadeOut();\r\n                $('.baselinks').stop().slideUp({complete: function() {\r\n                    $('.showbases').fadeIn();\r\n                    $('.chartlinks').slideDown();\r\n                }});\r\n            });\r\n            $('.examplelinks a').each(function(i, elem) {\r\n                $(elem).click(function(evt) {\r\n                    $('#show').prop('src', $(evt.target).prop('href'));\r\n                    evt.stopPropagation();\r\n                    evt.preventDefault();\r\n                    $('.examplelinks a').removeClass('selected');\r\n                    $(evt.target).addClass('selected');\r\n                    // add link to source\r\n                    var urlparts = $(evt.target).prop('href').split('/');\r\n                    var file = urlparts[urlparts.length - 1];\r\n                    var sourceurl = 'https://github.com/nvd3-community/nvd3/blob/gh-pages/examples/' + file;\r\n                    $('#tosource').prop('href', sourceurl).fadeIn();\r\n                    // also set link to view only the example\r\n                    $('#showonlythis').prop('href', $(evt.target).prop('href'));\r\n                    // done\r\n                    $('#example_options').attr('style', '');\r\n                    return false;\r\n                });\r\n            });\r\n        });\r\n    </script>\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\r\n\r\n</head>\r\n<body>\r\n\r\n<header>\r\n    <h1>Nvd3</h1>\r\n    <p>A reusable chart library for d3.js</p>\r\n</header>\r\n\r\n<div id=\"banner\">\r\n    <div>\r\n        <span id=\"logo\"></span>\r\n\r\n        <a href=\"https://github.com/nvd3-community/nvd3\" target=\"github\" class=\"button fork\"><strong>GitHub</strong></a>\r\n        <a href=\"site.html\" class=\"button fork docs selected\"><strong>Examples</strong></a>\r\n        <a href=\"documentation.html\" class=\"button fork docs\"><strong>Documentation</strong></a>\r\n        <div class=\"downloads\">\r\n            <span>Downloads:</span>\r\n            <ul>\r\n                <li><a href=\"https://github.com/nvd3-community/nvd3/zipball/master\" class=\"button\">ZIP</a></li>\r\n                <li><a href=\"https://github.com/nvd3-community/nvd3/tarball/master\" class=\"button\">TAR</a></li>\r\n            </ul>\r\n        </div>\r\n    </div>\r\n</div><!-- end banner -->\r\n\r\n<div class=\"wrapper\">\r\n    <nav>\r\n        <ul></ul>\r\n    </nav>\r\n    <section>\r\n        <h3>\r\n            Welcome to NVD3, reusable D3.js charts!\r\n        </h3>\r\n\r\n        <p>\r\n            View our examples below, and check out our repository or download our latest code\r\n            using the buttons above!\r\n        </p>\r\n\r\n        <div>\r\n            <a href=\"#\" class=\"showcharts\">Show Chart Examples</a>\r\n            <a href=\"#\" class=\"showbases\">Show Base Examples</a>\r\n        </div>\r\n        <div class=\"examplelinks chartlinks\">\r\n            <a href=\"bulletChart.html\">BulletChart</a> |\r\n            <a href=\"cumulativeLineChart.html\">CumulativeLineChart</a> |\r\n            <a href=\"lineChart.html\">lineChart</a> |\r\n            <a href=\"lineChartSVGResize.html\">LineChartZoom</a> |\r\n            <a href=\"lineWithFocusChart.html\">LineWithFocusChart</a> |\r\n            <a href=\"linePlusBarChart.html\">LinePlusBarChart</a> |\r\n            <a href=\"discreteBarChart.html\">DiscreteBarChart</a> |\r\n            <a href=\"historicalBarChart.html\">HistoricalBarChart</a> |\r\n            <a href=\"TimeSeries.html\">TimeSeries</a> |\r\n            <a href=\"multiBarChart.html\">MultiBarChart</a> |\r\n            <a href=\"multiBarChart2.html\">MultiBarChart2</a> |\r\n            <a href=\"multiBarHorizontalChart.html\">MultiBarHorizontalChart</a> |\r\n            <a href=\"multiChart.html\">MultiChart</a> |\r\n            <a href=\"donutChart.html\">DonutCharts</a> |\r\n            <a href=\"pieChart.html\">PieCharts</a> |\r\n            <a href=\"monitoringChart.html\">MonitoringCharts</a> |\r\n            <a href=\"scatterChart.html\">ScatterChart</a> |\r\n            <a href=\"scatterPlusLineChart.html\">ScatterPlusLineChart</a> |\r\n            <a href=\"sparklinePlus.html\">SparklinePlus</a> |\r\n            <a href=\"stackedAreaChart.html\">StackedAreaChart</a> |\r\n            <a href=\"parallelCoordinates.html\">parallelCoordinates</a> |\r\n            <a href=\"candlestickChart.html\">CandlestickChart</a> |\r\n            <a href=\"ohlcChart.html\">ohlcChart</a> |\r\n            <a href=\"sunburst.html\">sunburst</a> |\r\n            <a href=\"boxPlot.html\">boxPlot</a> |\r\n            <a href=\"boxPlotCustomModel.html\">boxPlotCustomModel</a> |\r\n            <a href=\"forceDirected.html\">forceDirected</a> |\r\n            <a href=\"distroPlotChart.html\">distroPlot</a> |\r\n            <a href=\"heatMap.html\">heatMap</a>\r\n        </div>\r\n\r\n        <div class=\"examplelinks baselinks\">\r\n            <a href=\"sparkline.html\">Sparkline</a> |\r\n            <a href=\"scatter.html\">Scatter</a> |\r\n            <a href=\"pie.html\">Pie</a> |\r\n            <a href=\"legend.html\">Legend</a> |\r\n            <a href=\"bullet.html\">Bullet</a> |\r\n            <a href=\"line.html\">Line</a> |\r\n            <a href=\"candlestick.html\">Candlestick</a> |\r\n            <a href=\"ohlc.html\">ohlc</a> |\r\n            <a href=\"stackedArea.html\">StackedArea</a> |\r\n            <a href=\"tooltip.html\">tooltip</a>\r\n        </div>\r\n\r\n        <div id=\"show_wrapper\"><iframe id=\"show\"></iframe></div>\r\n        <div id=\"example_options\" style=\"visibility: hidden;\">\r\n            <a target=\"source\" id=\"tosource\" href=\"#\">View source for the example above!</a> |\r\n            <a target=\"alone\" id=\"showonlythis\" href=\"#\">View Just This</a>\r\n        </div>\r\n\r\n    </section>\r\n</div>\r\n</body>\r\n</html>\r\n"
  },
  {
    "path": "examples/sparkline.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body {\n            margin: 0px;\n            padding: 0px;\n        }\n        #chart1 {\n            height: 30px;\n        }\n    </style>\n</head>\n<body>\n\n<h2>Sparkline: <svg id=\"chart1\" class=\"sparkline\"></svg></h2>\n\n<script>\n\n    nv.addGraph({\n        generate: function() {\n            var chart = nv.models.sparkline()\n                    .width(400)\n                    .height(30)\n\n            d3.select(\"#chart1\")\n                    .datum(sine())\n                    .call(chart);\n\n            return chart;\n        }\n    });\n\n    function sine() {\n        var sin = [];\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: Math.sin(i/10)});\n        }\n\n        return sin;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/sparklinePlus.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body {\n            margin: 0px;\n            padding: 0px;\n        }\n        svg.sparkline {\n            width: 500px;\n            height: 70px;\n            font-size: 14px;\n            margin-top: -6px;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<p><svg id=\"chart1\" class=\"sparkline\"></svg></p>\n<p><svg id=\"chart2\" class=\"sparkline\"></svg></p>\n<p><svg id=\"chart3\" class=\"sparkline\"></svg></p>\n\n<script>\n\n    function defaultChartConfig(containerId, data) {\n        nv.addGraph(function() {\n\n            var chart = nv.models.sparklinePlus();\n            chart.margin({left:70})\n                .x(function(d,i) { return i })\n                .showLastValue(true)\n                .xTickFormat(function(d) {\n                    return d3.time.format('%x')(new Date(data[d].x))\n                });\n\n            d3.select(containerId)\n                    .datum(data)\n                    .call(chart);\n\n            return chart;\n        });\n    }\n\n    defaultChartConfig(\"#chart1\",sine());\n    defaultChartConfig(\"#chart2\", volatileChart(130.0, 0.02));\n    defaultChartConfig(\"#chart3\", volatileChart(25.0, 0.09,30));\n\n    function sine() {\n        var sin = [];\n        var now =+new Date();\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: now + i * 1000 * 60 * 60 * 24, y: Math.sin(i/10)});\n        }\n\n        return sin;\n    }\n\n    function volatileChart(startPrice, volatility, numPoints) {\n        var rval =  [];\n        var now =+new Date();\n        numPoints = numPoints || 100;\n        for(var i = 1; i < numPoints; i++) {\n\n            rval.push({x: now + i * 1000 * 60 * 60 * 24, y: startPrice});\n            var rnd = Math.random();\n            var changePct = 2 * volatility * rnd;\n            if ( changePct > volatility) {\n                changePct -= (2*volatility);\n            }\n            startPrice = startPrice + startPrice * changePct;\n        }\n        return rval;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/stackedArea.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart\">\n    <svg></svg>\n</div>\n\n<script>\n\n    nv.addGraph({\n        generate: function() {\n            var n = 10, // number of layers\n                m = 200; // number of samples per layer\n\n            var data = stream_layers(n,m).map(function(data, i) {\n                return {\n                    key: 'Stream' + i,\n                    values: data\n                };\n            });\n\n            var width = nv.utils.windowSize().width;\n            var height = nv.utils.windowSize().height;\n\n            var chart = nv.models.stackedArea()\n                .width(width)\n                .height(height);\n\n            var svg = d3.select('#chart svg').datum(data);\n            svg.transition().duration(500).call(chart);\n            return chart;\n        },\n        callback: function(graph) {\n\n            graph.dispatch.on('tooltipShow', function(e) {\n                var offsetElement = document.getElementById(\"chart\"),\n                    left = e.pos[0] + offsetElement.offsetLeft,\n                    top = e.pos[1] + offsetElement.offsetTop,\n                    formatterY = d3.format(\",.2%\"),\n                    formatterX = function(d) {\n                        return   d3.time.format('%x')(new Date(d))\n                    };\n\n                var content = '<h3>' + e.series.key + '</h3>' +\n                    '<p>' +\n                    formatterY(graph.y()(e.point)) + ' at ' + formatterX(graph.x()(e.point)) +\n                    '</p>';\n\n                nv.tooltip.show([left, top], content);\n            });\n\n            graph.dispatch.on('tooltipHide', function(e) {\n                nv.tooltip.cleanup();\n            });\n\n            nv.utils.windowResize(function() {\n                var width = nv.utils.windowSize().width;\n                var height = nv.utils.windowSize().height;\n\n                graph.width(width).height(height);\n                d3.select('#chart svg').call(graph);\n            });\n        }\n    });\n\n    /* Inspired by Lee Byron's test data generator. */\n    function stream_layers(n, m, o) {\n        if (arguments.length < 3) o = 0;\n        function bump(a) {\n            var x = 1 / (.1 + Math.random()),\n                y = 2 * Math.random() - .5,\n                z = 10 / (.1 + Math.random());\n            for (var i = 0; i < m; i++) {\n                var w = (i / m - y) * z;\n                a[i] += x * Math.exp(-w * w);\n            }\n        }\n        return d3.range(n).map(function() {\n            var a = [], i;\n            for (i = 0; i < m; i++) a[i] = o + o * Math.random();\n            for (i = 0; i < 5; i++) bump(a);\n            return a.map(stream_index);\n        });\n    }\n\n    /* Another layer generator using gamma distributions. */\n    function stream_waves(n, m) {\n        return d3.range(n).map(function(i) {\n            return d3.range(m).map(function(j) {\n                var x = 20 * j / m - i / 3;\n                return 2 * x * Math.exp(-.5 * x);\n            }).map(stream_index);\n        });\n    }\n\n    function stream_index(d, i) {\n        return {x: i, y: Math.max(0, d)};\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/stackedAreaChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n<button onclick=\"expandLegend();\">Expand/Contract Legend</button>\n    <script>\n        var expandLegend = function() {\n            var exp = chart.legend.expanded();\n            chart.legend.expanded(!exp);\n            chart.update();\n        }\n    </script>\n<svg id=\"chart1\"></svg>\n\n<script>\n\n    var histcatexplong = [\n        {\n            \"key\" : \"Consumer Discretionary\" ,\n            \"values\" : [ [ 1138683600000 , 27.38478809681] , [ 1141102800000 , 27.371377218208] , [ 1143781200000 , 26.309915460827] , [ 1146369600000 , 26.425199957521] , [ 1149048000000 , 26.823411519395] , [ 1151640000000 , 23.850443591584] , [ 1154318400000 , 23.158355444054] , [ 1156996800000 , 22.998689393694] , [ 1159588800000 , 27.977128511299] , [ 1162270800000 , 29.073672469721] , [ 1164862800000 , 28.587640408904] , [ 1167541200000 , 22.788453687638] , [ 1170219600000 , 22.429199073597] , [ 1172638800000 , 22.324103271051] , [ 1175313600000 , 17.558388444186] , [ 1177905600000 , 16.769518096208] , [ 1180584000000 , 16.214738201302] , [ 1183176000000 , 18.729632971228] , [ 1185854400000 , 18.814523318848] , [ 1188532800000 , 19.789986451358] , [ 1191124800000 , 17.070049054933] , [ 1193803200000 , 16.121349575715] , [ 1196398800000 , 15.141659430091] , [ 1199077200000 , 17.175388025298] , [ 1201755600000 , 17.286592443521] , [ 1204261200000 , 16.323141626569] , [ 1206936000000 , 19.231263773952] , [ 1209528000000 , 18.446256391094] , [ 1212206400000 , 17.822632399764] , [ 1214798400000 , 15.539366475979] , [ 1217476800000 , 15.255131790216] , [ 1220155200000 , 15.660963922593] , [ 1222747200000 , 13.254482273697] , [ 1225425600000 , 11.920796202299] , [ 1228021200000 , 12.122809090925] , [ 1230699600000 , 15.691026271393] , [ 1233378000000 , 14.720881635107] , [ 1235797200000 , 15.387939360044] , [ 1238472000000 , 13.765436672229] , [ 1241064000000 , 14.6314458648] , [ 1243742400000 , 14.292446536221] , [ 1246334400000 , 16.170071367016] , [ 1249012800000 , 15.948135554337] , [ 1251691200000 , 16.612872685134] , [ 1254283200000 , 18.778338719091] , [ 1256961600000 , 16.75602606542] , [ 1259557200000 , 19.385804443147] , [ 1262235600000 , 22.950590240168] , [ 1264914000000 , 23.61159018141] , [ 1267333200000 , 25.708586989581] , [ 1270008000000 , 26.883915999885] , [ 1272600000000 , 25.893486687065] , [ 1275278400000 , 24.678914263176] , [ 1277870400000 , 25.937275793023] , [ 1280548800000 , 29.46138169384] , [ 1283227200000 , 27.357322961862] , [ 1285819200000 , 29.057235285673] , [ 1288497600000 , 28.549434189386] , [ 1291093200000 , 28.506352379723] , [ 1293771600000 , 29.449241421597] , [ 1296450000000 , 25.796838168807] , [ 1298869200000 , 28.740145449189] , [ 1301544000000 , 22.091744141872] , [ 1304136000000 , 25.079662545409] , [ 1306814400000 , 23.674906973064] , [ 1309406400000 , 23.41800274293] , [ 1312084800000 , 23.243644138871] , [ 1314763200000 , 31.591854066817] , [ 1317355200000 , 31.497112374114] , [ 1320033600000 , 26.672380820431] , [ 1322629200000 , 27.297080015495] , [ 1325307600000 , 20.174315530051] , [ 1327986000000 , 19.631084213899] , [ 1330491600000 , 20.366462219462] , [ 1333166400000 , 17.429019937289] , [ 1335758400000 , 16.75543633539] , [ 1338436800000 , 16.182906906042]]\n        } ,\n        {\n            \"key\" : \"Consumer Staples\" ,\n            \"values\" : [ [ 1138683600000 , 7.2800122043237] , [ 1141102800000 , 7.1187787503354] , [ 1143781200000 , 8.351887016482] , [ 1146369600000 , 8.4156698763993] , [ 1149048000000 , 8.1673298604231] , [ 1151640000000 , 5.5132447126042] , [ 1154318400000 , 6.1152537710599] , [ 1156996800000 , 6.076765091942] , [ 1159588800000 , 4.6304473798646] , [ 1162270800000 , 4.6301068469402] , [ 1164862800000 , 4.3466656309389] , [ 1167541200000 , 6.830104897003] , [ 1170219600000 , 7.241633040029] , [ 1172638800000 , 7.1432372054153] , [ 1175313600000 , 10.608942063374] , [ 1177905600000 , 10.914964549494] , [ 1180584000000 , 10.933223880565] , [ 1183176000000 , 8.3457524851265] , [ 1185854400000 , 8.1078413081882] , [ 1188532800000 , 8.2697185922474] , [ 1191124800000 , 8.4742436475968] , [ 1193803200000 , 8.4994601179319] , [ 1196398800000 , 8.7387319683243] , [ 1199077200000 , 6.8829183612895] , [ 1201755600000 , 6.984133637885] , [ 1204261200000 , 7.0860136043287] , [ 1206936000000 , 4.3961787956053] , [ 1209528000000 , 3.8699674365231] , [ 1212206400000 , 3.6928925238305] , [ 1214798400000 , 6.7571718894253] , [ 1217476800000 , 6.4367313362344] , [ 1220155200000 , 6.4048441521454] , [ 1222747200000 , 5.4643833239669] , [ 1225425600000 , 5.3150786833374] , [ 1228021200000 , 5.3011272612576] , [ 1230699600000 , 4.1203601430809] , [ 1233378000000 , 4.0881783200525] , [ 1235797200000 , 4.1928665957189] , [ 1238472000000 , 7.0249415663205] , [ 1241064000000 , 7.006530880769] , [ 1243742400000 , 6.994835633224] , [ 1246334400000 , 6.1220222336254] , [ 1249012800000 , 6.1177436137653] , [ 1251691200000 , 6.1413396231981] , [ 1254283200000 , 4.8046006145874] , [ 1256961600000 , 4.6647600660544] , [ 1259557200000 , 4.544865006255] , [ 1262235600000 , 6.0488249316539] , [ 1264914000000 , 6.3188669540206] , [ 1267333200000 , 6.5873958262306] , [ 1270008000000 , 6.2281189839578] , [ 1272600000000 , 5.8948915746059] , [ 1275278400000 , 5.5967320482214] , [ 1277870400000 , 0.99784432084837] , [ 1280548800000 , 1.0950794175359] , [ 1283227200000 , 0.94479734407491] , [ 1285819200000 , 1.222093988688] , [ 1288497600000 , 1.335093106856] , [ 1291093200000 , 1.3302565104985] , [ 1293771600000 , 1.340824670897] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 4.4583692315] , [ 1320033600000 , 3.6493043348059] , [ 1322629200000 , 3.8610064091761] , [ 1325307600000 , 5.5144800685202] , [ 1327986000000 , 5.1750695220792] , [ 1330491600000 , 5.6710066952691] , [ 1333166400000 , 8.5658461590953] , [ 1335758400000 , 8.6135447714243] , [ 1338436800000 , 8.0231460925212]]\n        } ,\n        {\n            \"key\" : \"Energy\" ,\n            \"values\" : [ [ 1138683600000 , 1.544303464167] , [ 1141102800000 , 1.4387289432421] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 1.328626801128] , [ 1154318400000 , 1.2874050802627] , [ 1156996800000 , 1.0872743105593] , [ 1159588800000 , 0.96042562635813] , [ 1162270800000 , 0.93139372870616] , [ 1164862800000 , 0.94432167305385] , [ 1167541200000 , 1.277750166208] , [ 1170219600000 , 1.2204893886811] , [ 1172638800000 , 1.207489123122] , [ 1175313600000 , 1.2490651414113] , [ 1177905600000 , 1.2593129913052] , [ 1180584000000 , 1.373329808388] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 1.4516108933695] , [ 1225425600000 , 1.1856025268225] , [ 1228021200000 , 1.3430470355439] , [ 1230699600000 , 2.2752595354509] , [ 1233378000000 , 2.4031560010523] , [ 1235797200000 , 2.0822430731926] , [ 1238472000000 , 1.5640902826938] , [ 1241064000000 , 1.5812873972356] , [ 1243742400000 , 1.9462448548894] , [ 1246334400000 , 2.9464870223957] , [ 1249012800000 , 3.0744699383222] , [ 1251691200000 , 2.9422304628446] , [ 1254283200000 , 2.7503075599999] , [ 1256961600000 , 2.6506701800427] , [ 1259557200000 , 2.8005425319977] , [ 1262235600000 , 2.6816184971185] , [ 1264914000000 , 2.681206271327] , [ 1267333200000 , 2.8195488011259] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 1.0687057346382] , [ 1280548800000 , 1.2539400544134] , [ 1283227200000 , 1.1862969445955] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 1.941972859484] , [ 1298869200000 , 2.1142247697552] , [ 1301544000000 , 2.3788590206824] , [ 1304136000000 , 2.5337302877545] , [ 1306814400000 , 2.3163370395199] , [ 1309406400000 , 2.0645451843195] , [ 1312084800000 , 2.1004446672411] , [ 1314763200000 , 3.6301875804303] , [ 1317355200000 , 2.454204664652] , [ 1320033600000 , 2.196082370894] , [ 1322629200000 , 2.3358418255202] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0.39001201038526] , [ 1335758400000 , 0.30945472725559] , [ 1338436800000 , 0.31062439305591]]\n        } ,\n        {\n            \"key\" : \"Financials\" ,\n            \"values\" : [ [ 1138683600000 , 13.356778764352] , [ 1141102800000 , 13.611196863271] , [ 1143781200000 , 6.895903006119] , [ 1146369600000 , 6.9939633271352] , [ 1149048000000 , 6.7241510257675] , [ 1151640000000 , 5.5611293669516] , [ 1154318400000 , 5.6086488714041] , [ 1156996800000 , 5.4962849907033] , [ 1159588800000 , 6.9193153169279] , [ 1162270800000 , 7.0016334389777] , [ 1164862800000 , 6.7865422443273] , [ 1167541200000 , 9.0006454225383] , [ 1170219600000 , 9.2233916171431] , [ 1172638800000 , 8.8929316009479] , [ 1175313600000 , 10.345937520404] , [ 1177905600000 , 10.075914677026] , [ 1180584000000 , 10.089006188111] , [ 1183176000000 , 10.598330295008] , [ 1185854400000 , 9.968954653301] , [ 1188532800000 , 9.7740580198146] , [ 1191124800000 , 10.558483060626] , [ 1193803200000 , 9.9314651823603] , [ 1196398800000 , 9.3997715873769] , [ 1199077200000 , 8.4086493387262] , [ 1201755600000 , 8.9698309085926] , [ 1204261200000 , 8.2778357995396] , [ 1206936000000 , 8.8585045600123] , [ 1209528000000 , 8.7013756413322] , [ 1212206400000 , 7.7933605469443] , [ 1214798400000 , 7.0236183483064] , [ 1217476800000 , 6.9873088186829] , [ 1220155200000 , 6.8031713070097] , [ 1222747200000 , 6.6869531315723] , [ 1225425600000 , 6.138256993963] , [ 1228021200000 , 5.6434994016354] , [ 1230699600000 , 5.495220262512] , [ 1233378000000 , 4.6885326869846] , [ 1235797200000 , 4.4524349883438] , [ 1238472000000 , 5.6766520778185] , [ 1241064000000 , 5.7675774480752] , [ 1243742400000 , 5.7882863168337] , [ 1246334400000 , 7.2666010034924] , [ 1249012800000 , 7.519182132226] , [ 1251691200000 , 7.849651451445] , [ 1254283200000 , 10.383992037985] , [ 1256961600000 , 9.0653691861818] , [ 1259557200000 , 9.6705248324159] , [ 1262235600000 , 10.856380561349] , [ 1264914000000 , 11.27452370892] , [ 1267333200000 , 11.754156529088] , [ 1270008000000 , 8.2870811422456] , [ 1272600000000 , 8.0210264360699] , [ 1275278400000 , 7.5375074474865] , [ 1277870400000 , 8.3419527338039] , [ 1280548800000 , 9.4197471818443] , [ 1283227200000 , 8.7321733185797] , [ 1285819200000 , 9.6627062648126] , [ 1288497600000 , 10.187962234549] , [ 1291093200000 , 9.8144201733476] , [ 1293771600000 , 10.275723361713] , [ 1296450000000 , 16.796066079353] , [ 1298869200000 , 17.543254984075] , [ 1301544000000 , 16.673660675084] , [ 1304136000000 , 17.963944353609] , [ 1306814400000 , 16.637740867211] , [ 1309406400000 , 15.84857094609] , [ 1312084800000 , 14.767303362182] , [ 1314763200000 , 24.778452182432] , [ 1317355200000 , 18.370353229999] , [ 1320033600000 , 15.2531374291] , [ 1322629200000 , 14.989600840649] , [ 1325307600000 , 16.052539160125] , [ 1327986000000 , 16.424390322793] , [ 1330491600000 , 17.884020741105] , [ 1333166400000 , 7.1424929577921] , [ 1335758400000 , 7.8076213051482] , [ 1338436800000 , 7.2462684949232]]\n        } ,\n        {\n            \"key\" : \"Health Care\" ,\n            \"values\" : [ [ 1138683600000 , 14.212410956029] , [ 1141102800000 , 13.973193618249] , [ 1143781200000 , 15.218233920665] , [ 1146369600000 , 14.38210972745] , [ 1149048000000 , 13.894310878491] , [ 1151640000000 , 15.593086090032] , [ 1154318400000 , 16.244839695188] , [ 1156996800000 , 16.017088850646] , [ 1159588800000 , 14.183951830055] , [ 1162270800000 , 14.148523245697] , [ 1164862800000 , 13.424326059972] , [ 1167541200000 , 12.974450435753] , [ 1170219600000 , 13.23247041802] , [ 1172638800000 , 13.318762655574] , [ 1175313600000 , 15.961407746104] , [ 1177905600000 , 16.287714639805] , [ 1180584000000 , 16.246590583889] , [ 1183176000000 , 17.564505594809] , [ 1185854400000 , 17.872725373165] , [ 1188532800000 , 18.018998508757] , [ 1191124800000 , 15.584518016603] , [ 1193803200000 , 15.480850647181] , [ 1196398800000 , 15.699120036984] , [ 1199077200000 , 19.184281817226] , [ 1201755600000 , 19.691226605207] , [ 1204261200000 , 18.982314051295] , [ 1206936000000 , 18.707820309008] , [ 1209528000000 , 17.459630929761] , [ 1212206400000 , 16.500616076782] , [ 1214798400000 , 18.086324003979] , [ 1217476800000 , 18.929464156258] , [ 1220155200000 , 18.233728682084] , [ 1222747200000 , 16.315776297325] , [ 1225425600000 , 14.63289219025] , [ 1228021200000 , 14.667835024478] , [ 1230699600000 , 13.946993947308] , [ 1233378000000 , 14.394304684397] , [ 1235797200000 , 13.724462792967] , [ 1238472000000 , 10.930879035806] , [ 1241064000000 , 9.8339915513708] , [ 1243742400000 , 10.053858541872] , [ 1246334400000 , 11.786998438287] , [ 1249012800000 , 11.780994901769] , [ 1251691200000 , 11.305889670276] , [ 1254283200000 , 10.918452290083] , [ 1256961600000 , 9.6811395055706] , [ 1259557200000 , 10.971529744038] , [ 1262235600000 , 13.330210480209] , [ 1264914000000 , 14.592637568961] , [ 1267333200000 , 14.605329141157] , [ 1270008000000 , 13.936853794037] , [ 1272600000000 , 12.189480759072] , [ 1275278400000 , 11.676151385046] , [ 1277870400000 , 13.058852800017] , [ 1280548800000 , 13.62891543203] , [ 1283227200000 , 13.811107569918] , [ 1285819200000 , 13.786494560787] , [ 1288497600000 , 14.04516285753] , [ 1291093200000 , 13.697412447288] , [ 1293771600000 , 13.677681376221] , [ 1296450000000 , 19.961511864531] , [ 1298869200000 , 21.049198298158] , [ 1301544000000 , 22.687631094008] , [ 1304136000000 , 25.469010617433] , [ 1306814400000 , 24.883799437121] , [ 1309406400000 , 24.203843814248] , [ 1312084800000 , 22.138760964038] , [ 1314763200000 , 16.034636966228] , [ 1317355200000 , 15.394958944556] , [ 1320033600000 , 12.625642461969] , [ 1322629200000 , 12.973735699739] , [ 1325307600000 , 15.786018336149] , [ 1327986000000 , 15.227368020134] , [ 1330491600000 , 15.899752650734] , [ 1333166400000 , 18.994731295388] , [ 1335758400000 , 18.450055817702] , [ 1338436800000 , 17.863719889669]]\n        } ,\n        {\n            \"key\" : \"Industrials\" ,\n            \"values\" : [ [ 1138683600000 , 7.1590087090398] , [ 1141102800000 , 7.1297210970108] , [ 1143781200000 , 5.5774588290586] , [ 1146369600000 , 5.4977254491156] , [ 1149048000000 , 5.5138153113634] , [ 1151640000000 , 4.3198084032122] , [ 1154318400000 , 3.9179295839125] , [ 1156996800000 , 3.8110093051479] , [ 1159588800000 , 5.5629020916939] , [ 1162270800000 , 5.7241673711336] , [ 1164862800000 , 5.4715049695004] , [ 1167541200000 , 4.9193763571618] , [ 1170219600000 , 5.136053947247] , [ 1172638800000 , 5.1327258759766] , [ 1175313600000 , 5.1888943925082] , [ 1177905600000 , 5.5191481293345] , [ 1180584000000 , 5.6093625614921] , [ 1183176000000 , 4.2706312987397] , [ 1185854400000 , 4.4453235132117] , [ 1188532800000 , 4.6228003109761] , [ 1191124800000 , 5.0645764756954] , [ 1193803200000 , 5.0723447230959] , [ 1196398800000 , 5.1457765818846] , [ 1199077200000 , 5.4067851597282] , [ 1201755600000 , 5.472241916816] , [ 1204261200000 , 5.3742740389688] , [ 1206936000000 , 6.251751933664] , [ 1209528000000 , 6.1406852153472] , [ 1212206400000 , 5.8164385627465] , [ 1214798400000 , 5.4255846656171] , [ 1217476800000 , 5.3738499417204] , [ 1220155200000 , 5.1815627753979] , [ 1222747200000 , 5.0305983235349] , [ 1225425600000 , 4.6823058607165] , [ 1228021200000 , 4.5941481589093] , [ 1230699600000 , 5.4669598474575] , [ 1233378000000 , 5.1249037357] , [ 1235797200000 , 4.3504421250742] , [ 1238472000000 , 4.6260881026002] , [ 1241064000000 , 5.0140402458946] , [ 1243742400000 , 4.7458462454774] , [ 1246334400000 , 6.0437019654564] , [ 1249012800000 , 6.4595216249754] , [ 1251691200000 , 6.6420468254155] , [ 1254283200000 , 5.8927271960913] , [ 1256961600000 , 5.4712108838003] , [ 1259557200000 , 6.1220254207747] , [ 1262235600000 , 5.5385935169255] , [ 1264914000000 , 5.7383377612639] , [ 1267333200000 , 6.1715976730415] , [ 1270008000000 , 4.0102262681174] , [ 1272600000000 , 3.769389679692] , [ 1275278400000 , 3.5301571031152] , [ 1277870400000 , 2.7660252652526] , [ 1280548800000 , 3.1409983385775] , [ 1283227200000 , 3.0528024863055] , [ 1285819200000 , 4.3126123157971] , [ 1288497600000 , 4.594654041683] , [ 1291093200000 , 4.5424126126793] , [ 1293771600000 , 4.7790043987302] , [ 1296450000000 , 7.4969154058289] , [ 1298869200000 , 7.9424751557821] , [ 1301544000000 , 7.1560736250547] , [ 1304136000000 , 7.9478117337855] , [ 1306814400000 , 7.4109214848895] , [ 1309406400000 , 7.5966457641101] , [ 1312084800000 , 7.165754444071] , [ 1314763200000 , 5.4816702524302] , [ 1317355200000 , 4.9893656089584] , [ 1320033600000 , 4.498385105327] , [ 1322629200000 , 4.6776090358151] , [ 1325307600000 , 8.1350814368063] , [ 1327986000000 , 8.0732769990652] , [ 1330491600000 , 8.5602340387277] , [ 1333166400000 , 5.1293714074325] , [ 1335758400000 , 5.2586794619016] , [ 1338436800000 , 5.1100853569977]]\n        } ,\n        {\n            \"key\" : \"Information Technology\" ,\n            \"values\" : [ [ 1138683600000 , 13.242301508051] , [ 1141102800000 , 12.863536342042] , [ 1143781200000 , 21.034044171629] , [ 1146369600000 , 21.419084618803] , [ 1149048000000 , 21.142678863691] , [ 1151640000000 , 26.568489677529] , [ 1154318400000 , 24.839144939905] , [ 1156996800000 , 25.456187462167] , [ 1159588800000 , 26.350164502826] , [ 1162270800000 , 26.47833320519] , [ 1164862800000 , 26.425979547847] , [ 1167541200000 , 28.191461582256] , [ 1170219600000 , 28.930307448808] , [ 1172638800000 , 29.521413891117] , [ 1175313600000 , 28.188285966466] , [ 1177905600000 , 27.704619625832] , [ 1180584000000 , 27.490862424829] , [ 1183176000000 , 28.770679721286] , [ 1185854400000 , 29.060480671449] , [ 1188532800000 , 28.240998844973] , [ 1191124800000 , 33.004893194127] , [ 1193803200000 , 34.075180359928] , [ 1196398800000 , 32.548560664833] , [ 1199077200000 , 30.629727432728] , [ 1201755600000 , 28.642858788159] , [ 1204261200000 , 27.973575227842] , [ 1206936000000 , 27.393351882726] , [ 1209528000000 , 28.476095288523] , [ 1212206400000 , 29.29667866426] , [ 1214798400000 , 29.222333802896] , [ 1217476800000 , 28.092966093843] , [ 1220155200000 , 28.107159262922] , [ 1222747200000 , 25.482974832098] , [ 1225425600000 , 21.208115993834] , [ 1228021200000 , 20.295043095268] , [ 1230699600000 , 15.925754618401] , [ 1233378000000 , 17.162864628346] , [ 1235797200000 , 17.084345773174] , [ 1238472000000 , 22.246007102281] , [ 1241064000000 , 24.530543998509] , [ 1243742400000 , 25.084184918242] , [ 1246334400000 , 16.606166527358] , [ 1249012800000 , 17.239620011628] , [ 1251691200000 , 17.336739127379] , [ 1254283200000 , 25.478492475753] , [ 1256961600000 , 23.017152085245] , [ 1259557200000 , 25.617745423683] , [ 1262235600000 , 24.061133998642] , [ 1264914000000 , 23.223933318644] , [ 1267333200000 , 24.425887263937] , [ 1270008000000 , 35.501471156693] , [ 1272600000000 , 33.775013878676] , [ 1275278400000 , 30.417993630285] , [ 1277870400000 , 30.023598978467] , [ 1280548800000 , 33.327519522436] , [ 1283227200000 , 31.963388450371] , [ 1285819200000 , 30.498967232092] , [ 1288497600000 , 32.403696817912] , [ 1291093200000 , 31.47736071922] , [ 1293771600000 , 31.53259666241] , [ 1296450000000 , 41.760282761548] , [ 1298869200000 , 45.605771243237] , [ 1301544000000 , 39.986557966215] , [ 1304136000000 , 43.846330510051] , [ 1306814400000 , 39.857316881857] , [ 1309406400000 , 37.675127768208] , [ 1312084800000 , 35.775077970313] , [ 1314763200000 , 48.631009702577] , [ 1317355200000 , 42.830831754505] , [ 1320033600000 , 35.611502589362] , [ 1322629200000 , 35.320136981738] , [ 1325307600000 , 31.564136901516] , [ 1327986000000 , 32.074407502433] , [ 1330491600000 , 35.053013769976] , [ 1333166400000 , 26.434568573937] , [ 1335758400000 , 25.305617871002] , [ 1338436800000 , 24.520919418236]]\n        } ,\n        {\n            \"key\" : \"Materials\" ,\n            \"values\" : [ [ 1138683600000 , 5.5806167415681] , [ 1141102800000 , 5.4539047069985] , [ 1143781200000 , 7.6728842432362] , [ 1146369600000 , 7.719946716654] , [ 1149048000000 , 8.0144619912942] , [ 1151640000000 , 7.942223133434] , [ 1154318400000 , 8.3998279827444] , [ 1156996800000 , 8.532324572605] , [ 1159588800000 , 4.7324285199763] , [ 1162270800000 , 4.7402397487697] , [ 1164862800000 , 4.9042069355168] , [ 1167541200000 , 5.9583963430882] , [ 1170219600000 , 6.3693899239171] , [ 1172638800000 , 6.261153903813] , [ 1175313600000 , 5.3443942184584] , [ 1177905600000 , 5.4932111235361] , [ 1180584000000 , 5.5747393101109] , [ 1183176000000 , 5.3833633060013] , [ 1185854400000 , 5.5125898831832] , [ 1188532800000 , 5.8116112661327] , [ 1191124800000 , 4.3962296939996] , [ 1193803200000 , 4.6967663605521] , [ 1196398800000 , 4.7963004350914] , [ 1199077200000 , 4.1817985183351] , [ 1201755600000 , 4.3797643870182] , [ 1204261200000 , 4.6966642197965] , [ 1206936000000 , 4.3609995132565] , [ 1209528000000 , 4.4736290996496] , [ 1212206400000 , 4.3749762738128] , [ 1214798400000 , 3.3274661194507] , [ 1217476800000 , 3.0316184691337] , [ 1220155200000 , 2.5718140204728] , [ 1222747200000 , 2.7034994044603] , [ 1225425600000 , 2.2033786591364] , [ 1228021200000 , 1.9850621240805] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0.44495950017788] , [ 1256961600000 , 0.33945469262483] , [ 1259557200000 , 0.38348269455195] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0.52216435716176] , [ 1298869200000 , 0.59275786698454] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Telecommunication Services\" ,\n            \"values\" : [ [ 1138683600000 , 3.7056975170243] , [ 1141102800000 , 3.7561118692318] , [ 1143781200000 , 2.861913700854] , [ 1146369600000 , 2.9933744103381] , [ 1149048000000 , 2.7127537218463] , [ 1151640000000 , 3.1195497076283] , [ 1154318400000 , 3.4066964004508] , [ 1156996800000 , 3.3754571113569] , [ 1159588800000 , 2.2965579982924] , [ 1162270800000 , 2.4486818633018] , [ 1164862800000 , 2.4002308848517] , [ 1167541200000 , 1.9649579750349] , [ 1170219600000 , 1.9385263638056] , [ 1172638800000 , 1.9128975336387] , [ 1175313600000 , 2.3412869836298] , [ 1177905600000 , 2.4337870351445] , [ 1180584000000 , 2.62179703171] , [ 1183176000000 , 3.2642864957929] , [ 1185854400000 , 3.3200396223709] , [ 1188532800000 , 3.3934212707572] , [ 1191124800000 , 4.2822327088179] , [ 1193803200000 , 4.1474964228541] , [ 1196398800000 , 4.1477082879801] , [ 1199077200000 , 5.2947122916128] , [ 1201755600000 , 5.2919843508028] , [ 1204261200000 , 5.1989783050309] , [ 1206936000000 , 3.5603057673513] , [ 1209528000000 , 3.3009087690692] , [ 1212206400000 , 3.1784852603792] , [ 1214798400000 , 4.5889503538868] , [ 1217476800000 , 4.401779617494] , [ 1220155200000 , 4.2208301828278] , [ 1222747200000 , 3.89396671475] , [ 1225425600000 , 3.0423832241354] , [ 1228021200000 , 3.135520611578] , [ 1230699600000 , 1.9631418164089] , [ 1233378000000 , 1.8963543874958] , [ 1235797200000 , 1.8266636017025] , [ 1238472000000 , 0.93136635895188] , [ 1241064000000 , 0.92737801918888] , [ 1243742400000 , 0.97591889805002] , [ 1246334400000 , 2.6841193805515] , [ 1249012800000 , 2.5664341140531] , [ 1251691200000 , 2.3887523699873] , [ 1254283200000 , 1.1737801663681] , [ 1256961600000 , 1.0953582317281] , [ 1259557200000 , 1.2495674976653] , [ 1262235600000 , 0.36607452464754] , [ 1264914000000 , 0.3548719047291] , [ 1267333200000 , 0.36769242398939] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0.85450741275337] , [ 1288497600000 , 0.91360317921637] , [ 1291093200000 , 0.89647678692269] , [ 1293771600000 , 0.87800687192639] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0.43668720882994] , [ 1304136000000 , 0.4756523602692] , [ 1306814400000 , 0.46947368328469] , [ 1309406400000 , 0.45138896152316] , [ 1312084800000 , 0.43828726648117] , [ 1314763200000 , 2.0820861395316] , [ 1317355200000 , 0.9364411075395] , [ 1320033600000 , 0.60583907839773] , [ 1322629200000 , 0.61096950747437] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Utilities\" ,\n            \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 0] , [ 1225425600000 , 0] , [ 1228021200000 , 0] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0] , [ 1256961600000 , 0] , [ 1259557200000 , 0] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        }\n    ];\n\n    var colors = d3.scale.category20();\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.stackedAreaChart()\n            .useInteractiveGuideline(true)\n            .x(function(d) { return d[0] })\n            .y(function(d) { return d[1] })\n            .controlLabels({stacked: \"Stacked\"})\n            .duration(300);\n\n        chart.xAxis.tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n        chart.yAxis.tickFormat(d3.format(',.4f'));\n\n        chart.legend.vers('furious');\n\n        d3.select('#chart1')\n            .datum(histcatexplong)\n            .transition().duration(1000)\n            .call(chart)\n            .each('start', function() {\n                setTimeout(function() {\n                    d3.selectAll('#chart1 *').each(function() {\n                        if(this.__transition__)\n                            this.__transition__.duration = 1;\n                    })\n                }, 0)\n            });\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/stackedAreaWithFocusChart.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n<button onclick=\"expandLegend();\">Expand/Contract Legend</button>\n    <script>\n        var expandLegend = function() {\n            var exp = chart.legend.expanded();\n            chart.legend.expanded(!exp);\n            chart.update();\n        }\n    </script>\n<svg id=\"chart1\"></svg>\n\n<script>\n\n    var histcatexplong = [\n        {\n            \"key\" : \"Consumer Discretionary\" ,\n            \"values\" : [ [ 1138683600000 , 27.38478809681] , [ 1141102800000 , 27.371377218208] , [ 1143781200000 , 26.309915460827] , [ 1146369600000 , 26.425199957521] , [ 1149048000000 , 26.823411519395] , [ 1151640000000 , 23.850443591584] , [ 1154318400000 , 23.158355444054] , [ 1156996800000 , 22.998689393694] , [ 1159588800000 , 27.977128511299] , [ 1162270800000 , 29.073672469721] , [ 1164862800000 , 28.587640408904] , [ 1167541200000 , 22.788453687638] , [ 1170219600000 , 22.429199073597] , [ 1172638800000 , 22.324103271051] , [ 1175313600000 , 17.558388444186] , [ 1177905600000 , 16.769518096208] , [ 1180584000000 , 16.214738201302] , [ 1183176000000 , 18.729632971228] , [ 1185854400000 , 18.814523318848] , [ 1188532800000 , 19.789986451358] , [ 1191124800000 , 17.070049054933] , [ 1193803200000 , 16.121349575715] , [ 1196398800000 , 15.141659430091] , [ 1199077200000 , 17.175388025298] , [ 1201755600000 , 17.286592443521] , [ 1204261200000 , 16.323141626569] , [ 1206936000000 , 19.231263773952] , [ 1209528000000 , 18.446256391094] , [ 1212206400000 , 17.822632399764] , [ 1214798400000 , 15.539366475979] , [ 1217476800000 , 15.255131790216] , [ 1220155200000 , 15.660963922593] , [ 1222747200000 , 13.254482273697] , [ 1225425600000 , 11.920796202299] , [ 1228021200000 , 12.122809090925] , [ 1230699600000 , 15.691026271393] , [ 1233378000000 , 14.720881635107] , [ 1235797200000 , 15.387939360044] , [ 1238472000000 , 13.765436672229] , [ 1241064000000 , 14.6314458648] , [ 1243742400000 , 14.292446536221] , [ 1246334400000 , 16.170071367016] , [ 1249012800000 , 15.948135554337] , [ 1251691200000 , 16.612872685134] , [ 1254283200000 , 18.778338719091] , [ 1256961600000 , 16.75602606542] , [ 1259557200000 , 19.385804443147] , [ 1262235600000 , 22.950590240168] , [ 1264914000000 , 23.61159018141] , [ 1267333200000 , 25.708586989581] , [ 1270008000000 , 26.883915999885] , [ 1272600000000 , 25.893486687065] , [ 1275278400000 , 24.678914263176] , [ 1277870400000 , 25.937275793023] , [ 1280548800000 , 29.46138169384] , [ 1283227200000 , 27.357322961862] , [ 1285819200000 , 29.057235285673] , [ 1288497600000 , 28.549434189386] , [ 1291093200000 , 28.506352379723] , [ 1293771600000 , 29.449241421597] , [ 1296450000000 , 25.796838168807] , [ 1298869200000 , 28.740145449189] , [ 1301544000000 , 22.091744141872] , [ 1304136000000 , 25.079662545409] , [ 1306814400000 , 23.674906973064] , [ 1309406400000 , 23.41800274293] , [ 1312084800000 , 23.243644138871] , [ 1314763200000 , 31.591854066817] , [ 1317355200000 , 31.497112374114] , [ 1320033600000 , 26.672380820431] , [ 1322629200000 , 27.297080015495] , [ 1325307600000 , 20.174315530051] , [ 1327986000000 , 19.631084213899] , [ 1330491600000 , 20.366462219462] , [ 1333166400000 , 17.429019937289] , [ 1335758400000 , 16.75543633539] , [ 1338436800000 , 16.182906906042]]\n        } ,\n        {\n            \"key\" : \"Consumer Staples\" ,\n            \"values\" : [ [ 1138683600000 , 7.2800122043237] , [ 1141102800000 , 7.1187787503354] , [ 1143781200000 , 8.351887016482] , [ 1146369600000 , 8.4156698763993] , [ 1149048000000 , 8.1673298604231] , [ 1151640000000 , 5.5132447126042] , [ 1154318400000 , 6.1152537710599] , [ 1156996800000 , 6.076765091942] , [ 1159588800000 , 4.6304473798646] , [ 1162270800000 , 4.6301068469402] , [ 1164862800000 , 4.3466656309389] , [ 1167541200000 , 6.830104897003] , [ 1170219600000 , 7.241633040029] , [ 1172638800000 , 7.1432372054153] , [ 1175313600000 , 10.608942063374] , [ 1177905600000 , 10.914964549494] , [ 1180584000000 , 10.933223880565] , [ 1183176000000 , 8.3457524851265] , [ 1185854400000 , 8.1078413081882] , [ 1188532800000 , 8.2697185922474] , [ 1191124800000 , 8.4742436475968] , [ 1193803200000 , 8.4994601179319] , [ 1196398800000 , 8.7387319683243] , [ 1199077200000 , 6.8829183612895] , [ 1201755600000 , 6.984133637885] , [ 1204261200000 , 7.0860136043287] , [ 1206936000000 , 4.3961787956053] , [ 1209528000000 , 3.8699674365231] , [ 1212206400000 , 3.6928925238305] , [ 1214798400000 , 6.7571718894253] , [ 1217476800000 , 6.4367313362344] , [ 1220155200000 , 6.4048441521454] , [ 1222747200000 , 5.4643833239669] , [ 1225425600000 , 5.3150786833374] , [ 1228021200000 , 5.3011272612576] , [ 1230699600000 , 4.1203601430809] , [ 1233378000000 , 4.0881783200525] , [ 1235797200000 , 4.1928665957189] , [ 1238472000000 , 7.0249415663205] , [ 1241064000000 , 7.006530880769] , [ 1243742400000 , 6.994835633224] , [ 1246334400000 , 6.1220222336254] , [ 1249012800000 , 6.1177436137653] , [ 1251691200000 , 6.1413396231981] , [ 1254283200000 , 4.8046006145874] , [ 1256961600000 , 4.6647600660544] , [ 1259557200000 , 4.544865006255] , [ 1262235600000 , 6.0488249316539] , [ 1264914000000 , 6.3188669540206] , [ 1267333200000 , 6.5873958262306] , [ 1270008000000 , 6.2281189839578] , [ 1272600000000 , 5.8948915746059] , [ 1275278400000 , 5.5967320482214] , [ 1277870400000 , 0.99784432084837] , [ 1280548800000 , 1.0950794175359] , [ 1283227200000 , 0.94479734407491] , [ 1285819200000 , 1.222093988688] , [ 1288497600000 , 1.335093106856] , [ 1291093200000 , 1.3302565104985] , [ 1293771600000 , 1.340824670897] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 4.4583692315] , [ 1320033600000 , 3.6493043348059] , [ 1322629200000 , 3.8610064091761] , [ 1325307600000 , 5.5144800685202] , [ 1327986000000 , 5.1750695220792] , [ 1330491600000 , 5.6710066952691] , [ 1333166400000 , 8.5658461590953] , [ 1335758400000 , 8.6135447714243] , [ 1338436800000 , 8.0231460925212]]\n        } ,\n        {\n            \"key\" : \"Energy\" ,\n            \"values\" : [ [ 1138683600000 , 1.544303464167] , [ 1141102800000 , 1.4387289432421] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 1.328626801128] , [ 1154318400000 , 1.2874050802627] , [ 1156996800000 , 1.0872743105593] , [ 1159588800000 , 0.96042562635813] , [ 1162270800000 , 0.93139372870616] , [ 1164862800000 , 0.94432167305385] , [ 1167541200000 , 1.277750166208] , [ 1170219600000 , 1.2204893886811] , [ 1172638800000 , 1.207489123122] , [ 1175313600000 , 1.2490651414113] , [ 1177905600000 , 1.2593129913052] , [ 1180584000000 , 1.373329808388] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 1.4516108933695] , [ 1225425600000 , 1.1856025268225] , [ 1228021200000 , 1.3430470355439] , [ 1230699600000 , 2.2752595354509] , [ 1233378000000 , 2.4031560010523] , [ 1235797200000 , 2.0822430731926] , [ 1238472000000 , 1.5640902826938] , [ 1241064000000 , 1.5812873972356] , [ 1243742400000 , 1.9462448548894] , [ 1246334400000 , 2.9464870223957] , [ 1249012800000 , 3.0744699383222] , [ 1251691200000 , 2.9422304628446] , [ 1254283200000 , 2.7503075599999] , [ 1256961600000 , 2.6506701800427] , [ 1259557200000 , 2.8005425319977] , [ 1262235600000 , 2.6816184971185] , [ 1264914000000 , 2.681206271327] , [ 1267333200000 , 2.8195488011259] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 1.0687057346382] , [ 1280548800000 , 1.2539400544134] , [ 1283227200000 , 1.1862969445955] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 1.941972859484] , [ 1298869200000 , 2.1142247697552] , [ 1301544000000 , 2.3788590206824] , [ 1304136000000 , 2.5337302877545] , [ 1306814400000 , 2.3163370395199] , [ 1309406400000 , 2.0645451843195] , [ 1312084800000 , 2.1004446672411] , [ 1314763200000 , 3.6301875804303] , [ 1317355200000 , 2.454204664652] , [ 1320033600000 , 2.196082370894] , [ 1322629200000 , 2.3358418255202] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0.39001201038526] , [ 1335758400000 , 0.30945472725559] , [ 1338436800000 , 0.31062439305591]]\n        } ,\n        {\n            \"key\" : \"Financials\" ,\n            \"values\" : [ [ 1138683600000 , 13.356778764352] , [ 1141102800000 , 13.611196863271] , [ 1143781200000 , 6.895903006119] , [ 1146369600000 , 6.9939633271352] , [ 1149048000000 , 6.7241510257675] , [ 1151640000000 , 5.5611293669516] , [ 1154318400000 , 5.6086488714041] , [ 1156996800000 , 5.4962849907033] , [ 1159588800000 , 6.9193153169279] , [ 1162270800000 , 7.0016334389777] , [ 1164862800000 , 6.7865422443273] , [ 1167541200000 , 9.0006454225383] , [ 1170219600000 , 9.2233916171431] , [ 1172638800000 , 8.8929316009479] , [ 1175313600000 , 10.345937520404] , [ 1177905600000 , 10.075914677026] , [ 1180584000000 , 10.089006188111] , [ 1183176000000 , 10.598330295008] , [ 1185854400000 , 9.968954653301] , [ 1188532800000 , 9.7740580198146] , [ 1191124800000 , 10.558483060626] , [ 1193803200000 , 9.9314651823603] , [ 1196398800000 , 9.3997715873769] , [ 1199077200000 , 8.4086493387262] , [ 1201755600000 , 8.9698309085926] , [ 1204261200000 , 8.2778357995396] , [ 1206936000000 , 8.8585045600123] , [ 1209528000000 , 8.7013756413322] , [ 1212206400000 , 7.7933605469443] , [ 1214798400000 , 7.0236183483064] , [ 1217476800000 , 6.9873088186829] , [ 1220155200000 , 6.8031713070097] , [ 1222747200000 , 6.6869531315723] , [ 1225425600000 , 6.138256993963] , [ 1228021200000 , 5.6434994016354] , [ 1230699600000 , 5.495220262512] , [ 1233378000000 , 4.6885326869846] , [ 1235797200000 , 4.4524349883438] , [ 1238472000000 , 5.6766520778185] , [ 1241064000000 , 5.7675774480752] , [ 1243742400000 , 5.7882863168337] , [ 1246334400000 , 7.2666010034924] , [ 1249012800000 , 7.519182132226] , [ 1251691200000 , 7.849651451445] , [ 1254283200000 , 10.383992037985] , [ 1256961600000 , 9.0653691861818] , [ 1259557200000 , 9.6705248324159] , [ 1262235600000 , 10.856380561349] , [ 1264914000000 , 11.27452370892] , [ 1267333200000 , 11.754156529088] , [ 1270008000000 , 8.2870811422456] , [ 1272600000000 , 8.0210264360699] , [ 1275278400000 , 7.5375074474865] , [ 1277870400000 , 8.3419527338039] , [ 1280548800000 , 9.4197471818443] , [ 1283227200000 , 8.7321733185797] , [ 1285819200000 , 9.6627062648126] , [ 1288497600000 , 10.187962234549] , [ 1291093200000 , 9.8144201733476] , [ 1293771600000 , 10.275723361713] , [ 1296450000000 , 16.796066079353] , [ 1298869200000 , 17.543254984075] , [ 1301544000000 , 16.673660675084] , [ 1304136000000 , 17.963944353609] , [ 1306814400000 , 16.637740867211] , [ 1309406400000 , 15.84857094609] , [ 1312084800000 , 14.767303362182] , [ 1314763200000 , 24.778452182432] , [ 1317355200000 , 18.370353229999] , [ 1320033600000 , 15.2531374291] , [ 1322629200000 , 14.989600840649] , [ 1325307600000 , 16.052539160125] , [ 1327986000000 , 16.424390322793] , [ 1330491600000 , 17.884020741105] , [ 1333166400000 , 7.1424929577921] , [ 1335758400000 , 7.8076213051482] , [ 1338436800000 , 7.2462684949232]]\n        } ,\n        {\n            \"key\" : \"Health Care\" ,\n            \"values\" : [ [ 1138683600000 , 14.212410956029] , [ 1141102800000 , 13.973193618249] , [ 1143781200000 , 15.218233920665] , [ 1146369600000 , 14.38210972745] , [ 1149048000000 , 13.894310878491] , [ 1151640000000 , 15.593086090032] , [ 1154318400000 , 16.244839695188] , [ 1156996800000 , 16.017088850646] , [ 1159588800000 , 14.183951830055] , [ 1162270800000 , 14.148523245697] , [ 1164862800000 , 13.424326059972] , [ 1167541200000 , 12.974450435753] , [ 1170219600000 , 13.23247041802] , [ 1172638800000 , 13.318762655574] , [ 1175313600000 , 15.961407746104] , [ 1177905600000 , 16.287714639805] , [ 1180584000000 , 16.246590583889] , [ 1183176000000 , 17.564505594809] , [ 1185854400000 , 17.872725373165] , [ 1188532800000 , 18.018998508757] , [ 1191124800000 , 15.584518016603] , [ 1193803200000 , 15.480850647181] , [ 1196398800000 , 15.699120036984] , [ 1199077200000 , 19.184281817226] , [ 1201755600000 , 19.691226605207] , [ 1204261200000 , 18.982314051295] , [ 1206936000000 , 18.707820309008] , [ 1209528000000 , 17.459630929761] , [ 1212206400000 , 16.500616076782] , [ 1214798400000 , 18.086324003979] , [ 1217476800000 , 18.929464156258] , [ 1220155200000 , 18.233728682084] , [ 1222747200000 , 16.315776297325] , [ 1225425600000 , 14.63289219025] , [ 1228021200000 , 14.667835024478] , [ 1230699600000 , 13.946993947308] , [ 1233378000000 , 14.394304684397] , [ 1235797200000 , 13.724462792967] , [ 1238472000000 , 10.930879035806] , [ 1241064000000 , 9.8339915513708] , [ 1243742400000 , 10.053858541872] , [ 1246334400000 , 11.786998438287] , [ 1249012800000 , 11.780994901769] , [ 1251691200000 , 11.305889670276] , [ 1254283200000 , 10.918452290083] , [ 1256961600000 , 9.6811395055706] , [ 1259557200000 , 10.971529744038] , [ 1262235600000 , 13.330210480209] , [ 1264914000000 , 14.592637568961] , [ 1267333200000 , 14.605329141157] , [ 1270008000000 , 13.936853794037] , [ 1272600000000 , 12.189480759072] , [ 1275278400000 , 11.676151385046] , [ 1277870400000 , 13.058852800017] , [ 1280548800000 , 13.62891543203] , [ 1283227200000 , 13.811107569918] , [ 1285819200000 , 13.786494560787] , [ 1288497600000 , 14.04516285753] , [ 1291093200000 , 13.697412447288] , [ 1293771600000 , 13.677681376221] , [ 1296450000000 , 19.961511864531] , [ 1298869200000 , 21.049198298158] , [ 1301544000000 , 22.687631094008] , [ 1304136000000 , 25.469010617433] , [ 1306814400000 , 24.883799437121] , [ 1309406400000 , 24.203843814248] , [ 1312084800000 , 22.138760964038] , [ 1314763200000 , 16.034636966228] , [ 1317355200000 , 15.394958944556] , [ 1320033600000 , 12.625642461969] , [ 1322629200000 , 12.973735699739] , [ 1325307600000 , 15.786018336149] , [ 1327986000000 , 15.227368020134] , [ 1330491600000 , 15.899752650734] , [ 1333166400000 , 18.994731295388] , [ 1335758400000 , 18.450055817702] , [ 1338436800000 , 17.863719889669]]\n        } ,\n        {\n            \"key\" : \"Industrials\" ,\n            \"values\" : [ [ 1138683600000 , 7.1590087090398] , [ 1141102800000 , 7.1297210970108] , [ 1143781200000 , 5.5774588290586] , [ 1146369600000 , 5.4977254491156] , [ 1149048000000 , 5.5138153113634] , [ 1151640000000 , 4.3198084032122] , [ 1154318400000 , 3.9179295839125] , [ 1156996800000 , 3.8110093051479] , [ 1159588800000 , 5.5629020916939] , [ 1162270800000 , 5.7241673711336] , [ 1164862800000 , 5.4715049695004] , [ 1167541200000 , 4.9193763571618] , [ 1170219600000 , 5.136053947247] , [ 1172638800000 , 5.1327258759766] , [ 1175313600000 , 5.1888943925082] , [ 1177905600000 , 5.5191481293345] , [ 1180584000000 , 5.6093625614921] , [ 1183176000000 , 4.2706312987397] , [ 1185854400000 , 4.4453235132117] , [ 1188532800000 , 4.6228003109761] , [ 1191124800000 , 5.0645764756954] , [ 1193803200000 , 5.0723447230959] , [ 1196398800000 , 5.1457765818846] , [ 1199077200000 , 5.4067851597282] , [ 1201755600000 , 5.472241916816] , [ 1204261200000 , 5.3742740389688] , [ 1206936000000 , 6.251751933664] , [ 1209528000000 , 6.1406852153472] , [ 1212206400000 , 5.8164385627465] , [ 1214798400000 , 5.4255846656171] , [ 1217476800000 , 5.3738499417204] , [ 1220155200000 , 5.1815627753979] , [ 1222747200000 , 5.0305983235349] , [ 1225425600000 , 4.6823058607165] , [ 1228021200000 , 4.5941481589093] , [ 1230699600000 , 5.4669598474575] , [ 1233378000000 , 5.1249037357] , [ 1235797200000 , 4.3504421250742] , [ 1238472000000 , 4.6260881026002] , [ 1241064000000 , 5.0140402458946] , [ 1243742400000 , 4.7458462454774] , [ 1246334400000 , 6.0437019654564] , [ 1249012800000 , 6.4595216249754] , [ 1251691200000 , 6.6420468254155] , [ 1254283200000 , 5.8927271960913] , [ 1256961600000 , 5.4712108838003] , [ 1259557200000 , 6.1220254207747] , [ 1262235600000 , 5.5385935169255] , [ 1264914000000 , 5.7383377612639] , [ 1267333200000 , 6.1715976730415] , [ 1270008000000 , 4.0102262681174] , [ 1272600000000 , 3.769389679692] , [ 1275278400000 , 3.5301571031152] , [ 1277870400000 , 2.7660252652526] , [ 1280548800000 , 3.1409983385775] , [ 1283227200000 , 3.0528024863055] , [ 1285819200000 , 4.3126123157971] , [ 1288497600000 , 4.594654041683] , [ 1291093200000 , 4.5424126126793] , [ 1293771600000 , 4.7790043987302] , [ 1296450000000 , 7.4969154058289] , [ 1298869200000 , 7.9424751557821] , [ 1301544000000 , 7.1560736250547] , [ 1304136000000 , 7.9478117337855] , [ 1306814400000 , 7.4109214848895] , [ 1309406400000 , 7.5966457641101] , [ 1312084800000 , 7.165754444071] , [ 1314763200000 , 5.4816702524302] , [ 1317355200000 , 4.9893656089584] , [ 1320033600000 , 4.498385105327] , [ 1322629200000 , 4.6776090358151] , [ 1325307600000 , 8.1350814368063] , [ 1327986000000 , 8.0732769990652] , [ 1330491600000 , 8.5602340387277] , [ 1333166400000 , 5.1293714074325] , [ 1335758400000 , 5.2586794619016] , [ 1338436800000 , 5.1100853569977]]\n        } ,\n        {\n            \"key\" : \"Information Technology\" ,\n            \"values\" : [ [ 1138683600000 , 13.242301508051] , [ 1141102800000 , 12.863536342042] , [ 1143781200000 , 21.034044171629] , [ 1146369600000 , 21.419084618803] , [ 1149048000000 , 21.142678863691] , [ 1151640000000 , 26.568489677529] , [ 1154318400000 , 24.839144939905] , [ 1156996800000 , 25.456187462167] , [ 1159588800000 , 26.350164502826] , [ 1162270800000 , 26.47833320519] , [ 1164862800000 , 26.425979547847] , [ 1167541200000 , 28.191461582256] , [ 1170219600000 , 28.930307448808] , [ 1172638800000 , 29.521413891117] , [ 1175313600000 , 28.188285966466] , [ 1177905600000 , 27.704619625832] , [ 1180584000000 , 27.490862424829] , [ 1183176000000 , 28.770679721286] , [ 1185854400000 , 29.060480671449] , [ 1188532800000 , 28.240998844973] , [ 1191124800000 , 33.004893194127] , [ 1193803200000 , 34.075180359928] , [ 1196398800000 , 32.548560664833] , [ 1199077200000 , 30.629727432728] , [ 1201755600000 , 28.642858788159] , [ 1204261200000 , 27.973575227842] , [ 1206936000000 , 27.393351882726] , [ 1209528000000 , 28.476095288523] , [ 1212206400000 , 29.29667866426] , [ 1214798400000 , 29.222333802896] , [ 1217476800000 , 28.092966093843] , [ 1220155200000 , 28.107159262922] , [ 1222747200000 , 25.482974832098] , [ 1225425600000 , 21.208115993834] , [ 1228021200000 , 20.295043095268] , [ 1230699600000 , 15.925754618401] , [ 1233378000000 , 17.162864628346] , [ 1235797200000 , 17.084345773174] , [ 1238472000000 , 22.246007102281] , [ 1241064000000 , 24.530543998509] , [ 1243742400000 , 25.084184918242] , [ 1246334400000 , 16.606166527358] , [ 1249012800000 , 17.239620011628] , [ 1251691200000 , 17.336739127379] , [ 1254283200000 , 25.478492475753] , [ 1256961600000 , 23.017152085245] , [ 1259557200000 , 25.617745423683] , [ 1262235600000 , 24.061133998642] , [ 1264914000000 , 23.223933318644] , [ 1267333200000 , 24.425887263937] , [ 1270008000000 , 35.501471156693] , [ 1272600000000 , 33.775013878676] , [ 1275278400000 , 30.417993630285] , [ 1277870400000 , 30.023598978467] , [ 1280548800000 , 33.327519522436] , [ 1283227200000 , 31.963388450371] , [ 1285819200000 , 30.498967232092] , [ 1288497600000 , 32.403696817912] , [ 1291093200000 , 31.47736071922] , [ 1293771600000 , 31.53259666241] , [ 1296450000000 , 41.760282761548] , [ 1298869200000 , 45.605771243237] , [ 1301544000000 , 39.986557966215] , [ 1304136000000 , 43.846330510051] , [ 1306814400000 , 39.857316881857] , [ 1309406400000 , 37.675127768208] , [ 1312084800000 , 35.775077970313] , [ 1314763200000 , 48.631009702577] , [ 1317355200000 , 42.830831754505] , [ 1320033600000 , 35.611502589362] , [ 1322629200000 , 35.320136981738] , [ 1325307600000 , 31.564136901516] , [ 1327986000000 , 32.074407502433] , [ 1330491600000 , 35.053013769976] , [ 1333166400000 , 26.434568573937] , [ 1335758400000 , 25.305617871002] , [ 1338436800000 , 24.520919418236]]\n        } ,\n        {\n            \"key\" : \"Materials\" ,\n            \"values\" : [ [ 1138683600000 , 5.5806167415681] , [ 1141102800000 , 5.4539047069985] , [ 1143781200000 , 7.6728842432362] , [ 1146369600000 , 7.719946716654] , [ 1149048000000 , 8.0144619912942] , [ 1151640000000 , 7.942223133434] , [ 1154318400000 , 8.3998279827444] , [ 1156996800000 , 8.532324572605] , [ 1159588800000 , 4.7324285199763] , [ 1162270800000 , 4.7402397487697] , [ 1164862800000 , 4.9042069355168] , [ 1167541200000 , 5.9583963430882] , [ 1170219600000 , 6.3693899239171] , [ 1172638800000 , 6.261153903813] , [ 1175313600000 , 5.3443942184584] , [ 1177905600000 , 5.4932111235361] , [ 1180584000000 , 5.5747393101109] , [ 1183176000000 , 5.3833633060013] , [ 1185854400000 , 5.5125898831832] , [ 1188532800000 , 5.8116112661327] , [ 1191124800000 , 4.3962296939996] , [ 1193803200000 , 4.6967663605521] , [ 1196398800000 , 4.7963004350914] , [ 1199077200000 , 4.1817985183351] , [ 1201755600000 , 4.3797643870182] , [ 1204261200000 , 4.6966642197965] , [ 1206936000000 , 4.3609995132565] , [ 1209528000000 , 4.4736290996496] , [ 1212206400000 , 4.3749762738128] , [ 1214798400000 , 3.3274661194507] , [ 1217476800000 , 3.0316184691337] , [ 1220155200000 , 2.5718140204728] , [ 1222747200000 , 2.7034994044603] , [ 1225425600000 , 2.2033786591364] , [ 1228021200000 , 1.9850621240805] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0.44495950017788] , [ 1256961600000 , 0.33945469262483] , [ 1259557200000 , 0.38348269455195] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0.52216435716176] , [ 1298869200000 , 0.59275786698454] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Telecommunication Services\" ,\n            \"values\" : [ [ 1138683600000 , 3.7056975170243] , [ 1141102800000 , 3.7561118692318] , [ 1143781200000 , 2.861913700854] , [ 1146369600000 , 2.9933744103381] , [ 1149048000000 , 2.7127537218463] , [ 1151640000000 , 3.1195497076283] , [ 1154318400000 , 3.4066964004508] , [ 1156996800000 , 3.3754571113569] , [ 1159588800000 , 2.2965579982924] , [ 1162270800000 , 2.4486818633018] , [ 1164862800000 , 2.4002308848517] , [ 1167541200000 , 1.9649579750349] , [ 1170219600000 , 1.9385263638056] , [ 1172638800000 , 1.9128975336387] , [ 1175313600000 , 2.3412869836298] , [ 1177905600000 , 2.4337870351445] , [ 1180584000000 , 2.62179703171] , [ 1183176000000 , 3.2642864957929] , [ 1185854400000 , 3.3200396223709] , [ 1188532800000 , 3.3934212707572] , [ 1191124800000 , 4.2822327088179] , [ 1193803200000 , 4.1474964228541] , [ 1196398800000 , 4.1477082879801] , [ 1199077200000 , 5.2947122916128] , [ 1201755600000 , 5.2919843508028] , [ 1204261200000 , 5.1989783050309] , [ 1206936000000 , 3.5603057673513] , [ 1209528000000 , 3.3009087690692] , [ 1212206400000 , 3.1784852603792] , [ 1214798400000 , 4.5889503538868] , [ 1217476800000 , 4.401779617494] , [ 1220155200000 , 4.2208301828278] , [ 1222747200000 , 3.89396671475] , [ 1225425600000 , 3.0423832241354] , [ 1228021200000 , 3.135520611578] , [ 1230699600000 , 1.9631418164089] , [ 1233378000000 , 1.8963543874958] , [ 1235797200000 , 1.8266636017025] , [ 1238472000000 , 0.93136635895188] , [ 1241064000000 , 0.92737801918888] , [ 1243742400000 , 0.97591889805002] , [ 1246334400000 , 2.6841193805515] , [ 1249012800000 , 2.5664341140531] , [ 1251691200000 , 2.3887523699873] , [ 1254283200000 , 1.1737801663681] , [ 1256961600000 , 1.0953582317281] , [ 1259557200000 , 1.2495674976653] , [ 1262235600000 , 0.36607452464754] , [ 1264914000000 , 0.3548719047291] , [ 1267333200000 , 0.36769242398939] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0.85450741275337] , [ 1288497600000 , 0.91360317921637] , [ 1291093200000 , 0.89647678692269] , [ 1293771600000 , 0.87800687192639] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0.43668720882994] , [ 1304136000000 , 0.4756523602692] , [ 1306814400000 , 0.46947368328469] , [ 1309406400000 , 0.45138896152316] , [ 1312084800000 , 0.43828726648117] , [ 1314763200000 , 2.0820861395316] , [ 1317355200000 , 0.9364411075395] , [ 1320033600000 , 0.60583907839773] , [ 1322629200000 , 0.61096950747437] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Utilities\" ,\n            \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 0] , [ 1225425600000 , 0] , [ 1228021200000 , 0] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0] , [ 1256961600000 , 0] , [ 1259557200000 , 0] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        }\n    ];\n\n    var colors = d3.scale.category20();\n    var chart;\n\n    nv.addGraph(function() {\n        chart = nv.models.stackedAreaWithFocusChart()\n            .useInteractiveGuideline(true)\n            .x(function(d) { return d[0] })\n            .y(function(d) { return d[1] })\n            .controlLabels({stacked: \"Stacked\"})\n            .duration(300);\n        chart.brushExtent([1225425600000, 1285819200000]);\n\n        chart.xAxis.tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n        chart.x2Axis.tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n        chart.yAxis.tickFormat(d3.format(',.4f'));\n        chart.y2Axis.tickFormat(d3.format(',.4f'));\n\n        chart.legend.vers('furious');\n\n        d3.select('#chart1')\n            .datum(histcatexplong)\n            .transition().duration(1000)\n            .call(chart)\n            .each('start', function() {\n                setTimeout(function() {\n                    d3.selectAll('#chart1 *').each(function() {\n                        if(this.__transition__)\n                            this.__transition__.duration = 1;\n                    })\n                }, 0)\n            });\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "examples/stylesheets/pygment_trac.css",
    "content": ".highlight .hll { background-color: #404040 }\r\n.highlight  { color: #d0d0d0 }\r\n.highlight .c { color: #999999; font-style: italic } /* Comment */\r\n.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */\r\n.highlight .g { color: #d0d0d0 } /* Generic */\r\n.highlight .k { color: #6ab825; font-weight: normal } /* Keyword */\r\n.highlight .l { color: #d0d0d0 } /* Literal */\r\n.highlight .n { color: #d0d0d0 } /* Name */\r\n.highlight .o { color: #d0d0d0 } /* Operator */\r\n.highlight .x { color: #d0d0d0 } /* Other */\r\n.highlight .p { color: #d0d0d0 } /* Punctuation */\r\n.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */\r\n.highlight .cp { color: #cd2828; font-weight: normal } /* Comment.Preproc */\r\n.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */\r\n.highlight .cs { color: #e50808; font-weight: normal; background-color: #520000 } /* Comment.Special */\r\n.highlight .gd { color: #d22323 } /* Generic.Deleted */\r\n.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */\r\n.highlight .gr { color: #d22323 } /* Generic.Error */\r\n.highlight .gh { color: #ffffff; font-weight: normal } /* Generic.Heading */\r\n.highlight .gi { color: #589819 } /* Generic.Inserted */\r\n.highlight .go { color: #cccccc } /* Generic.Output */\r\n.highlight .gp { color: #aaaaaa } /* Generic.Prompt */\r\n.highlight .gs { color: #d0d0d0; font-weight: normal } /* Generic.Strong */\r\n.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */\r\n.highlight .gt { color: #d22323 } /* Generic.Traceback */\r\n.highlight .kc { color: #6ab825; font-weight: normal } /* Keyword.Constant */\r\n.highlight .kd { color: #6ab825; font-weight: normal } /* Keyword.Declaration */\r\n.highlight .kn { color: #6ab825; font-weight: normal } /* Keyword.Namespace */\r\n.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */\r\n.highlight .kr { color: #6ab825; font-weight: normal } /* Keyword.Reserved */\r\n.highlight .kt { color: #6ab825; font-weight: normal } /* Keyword.Type */\r\n.highlight .ld { color: #d0d0d0 } /* Literal.Date */\r\n.highlight .m { color: #3677a9 } /* Literal.Number */\r\n.highlight .s { color: #ff8 } /* Literal.String */\r\n.highlight .na { color: #bbbbbb } /* Name.Attribute */\r\n.highlight .nb { color: #24909d } /* Name.Builtin */\r\n.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */\r\n.highlight .no { color: #40ffff } /* Name.Constant */\r\n.highlight .nd { color: #ffa500 } /* Name.Decorator */\r\n.highlight .ni { color: #d0d0d0 } /* Name.Entity */\r\n.highlight .ne { color: #bbbbbb } /* Name.Exception */\r\n.highlight .nf { color: #447fcf } /* Name.Function */\r\n.highlight .nl { color: #d0d0d0 } /* Name.Label */\r\n.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */\r\n.highlight .nx { color: #d0d0d0 } /* Name.Other */\r\n.highlight .py { color: #d0d0d0 } /* Name.Property */\r\n.highlight .nt { color: #6ab825;} /* Name.Tag */\r\n.highlight .nv { color: #40ffff } /* Name.Variable */\r\n.highlight .ow { color: #6ab825; font-weight: normal } /* Operator.Word */\r\n.highlight .w { color: #666666 } /* Text.Whitespace */\r\n.highlight .mf { color: #3677a9 } /* Literal.Number.Float */\r\n.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */\r\n.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */\r\n.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */\r\n.highlight .sb { color: #ff8 } /* Literal.String.Backtick */\r\n.highlight .sc { color: #ff8 } /* Literal.String.Char */\r\n.highlight .sd { color: #ff8 } /* Literal.String.Doc */\r\n.highlight .s2 { color: #ff8 } /* Literal.String.Double */\r\n.highlight .se { color: #ff8 } /* Literal.String.Escape */\r\n.highlight .sh { color: #ff8 } /* Literal.String.Heredoc */\r\n.highlight .si { color: #ff8 } /* Literal.String.Interpol */\r\n.highlight .sx { color: #ffa500 } /* Literal.String.Other */\r\n.highlight .sr { color: #ff8 } /* Literal.String.Regex */\r\n.highlight .s1 { color: #ff8 } /* Literal.String.Single */\r\n.highlight .ss { color: #ff8 } /* Literal.String.Symbol */\r\n.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */\r\n.highlight .vc { color: #40ffff } /* Name.Variable.Class */\r\n.highlight .vg { color: #40ffff } /* Name.Variable.Global */\r\n.highlight .vi { color: #40ffff } /* Name.Variable.Instance */\r\n.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */"
  },
  {
    "path": "examples/stylesheets/styles.css",
    "content": "/*\r\nLeap Day for GitHub Pages\r\nby Matt Graham\r\n*/\r\n\r\n\r\n/* normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */\r\n/* =============================================================================\r\n   HTML5 display definitions\r\n   ========================================================================== */\r\n/*\r\n * Corrects block display not defined in IE6/7/8/9 & FF3\r\n */\r\narticle,\r\naside,\r\ndetails,\r\nfigcaption,\r\nfigure,\r\nfooter,\r\nheader,\r\nhgroup,\r\nnav,\r\nsection,\r\nsummary {\r\n    display: block;\r\n}\r\n\r\n/*\r\n * Corrects inline-block display not defined in IE6/7/8/9 & FF3\r\n */\r\naudio,\r\ncanvas,\r\nvideo {\r\n    display: inline-block;\r\n    *display: inline;\r\n    *zoom: 1;\r\n}\r\n\r\n/*\r\n * Prevents modern browsers from displaying 'audio' without controls\r\n */\r\naudio:not([controls]) {\r\n    display: none;\r\n}\r\n\r\n/*\r\n * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4\r\n * Known issue: no IE6 support\r\n */\r\n[hidden] {\r\n    display: none;\r\n}\r\n\r\n/* =============================================================================\r\n   Base\r\n   ========================================================================== */\r\n/*\r\n * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units\r\n *    http://clagnut.com/blog/348/#c790\r\n * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom\r\n *    www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/\r\n */\r\nhtml {\r\n    font-size: 100%;\r\n    /* 1 */\r\n    -webkit-text-size-adjust: 100%;\r\n    /* 2 */\r\n    -ms-text-size-adjust: 100%;\r\n    /* 2 */\r\n}\r\n\r\n/*\r\n * Addresses font-family inconsistency between 'textarea' and other form elements.\r\n */\r\nhtml,\r\nbutton,\r\ninput,\r\nselect,\r\ntextarea {\r\n    font-family: sans-serif;\r\n}\r\n\r\n/*\r\n * Addresses margins handled incorrectly in IE6/7\r\n */\r\nbody {\r\n    margin: 0;\r\n}\r\n\r\n/* =============================================================================\r\n   Links\r\n   ========================================================================== */\r\n/*\r\n * Addresses outline displayed oddly in Chrome\r\n */\r\na:focus {\r\n    outline: thin dotted;\r\n}\r\n\r\n/*\r\n * Improves readability when focused and also mouse hovered in all browsers\r\n * people.opera.com/patrickl/experiments/keyboard/test\r\n */\r\na:hover,\r\na:active {\r\n    outline: 0;\r\n}\r\n\r\n/* =============================================================================\r\n   Typography\r\n   ========================================================================== */\r\n/*\r\n * Addresses font sizes and margins set differently in IE6/7\r\n * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5\r\n */\r\nh1 {\r\n    font-size: 2em;\r\n    margin: 0.67em 0;\r\n}\r\n\r\nh2 {\r\n    font-size: 1.5em;\r\n    margin: 0.83em 0;\r\n}\r\n\r\nh3 {\r\n    font-size: 1.17em;\r\n    margin: 1em 0;\r\n}\r\n\r\nh4 {\r\n    font-size: 1em;\r\n    margin: 1.33em 0;\r\n}\r\n\r\nh5 {\r\n    font-size: 0.83em;\r\n    margin: 1.67em 0;\r\n}\r\n\r\nh6 {\r\n    font-size: 0.75em;\r\n    margin: 2.33em 0;\r\n}\r\n\r\n/*\r\n * Addresses styling not present in IE7/8/9, S5, Chrome\r\n */\r\nabbr[title] {\r\n    border-bottom: 1px dotted;\r\n}\r\n\r\n/*\r\n * Addresses style set to 'bolder' in FF3+, S4/5, Chrome\r\n*/\r\nb,\r\nstrong {\r\n    font-weight: bold;\r\n}\r\n\r\nblockquote {\r\n    margin: 1em 40px;\r\n}\r\n\r\n/*\r\n * Addresses styling not present in S5, Chrome\r\n */\r\ndfn {\r\n    font-style: italic;\r\n}\r\n\r\n/*\r\n * Addresses styling not present in IE6/7/8/9\r\n */\r\nmark {\r\n    background: #ff0;\r\n    color: #000;\r\n}\r\n\r\n/*\r\n * Addresses margins set differently in IE6/7\r\n */\r\np,\r\npre {\r\n    margin: 1em 0;\r\n}\r\n\r\n/*\r\n * Corrects font family set oddly in IE6, S4/5, Chrome\r\n * en.wikipedia.org/wiki/User:Davidgothberg/Test59\r\n */\r\npre,\r\ncode,\r\nkbd,\r\nsamp {\r\n    font-family: monospace, serif;\r\n    _font-family: 'courier new', monospace;\r\n    font-size: 1em;\r\n}\r\n\r\n/*\r\n * 1. Addresses CSS quotes not supported in IE6/7\r\n * 2. Addresses quote property not supported in S4\r\n */\r\n/* 1 */\r\nq {\r\n    quotes: none;\r\n}\r\n\r\n/* 2 */\r\nq:before,\r\nq:after {\r\n    content: '';\r\n    content: none;\r\n}\r\n\r\nsmall {\r\n    font-size: 75%;\r\n}\r\n\r\n/*\r\n * Prevents sub and sup affecting line-height in all browsers\r\n * gist.github.com/413930\r\n */\r\nsub,\r\nsup {\r\n    font-size: 75%;\r\n    line-height: 0;\r\n    position: relative;\r\n    vertical-align: baseline;\r\n}\r\n\r\nsup {\r\n    top: -0.5em;\r\n}\r\n\r\nsub {\r\n    bottom: -0.25em;\r\n}\r\n\r\n/* =============================================================================\r\n   Lists\r\n   ========================================================================== */\r\n/*\r\n * Addresses margins set differently in IE6/7\r\n */\r\ndl,\r\nmenu,\r\nol,\r\nul {\r\n    margin: 1em 0;\r\n}\r\n\r\ndd {\r\n    margin: 0 0 0 40px;\r\n}\r\n\r\n/*\r\n * Addresses paddings set differently in IE6/7\r\n */\r\nmenu,\r\nol,\r\nul {\r\n    padding: 0 0 0 40px;\r\n}\r\n\r\n/*\r\n * Corrects list images handled incorrectly in IE7\r\n */\r\nnav ul,\r\nnav ol {\r\n    list-style: none;\r\n    list-style-image: none;\r\n}\r\n\r\nli span.inherited {\r\n    display: inline-block;\r\n    color: #CCC;\r\n}\r\n\r\n/* =============================================================================\r\n   Embedded content\r\n   ========================================================================== */\r\n/*\r\n * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3\r\n * 2. Improves image quality when scaled in IE7\r\n *    code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/\r\n */\r\nimg {\r\n    border: 0;\r\n    /* 1 */\r\n    -ms-interpolation-mode: bicubic;\r\n    /* 2 */\r\n}\r\n\r\n/*\r\n * Corrects overflow displayed oddly in IE9\r\n */\r\nsvg:not(:root) {\r\n    overflow: hidden;\r\n}\r\n\r\n/* =============================================================================\r\n   Figures\r\n   ========================================================================== */\r\n/*\r\n * Addresses margin not present in IE6/7/8/9, S5, O11\r\n */\r\nfigure {\r\n    margin: 0;\r\n}\r\n\r\n/* =============================================================================\r\n   Forms\r\n   ========================================================================== */\r\n/*\r\n * Corrects margin displayed oddly in IE6/7\r\n */\r\nform {\r\n    margin: 0;\r\n}\r\n\r\n/*\r\n * Define consistent border, margin, and padding\r\n */\r\nfieldset {\r\n    border: 1px solid #c0c0c0;\r\n    margin: 0 2px;\r\n    padding: 0.35em 0.625em 0.75em;\r\n}\r\n\r\n/*\r\n * 1. Corrects color not being inherited in IE6/7/8/9\r\n * 2. Corrects text not wrapping in FF3\r\n * 3. Corrects alignment displayed oddly in IE6/7\r\n */\r\nlegend {\r\n    border: 0;\r\n    /* 1 */\r\n    padding: 0;\r\n    white-space: normal;\r\n    /* 2 */\r\n    *margin-left: -7px;\r\n    /* 3 */\r\n}\r\n\r\n/*\r\n * 1. Corrects font size not being inherited in all browsers\r\n * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome\r\n * 3. Improves appearance and consistency in all browsers\r\n */\r\nbutton,\r\ninput,\r\nselect,\r\ntextarea {\r\n    font-size: 100%;\r\n    /* 1 */\r\n    margin: 0;\r\n    /* 2 */\r\n    vertical-align: baseline;\r\n    /* 3 */\r\n    *vertical-align: middle;\r\n    /* 3 */\r\n}\r\n\r\n/*\r\n * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet\r\n */\r\nbutton,\r\ninput {\r\n    line-height: normal;\r\n    /* 1 */\r\n}\r\n\r\n/*\r\n * 1. Improves usability and consistency of cursor style between image-type 'input' and others\r\n * 2. Corrects inability to style clickable 'input' types in iOS\r\n * 3. Removes inner spacing in IE7 without affecting normal text inputs\r\n *    Known issue: inner spacing remains in IE6\r\n */\r\nbutton,\r\ninput[type=\"button\"],\r\ninput[type=\"reset\"],\r\ninput[type=\"submit\"] {\r\n    cursor: pointer;\r\n    /* 1 */\r\n    -webkit-appearance: button;\r\n    /* 2 */\r\n    *overflow: visible;\r\n    /* 3 */\r\n}\r\n\r\n/*\r\n * Re-set default cursor for disabled elements\r\n */\r\nbutton[disabled],\r\ninput[disabled] {\r\n    cursor: default;\r\n}\r\n\r\n/*\r\n * 1. Addresses box sizing set to content-box in IE8/9\r\n * 2. Removes excess padding in IE8/9\r\n * 3. Removes excess padding in IE7\r\n      Known issue: excess padding remains in IE6\r\n */\r\ninput[type=\"checkbox\"],\r\ninput[type=\"radio\"] {\r\n    box-sizing: border-box;\r\n    /* 1 */\r\n    padding: 0;\r\n    /* 2 */\r\n    *height: 13px;\r\n    /* 3 */\r\n    *width: 13px;\r\n    /* 3 */\r\n}\r\n\r\n/*\r\n * 1. Addresses appearance set to searchfield in S5, Chrome\r\n * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)\r\n */\r\ninput[type=\"search\"] {\r\n    -webkit-appearance: textfield;\r\n    /* 1 */\r\n    -moz-box-sizing: content-box;\r\n    -webkit-box-sizing: content-box;\r\n    /* 2 */\r\n    box-sizing: content-box;\r\n}\r\n\r\n/*\r\n * Removes inner padding and search cancel button in S5, Chrome on OS X\r\n */\r\ninput[type=\"search\"]::-webkit-search-decoration,\r\ninput[type=\"search\"]::-webkit-search-cancel-button {\r\n    -webkit-appearance: none;\r\n}\r\n\r\n/*\r\n * Removes inner padding and border in FF3+\r\n * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/\r\n */\r\nbutton::-moz-focus-inner,\r\ninput::-moz-focus-inner {\r\n    border: 0;\r\n    padding: 0;\r\n}\r\n\r\n/*\r\n * 1. Removes default vertical scrollbar in IE6/7/8/9\r\n * 2. Improves readability and alignment in all browsers\r\n */\r\ntextarea {\r\n    overflow: auto;\r\n    /* 1 */\r\n    vertical-align: top;\r\n    /* 2 */\r\n}\r\n\r\nli.option {\r\n    cursor: pointer;\r\n}\r\nli.option:hover {\r\n    color: #FF9900;\r\n}\r\nli.option-selected {\r\n    color: #FF9900;\r\n    border-bottom: 1px solid #AAA;\r\n}\r\nli.option-selected:last-child {\r\n    border-bottom: 0px;\r\n}\r\nli.option div.option-info{\r\n    color: #999;\r\n    margin-top: 5px;\r\n    margin-bottom: 10px;\r\n    padding-left: 30px;\r\n}\r\nli.option div.option-info .part {\r\n    font-weight: bold;\r\n    color: #666;\r\n}\r\nli.option div.option-info .example {\r\n    display: inline-block;\r\n    border: 1px solid #CCC;\r\n    background: #EEE;\r\n    margin-top: 3px;\r\n    color: #666;\r\n    width: 100%;\r\n    box-sizing: border-box;\r\n}\r\nli.option div.option-info .example code {\r\n    white-space: pre;\r\n    padding: 5px;\r\n    font-family: \"Courier New\";\r\n    background: inherit ! important;\r\n}\r\n\r\n/* =============================================================================\r\n   Tables\r\n   ========================================================================== */\r\n/*\r\n * Remove most spacing between table cells\r\n */\r\ntable {\r\n    border-collapse: collapse;\r\n    border-spacing: 0;\r\n}\r\n\r\nbody {\r\n    font: 14px/22px \"Quattrocento Sans\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\r\n    color: #666;\r\n    font-weight: 300;\r\n    margin: 0px;\r\n    padding: 0px 0 20px 0px;\r\n    background: url(../images/body-background.png) #eae6d1;\r\n}\r\n\r\nh1, h2, h3, h4, h5, h6 {\r\n    color: #333;\r\n    margin: 0 0 10px;\r\n}\r\n\r\np, ul, ol, table, pre, dl {\r\n    margin: 0 0 20px;\r\n}\r\n\r\nh1, h2, h3 {\r\n    line-height: 1.1;\r\n}\r\n\r\nh1 {\r\n    font-size: 28px;\r\n}\r\n\r\nh2 {\r\n    font-size: 24px;\r\n    color: #393939;\r\n}\r\n\r\nh3, h4, h5, h6 {\r\n    color: #666666;\r\n}\r\n\r\nh3 {\r\n    font-size: 18px;\r\n    line-height: 24px;\r\n}\r\nh3.option {\r\n    background-color: #F2F2F2;\r\n    padding: 5px;\r\n    padding-left: 10px;\r\n    border-top: 5px solid #CCC;\r\n    margin-top: 10px;\r\n\tmin-height: 24px;\r\n}\r\nh3 .expand {\r\n    font-size: 14px;\r\n    position: relative;\r\n    margin-right: 10px;\r\n    float: right;\r\n    font-weight: normal;\r\n}\r\n\r\na {\r\n    color: #3399cc;\r\n    font-weight: 400;\r\n    text-decoration: none;\r\n}\r\n\r\na small {\r\n    font-size: 11px;\r\n    color: #666;\r\n    margin-top: -0.6em;\r\n    display: block;\r\n}\r\n\r\nul {\r\n    list-style-image: url(\"../images/bullet.png\");\r\n}\r\n\r\nstrong {\r\n    font-weight: bold;\r\n    color: #333;\r\n}\r\n\r\n.wrapper {\r\n    width: 900px;\r\n    margin: 0 auto;\r\n    position: relative;\r\n}\r\n\r\nsection img {\r\n    max-width: 100%;\r\n}\r\n\r\nblockquote {\r\n    border-left: 1px solid #ffcc00;\r\n    margin: 0;\r\n    padding: 0 0 0 20px;\r\n    font-style: italic;\r\n}\r\n\r\npre {\r\n    padding: 8px 15px;\r\n    background: #EEE;\r\n    -moz-border-radius: 3px;\r\n    -webkit-border-radius: 3px;\r\n    -o-border-radius: 3px;\r\n    -ms-border-radius: 3px;\r\n    -khtml-border-radius: 3px;\r\n    border-radius: 3px;\r\n    border: 1px solid #c7c7c7;\r\n    overflow: auto;\r\n    overflow-y: hidden;\r\n}\r\n\r\ntable {\r\n    width: 100%;\r\n    border-collapse: collapse;\r\n}\r\n\r\nth {\r\n    text-align: left;\r\n    padding: 5px 10px;\r\n    border-bottom: 1px solid #e5e5e5;\r\n    color: #444;\r\n}\r\n\r\ntd {\r\n    text-align: left;\r\n    padding: 5px 10px;\r\n    border-bottom: 1px solid #e5e5e5;\r\n    border-right: 1px solid #ffcc00;\r\n}\r\ntd:first-child {\r\n    border-left: 1px solid #ffcc00;\r\n}\r\n\r\nhr {\r\n    border: 0;\r\n    outline: none;\r\n    height: 11px;\r\n    background: transparent url(\"../images/hr.gif\") center center repeat-x;\r\n    margin: 0 0 20px;\r\n}\r\n\r\ndt {\r\n    color: #444;\r\n    font-weight: 700;\r\n}\r\n\r\nheader {\r\n    margin: 0;\r\n    top: 0;\r\n    left: 0;\r\n    right: 0;\r\n    width: 100%;\r\n    text-align: center;\r\n    background: url(../images/background.png) #4276b6;\r\n    -moz-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75);\r\n    -webkit-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75);\r\n    -o-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75);\r\n    box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75);\r\n    z-index: 99;\r\n    -webkit-font-smoothing: antialiased;\r\n    min-height: 76px;\r\n}\r\nheader h1 {\r\n    font: 40px/48px \"Copse\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\r\n    color: #f3f3f3;\r\n    text-shadow: 0px 2px 0px #235796;\r\n    margin: 0px;\r\n    white-space: nowrap;\r\n    overflow: hidden;\r\n    text-overflow: ellipsis;\r\n    -o-text-overflow: ellipsis;\r\n    -ms-text-overflow: ellipsis;\r\n}\r\nheader p {\r\n    color: #d8d8d8;\r\n    text-shadow: rgba(0, 0, 0, 0.2) 0 1px 0;\r\n    font-size: 18px;\r\n    margin: 0px;\r\n}\r\n\r\n#banner {\r\n    z-index: 100;\r\n    left: 0;\r\n    height: 50px;\r\n    width: 100%;\r\n    box-sizing: border-box;\r\n    top: 75px;\r\n    background: #ffcc00;\r\n    border: 1px solid #f0b500;\r\n    -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);\r\n    -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);\r\n    -o-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);\r\n    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25);\r\n    -moz-border-radius: 0px 2px 2px 0px;\r\n    -webkit-border-radius: 0px 2px 2px 0px;\r\n    -o-border-radius: 0px 2px 2px 0px;\r\n    -ms-border-radius: 0px 2px 2px 0px;\r\n    -khtml-border-radius: 0px 2px 2px 0px;\r\n    border-radius: 0px 2px 2px 0px;\r\n}\r\n#banner .button {\r\n    border: 1px solid #dba500;\r\n    background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffe788), color-stop(100%, #ffce38));\r\n    background: -webkit-linear-gradient(#ffe788, #ffce38);\r\n    background: -moz-linear-gradient(#ffe788, #ffce38);\r\n    background: -o-linear-gradient(#ffe788, #ffce38);\r\n    background: -ms-linear-gradient(#ffe788, #ffce38);\r\n    background: linear-gradient(#ffe788, #ffce38);\r\n    -moz-border-radius: 2px;\r\n    -webkit-border-radius: 2px;\r\n    -o-border-radius: 2px;\r\n    -ms-border-radius: 2px;\r\n    -khtml-border-radius: 2px;\r\n    border-radius: 2px;\r\n    -moz-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1);\r\n    -webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1);\r\n    -o-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1);\r\n    box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1);\r\n    background-color: #FFE788;\r\n    margin-left: 5px;\r\n    padding: 10px 12px;\r\n    margin-top: 6px;\r\n    line-height: 14px;\r\n    font-size: 14px;\r\n    color: #333;\r\n    font-weight: bold;\r\n    display: inline-block;\r\n    text-align: center;\r\n}\r\n#banner .button:hover {\r\n    background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffe788), color-stop(100%, #ffe788));\r\n    background: -webkit-linear-gradient(#ffe788, #ffe788);\r\n    background: -moz-linear-gradient(#ffe788, #ffe788);\r\n    background: -o-linear-gradient(#ffe788, #ffe788);\r\n    background: -ms-linear-gradient(#ffe788, #ffe788);\r\n    background: linear-gradient(#ffe788, #ffe788);\r\n    background-color: #ffeca0;\r\n}\r\n#banner .fork {\r\n    left: 50%;\r\n    padding: 10px 12px;\r\n    margin-top: 6px;\r\n    margin-left: 0px;\r\n    line-height: 14px;\r\n    font-size: 14px;\r\n    background-color: #FFE788;\r\n}\r\n#banner .docs {\r\n    margin-left: 10px !important;\r\n}\r\n#banner .button.selected {\r\n    background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffe788), color-stop(100%, #ffe788));\r\n    background: -webkit-linear-gradient(#ffe788, #ffe788);\r\n    background: -moz-linear-gradient(#ffe788, #ffe788);\r\n    background: -o-linear-gradient(#ffe788, #ffe788);\r\n    background: -ms-linear-gradient(#ffe788, #ffe788);\r\n    background: linear-gradient(#ffe788, #ffe788);\r\n    background-color: #ffeca0;\r\n}\r\n#banner .downloads {\r\n    float: right;\r\n    margin: 0 0 0 0;\r\n    margin-right: 2px;\r\n}\r\n#banner .downloads span {\r\n    float: left;\r\n    line-height: 52px;\r\n    font-size: 90%;\r\n    color: #9d7f0d;\r\n    text-transform: uppercase;\r\n    text-shadow: rgba(255, 255, 255, 0.2) 0 1px 0;\r\n}\r\n#banner ul {\r\n    list-style: none;\r\n    height: 40px;\r\n    padding: 0;\r\n    float: left;\r\n    margin-left: 10px;\r\n}\r\n#banner ul li {\r\n    display: inline;\r\n}\r\n#banner ul li a.button {\r\n    background-color: #FFE788;\r\n}\r\n#banner #logo {\r\n    position: absolute;\r\n    height: 36px;\r\n    width: 36px;\r\n    right: -60px;\r\n    top: 7px;\r\n    display: block;\r\n    background: url(../images/octocat-logo.png);\r\n}\r\n#banner > div {\r\n    width: 900px;\r\n    margin: 0 auto;\r\n    position: relative;\r\n}\r\nsection {\r\n    width: 100%;\r\n    box-sizing: border-box;\r\n    padding: 15px 30px 50px 30px;\r\n    position: relative;\r\n    background: #fbfbfb;\r\n    -moz-border-radius: 3px;\r\n    -webkit-border-radius: 3px;\r\n    -o-border-radius: 3px;\r\n    -ms-border-radius: 3px;\r\n    -khtml-border-radius: 3px;\r\n    border-radius: 3px;\r\n    border: 1px solid #cbcbcb;\r\n    -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4);\r\n    -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4);\r\n    -o-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4);\r\n    box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4);\r\n}\r\n\r\nsmall {\r\n    font-size: 12px;\r\n}\r\n\r\nnav {\r\n    width: 230px;\r\n    top: 220px;\r\n    left: 50%;\r\n    margin-left: -580px;\r\n    text-align: right;\r\n}\r\nnav ul {\r\n    list-style: none;\r\n    list-style-image: none;\r\n    font-size: 14px;\r\n    line-height: 24px;\r\n}\r\nnav ul li {\r\n    padding: 5px 0px;\r\n    line-height: 16px;\r\n}\r\nnav ul li.tag-h1 {\r\n    font-size: 1.2em;\r\n}\r\nnav ul li.tag-h1 a {\r\n    font-weight: bold;\r\n    color: #333;\r\n}\r\nnav ul li.tag-h2 + .tag-h1 {\r\n    margin-top: 10px;\r\n}\r\nnav ul a {\r\n    color: #666;\r\n}\r\nnav ul a:hover {\r\n    color: #999;\r\n}\r\n\r\nfooter {\r\n    width: 180px;\r\n    position: fixed;\r\n    left: 50%;\r\n    margin-left: -530px;\r\n    bottom: 20px;\r\n    text-align: right;\r\n    line-height: 16px;\r\n}\r\n\r\n#banner {\r\n    width: 100%;\r\n}\r\n#banner .downloads {\r\n    margin-right: 0px;\r\n}\r\n#banner #logo {\r\n    margin-right: 15px;\r\n}\r\n\r\n#banner .fork {\r\n    float: left;\r\n    margin-left: 0px;\r\n    display: inline-block;\r\n    left: 20px;\r\n}\r\n\r\n\r\n.showcharts, .showbases {\r\n    display: inline-block;\r\n    font-family: arial;\r\n    font-size: 14px;\r\n    color: #666;\r\n    padding: 2px;\r\n    padding-right: 5px;\r\n    padding-left: 5px;\r\n    background-color: #EEE;\r\n    border: 1px solid #CCC;\r\n    border-radius: 5px;\r\n    position: absolute;\r\n    right: 0;\r\n    margin: 10px;\r\n    top: 0;\r\n}\r\n.baselinks, .showcharts {\r\n    display: none;\r\n}\r\n.showcharts:hover, .showbases:hover {\r\n    background-color: #ffffcc;\r\n}\r\n.examplelinks a {\r\n    text-decoration: none;\r\n    font-size: 12px;\r\n    font-family: arial;\r\n    outline: none;\r\n    padding: 3px;\r\n    padding-left: 6px;\r\n    padding-right: 6px;\r\n}\r\n.examplelinks a.selected {\r\n    border: 1px solid #666;\r\n    background-color: #FFFF88;\r\n    padding: 2px;\r\n    padding-left: 5px;\r\n    padding-right: 5px;\r\n}\r\n\r\n.propdom {\r\n    height: 0;\r\n}\r\n\r\n.propdom.populated {\r\n    height: auto;\r\n    padding: 5px 10px;\r\n}\r\n\r\n.propdom .label {\r\n    font-weight: bold;\r\n}\r\n\r\niframe {\r\n    display: inline-block;\r\n    width: 100%;\r\n    height: 100%;\r\n    border: 0px;\r\n}\r\n#show_wrapper {\r\n    border: 1px solid #666;\r\n    width: 100%;\r\n    margin-top: 10px;\r\n    height: 400px;\r\n}\r\n\r\n@media print, screen and (max-width: 1060px) {\r\n    div.wrapper {\r\n        width: auto;\r\n        margin: 0;\r\n    }\r\n\r\n    #banner > div {\r\n        width: auto;\r\n        margin: 0;\r\n    }\r\n\r\n    nav {\r\n        display: none;\r\n    }\r\n\r\n    header, section, footer {\r\n        float: none;\r\n    }\r\n    header h1, section h1, footer h1 {\r\n        white-space: nowrap;\r\n        overflow: hidden;\r\n        text-overflow: ellipsis;\r\n        -o-text-overflow: ellipsis;\r\n        -ms-text-overflow: ellipsis;\r\n    }\r\n\r\n    #banner {\r\n        width: 100%;\r\n    }\r\n    #banner .downloads {\r\n        margin-right: 30px;\r\n    }\r\n    #banner #logo {\r\n        margin-right: 15px;\r\n    }\r\n\r\n\r\n\r\n    footer {\r\n        text-align: center;\r\n        margin: 20px auto;\r\n        position: relative;\r\n        left: auto;\r\n        bottom: auto;\r\n        width: auto;\r\n    }\r\n\r\n    body {\r\n        word-wrap: break-word;\r\n    }\r\n\r\n    header h1 {\r\n        font-size: 32px;\r\n        white-space: nowrap;\r\n        overflow: hidden;\r\n        text-overflow: ellipsis;\r\n        -o-text-overflow: ellipsis;\r\n        -ms-text-overflow: ellipsis;\r\n    }\r\n\r\n\r\n    #banner .fork {\r\n        float: left;\r\n        display: inline-block;\r\n        margin-left: 30px;\r\n        left: 20px;\r\n    }\r\n\r\n    section {\r\n        margin-bottom: 0px;\r\n        width: auto;\r\n        box-sizing: border-box;\r\n    }\r\n\r\n    header ul, header p.view {\r\n        position: static;\r\n    }\r\n}\r\n@media print, screen and (max-width: 480px) {\r\n    header {\r\n        position: relative;\r\n        padding: 5px 0px;\r\n        min-height: 0px;\r\n    }\r\n    header h1 {\r\n        font-size: 24px;\r\n        white-space: nowrap;\r\n        overflow: hidden;\r\n        text-overflow: ellipsis;\r\n        -o-text-overflow: ellipsis;\r\n        -ms-text-overflow: ellipsis;\r\n    }\r\n\r\n    section {\r\n        margin-top: 5px !important;\r\n        box-sizing: border-box;\r\n    }\r\n\r\n    #banner {\r\n        display: none;\r\n    }\r\n\r\n    header ul {\r\n        display: none;\r\n    }\r\n\r\n    .showcharts, .showbases {\r\n        position: relative !important;\r\n\r\n    }\r\n}\r\n@media print {\r\n    body {\r\n        padding: 0.4in;\r\n        font-size: 12pt;\r\n        color: #444;\r\n    }\r\n}\r\n@media print, screen and (max-height: 680px) {\r\n    footer {\r\n        text-align: center;\r\n        margin: 20px auto;\r\n        position: relative;\r\n        left: auto;\r\n        bottom: auto;\r\n        width: auto;\r\n    }\r\n}\r\n@media print, screen and (max-height: 480px) {\r\n    nav {\r\n        display: none;\r\n    }\r\n\r\n    footer {\r\n        text-align: center;\r\n        margin: 20px auto;\r\n        position: relative;\r\n        left: auto;\r\n        bottom: auto;\r\n        width: auto;\r\n    }\r\n}\r\n"
  },
  {
    "path": "examples/sunburst.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"lib/stream_layers.js\"></script>\n\n    <style>\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<svg id=\"test1\"></svg>\n\n<script>\n\n    var chart;\n\n    nv.addGraph(function() {\n        chart = nv.models.sunburstChart();\n\n        chart.color(d3.scale.category20c());\n\n        d3.select(\"#test1\")\n                .datum(getData())\n                .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function getData() {\n        return [{\n            \"name\": \"flare\",\n            \"children\": [\n                {\n                    \"name\": \"analytics\",\n                    \"children\": [\n                        {\n                            \"name\": \"cluster\",\n                            \"children\": [\n                                {\"name\": \"AgglomerativeCluster\", \"size\": 3938},\n                                {\"name\": \"CommunityStructure\", \"size\": 3812},\n                                {\"name\": \"HierarchicalCluster\", \"size\": 6714},\n                                {\"name\": \"MergeEdge\", \"size\": 743}\n                            ]\n                        },\n                        {\n                            \"name\": \"graph\",\n                            \"children\": [\n                                {\"name\": \"BetweennessCentrality\", \"size\": 3534},\n                                {\"name\": \"LinkDistance\", \"size\": 5731},\n                                {\"name\": \"MaxFlowMinCut\", \"size\": 7840},\n                                {\"name\": \"ShortestPaths\", \"size\": 5914},\n                                {\"name\": \"SpanningTree\", \"size\": 3416}\n                            ]\n                        },\n                        {\n                            \"name\": \"optimization\",\n                            \"children\": [\n                                {\"name\": \"AspectRatioBanker\", \"size\": 7074}\n                            ]\n                        }\n                    ]\n                },\n                {\n                    \"name\": \"animate\",\n                    \"children\": [\n                        {\"name\": \"Easing\", \"size\": 17010},\n                        {\"name\": \"FunctionSequence\", \"size\": 5842},\n                        {\n                            \"name\": \"interpolate\",\n                            \"children\": [\n                                {\"name\": \"ArrayInterpolator\", \"size\": 1983},\n                                {\"name\": \"ColorInterpolator\", \"size\": 2047},\n                                {\"name\": \"DateInterpolator\", \"size\": 1375},\n                                {\"name\": \"Interpolator\", \"size\": 8746},\n                                {\"name\": \"MatrixInterpolator\", \"size\": 2202},\n                                {\"name\": \"NumberInterpolator\", \"size\": 1382},\n                                {\"name\": \"ObjectInterpolator\", \"size\": 1629},\n                                {\"name\": \"PointInterpolator\", \"size\": 1675},\n                                {\"name\": \"RectangleInterpolator\", \"size\": 2042}\n                            ]\n                        },\n                        {\"name\": \"ISchedulable\", \"size\": 1041},\n                        {\"name\": \"Parallel\", \"size\": 5176},\n                        {\"name\": \"Pause\", \"size\": 449},\n                        {\"name\": \"Scheduler\", \"size\": 5593},\n                        {\"name\": \"Sequence\", \"size\": 5534},\n                        {\"name\": \"Transition\", \"size\": 9201},\n                        {\"name\": \"Transitioner\", \"size\": 19975},\n                        {\"name\": \"TransitionEvent\", \"size\": 1116},\n                        {\"name\": \"Tween\", \"size\": 6006}\n                    ]\n                },\n                {\n                    \"name\": \"devicedata\",\n                    \"children\": [\n                        {\n                            \"name\": \"converters\",\n                            \"children\": [\n                                {\"name\": \"Converters\", \"size\": 721},\n                                {\"name\": \"DelimitedTextConverter\", \"size\": 4294},\n                                {\"name\": \"GraphMLConverter\", \"size\": 9800},\n                                {\"name\": \"IDataConverter\", \"size\": 1314},\n                                {\"name\": \"JSONConverter\", \"size\": 2220}\n                            ]\n                        },\n                        {\"name\": \"DataField\", \"size\": 1759},\n                        {\"name\": \"DataSchema\", \"size\": 2165},\n                        {\"name\": \"DataSet\", \"size\": 586},\n                        {\"name\": \"DataSource\", \"size\": 3331},\n                        {\"name\": \"DataTable\", \"size\": 772},\n                        {\"name\": \"DataUtil\", \"size\": 3322}\n                    ]\n                },\n                {\n                    \"name\": \"display\",\n                    \"children\": [\n                        {\"name\": \"DirtySprite\", \"size\": 8833},\n                        {\"name\": \"LineSprite\", \"size\": 1732},\n                        {\"name\": \"RectSprite\", \"size\": 3623},\n                        {\"name\": \"TextSprite\", \"size\": 10066}\n                    ]\n                },\n                {\n                    \"name\": \"flex\",\n                    \"children\": [\n                        {\"name\": \"FlareVis\", \"size\": 4116}\n                    ]\n                },\n                {\n                    \"name\": \"physics\",\n                    \"children\": [\n                        {\"name\": \"DragForce\", \"size\": 1082},\n                        {\"name\": \"GravityForce\", \"size\": 1336},\n                        {\"name\": \"IForce\", \"size\": 319},\n                        {\"name\": \"NBodyForce\", \"size\": 10498},\n                        {\"name\": \"Particle\", \"size\": 2822},\n                        {\"name\": \"Simulation\", \"size\": 9983},\n                        {\"name\": \"Spring\", \"size\": 2213},\n                        {\"name\": \"SpringForce\", \"size\": 1681}\n                    ]\n                },\n                {\n                    \"name\": \"query\",\n                    \"children\": [\n                        {\"name\": \"AggregateExpression\", \"size\": 1616},\n                        {\"name\": \"And\", \"size\": 1027},\n                        {\"name\": \"Arithmetic\", \"size\": 3891},\n                        {\"name\": \"Average\", \"size\": 891},\n                        {\"name\": \"BinaryExpression\", \"size\": 2893},\n                        {\"name\": \"Comparison\", \"size\": 5103},\n                        {\"name\": \"CompositeExpression\", \"size\": 3677},\n                        {\"name\": \"Count\", \"size\": 781},\n                        {\"name\": \"DateUtil\", \"size\": 4141},\n                        {\"name\": \"Distinct\", \"size\": 933},\n                        {\"name\": \"Expression\", \"size\": 5130},\n                        {\"name\": \"ExpressionIterator\", \"size\": 3617},\n                        {\"name\": \"Fn\", \"size\": 3240},\n                        {\"name\": \"If\", \"size\": 2732},\n                        {\"name\": \"IsA\", \"size\": 2039},\n                        {\"name\": \"Literal\", \"size\": 1214},\n                        {\"name\": \"Match\", \"size\": 3748},\n                        {\"name\": \"Maximum\", \"size\": 843},\n                        {\n                            \"name\": \"methods\",\n                            \"children\": [\n                                {\"name\": \"add\", \"size\": 593},\n                                {\"name\": \"and\", \"size\": 330},\n                                {\"name\": \"average\", \"size\": 287},\n                                {\"name\": \"count\", \"size\": 277},\n                                {\"name\": \"distinct\", \"size\": 292},\n                                {\"name\": \"div\", \"size\": 595},\n                                {\"name\": \"eq\", \"size\": 594},\n                                {\"name\": \"fn\", \"size\": 460},\n                                {\"name\": \"gt\", \"size\": 603},\n                                {\"name\": \"gte\", \"size\": 625},\n                                {\"name\": \"iff\", \"size\": 748},\n                                {\"name\": \"isa\", \"size\": 461},\n                                {\"name\": \"lt\", \"size\": 597},\n                                {\"name\": \"lte\", \"size\": 619},\n                                {\"name\": \"max\", \"size\": 283},\n                                {\"name\": \"min\", \"size\": 283},\n                                {\"name\": \"mod\", \"size\": 591},\n                                {\"name\": \"mul\", \"size\": 603},\n                                {\"name\": \"neq\", \"size\": 599},\n                                {\"name\": \"not\", \"size\": 386},\n                                {\"name\": \"or\", \"size\": 323},\n                                {\"name\": \"orderby\", \"size\": 307},\n                                {\"name\": \"range\", \"size\": 772},\n                                {\"name\": \"select\", \"size\": 296},\n                                {\"name\": \"stddev\", \"size\": 363},\n                                {\"name\": \"sub\", \"size\": 600},\n                                {\"name\": \"sum\", \"size\": 280},\n                                {\"name\": \"update\", \"size\": 307},\n                                {\"name\": \"variance\", \"size\": 335},\n                                {\"name\": \"where\", \"size\": 299},\n                                {\"name\": \"xor\", \"size\": 354},\n                                {\"name\": \"_\", \"size\": 264}\n                            ]\n                        },\n                        {\"name\": \"Minimum\", \"size\": 843},\n                        {\"name\": \"Not\", \"size\": 1554},\n                        {\"name\": \"Or\", \"size\": 970},\n                        {\"name\": \"Query\", \"size\": 13896},\n                        {\"name\": \"Range\", \"size\": 1594},\n                        {\"name\": \"StringUtil\", \"size\": 4130},\n                        {\"name\": \"Sum\", \"size\": 791},\n                        {\"name\": \"Variable\", \"size\": 1124},\n                        {\"name\": \"Variance\", \"size\": 1876},\n                        {\"name\": \"Xor\", \"size\": 1101}\n                    ]\n                },\n                {\n                    \"name\": \"scale\",\n                    \"children\": [\n                        {\"name\": \"IScaleMap\", \"size\": 2105},\n                        {\"name\": \"LinearScale\", \"size\": 1316},\n                        {\"name\": \"LogScale\", \"size\": 3151},\n                        {\"name\": \"OrdinalScale\", \"size\": 3770},\n                        {\"name\": \"QuantileScale\", \"size\": 2435},\n                        {\"name\": \"QuantitativeScale\", \"size\": 4839},\n                        {\"name\": \"RootScale\", \"size\": 1756},\n                        {\"name\": \"Scale\", \"size\": 4268},\n                        {\"name\": \"ScaleType\", \"size\": 1821},\n                        {\"name\": \"TimeScale\", \"size\": 5833}\n                    ]\n                },\n                {\n                    \"name\": \"util\",\n                    \"children\": [\n                        {\"name\": \"Arrays\", \"size\": 8258},\n                        {\"name\": \"Colors\", \"size\": 10001},\n                        {\"name\": \"Dates\", \"size\": 8217},\n                        {\"name\": \"Displays\", \"size\": 12555},\n                        {\"name\": \"Filter\", \"size\": 2324},\n                        {\"name\": \"Geometry\", \"size\": 10993},\n                        {\n                            \"name\": \"heap\",\n                            \"children\": [\n                                {\"name\": \"FibonacciHeap\", \"size\": 9354},\n                                {\"name\": \"HeapNode\", \"size\": 1233}\n                            ]\n                        },\n                        {\"name\": \"IEvaluable\", \"size\": 335},\n                        {\"name\": \"IPredicate\", \"size\": 383},\n                        {\"name\": \"IValueProxy\", \"size\": 874},\n                        {\n                            \"name\": \"math\",\n                            \"children\": [\n                                {\"name\": \"DenseMatrix\", \"size\": 3165},\n                                {\"name\": \"IMatrix\", \"size\": 2815},\n                                {\"name\": \"SparseMatrix\", \"size\": 3366}\n                            ]\n                        },\n                        {\"name\": \"Maths\", \"size\": 17705},\n                        {\"name\": \"Orientation\", \"size\": 1486},\n                        {\n                            \"name\": \"palette\",\n                            \"children\": [\n                                {\"name\": \"ColorPalette\", \"size\": 6367},\n                                {\"name\": \"Palette\", \"size\": 1229},\n                                {\"name\": \"ShapePalette\", \"size\": 2059},\n                                {\"name\": \"SizePalette\", \"size\": 2291}\n                            ]\n                        },\n                        {\"name\": \"Property\", \"size\": 5559},\n                        {\"name\": \"Shapes\", \"size\": 19118},\n                        {\"name\": \"Sort\", \"size\": 6887},\n                        {\"name\": \"Stats\", \"size\": 6557},\n                        {\"name\": \"Strings\", \"size\": 22026}\n                    ]\n                },\n                {\n                    \"name\": \"vis\",\n                    \"children\": [\n                        {\n                            \"name\": \"axis\",\n                            \"children\": [\n                                {\"name\": \"Axes\", \"size\": 1302},\n                                {\"name\": \"Axis\", \"size\": 24593},\n                                {\"name\": \"AxisGridLine\", \"size\": 652},\n                                {\"name\": \"AxisLabel\", \"size\": 636},\n                                {\"name\": \"CartesianAxes\", \"size\": 6703}\n                            ]\n                        },\n                        {\n                            \"name\": \"controls\",\n                            \"children\": [\n                                {\"name\": \"AnchorControl\", \"size\": 2138},\n                                {\"name\": \"ClickControl\", \"size\": 3824},\n                                {\"name\": \"Control\", \"size\": 1353},\n                                {\"name\": \"ControlList\", \"size\": 4665},\n                                {\"name\": \"DragControl\", \"size\": 2649},\n                                {\"name\": \"ExpandControl\", \"size\": 2832},\n                                {\"name\": \"HoverControl\", \"size\": 4896},\n                                {\"name\": \"IControl\", \"size\": 763},\n                                {\"name\": \"PanZoomControl\", \"size\": 5222},\n                                {\"name\": \"SelectionControl\", \"size\": 7862},\n                                {\"name\": \"TooltipControl\", \"size\": 8435}\n                            ]\n                        },\n                        {\n                            \"name\": \"data\",\n                            \"children\": [\n                                {\"name\": \"Data\", \"size\": 20544},\n                                {\"name\": \"DataList\", \"size\": 19788},\n                                {\"name\": \"DataSprite\", \"size\": 10349},\n                                {\"name\": \"EdgeSprite\", \"size\": 3301},\n                                {\"name\": \"NodeSprite\", \"size\": 19382},\n                                {\n                                    \"name\": \"render\",\n                                    \"children\": [\n                                        {\"name\": \"ArrowType\", \"size\": 698},\n                                        {\"name\": \"EdgeRenderer\", \"size\": 5569},\n                                        {\"name\": \"IRenderer\", \"size\": 353},\n                                        {\"name\": \"ShapeRenderer\", \"size\": 2247}\n                                    ]\n                                },\n                                {\"name\": \"ScaleBinding\", \"size\": 11275},\n                                {\"name\": \"Tree\", \"size\": 7147},\n                                {\"name\": \"TreeBuilder\", \"size\": 9930}\n                            ]\n                        },\n                        {\n                            \"name\": \"events\",\n                            \"children\": [\n                                {\"name\": \"DataEvent\", \"size\": 2313},\n                                {\"name\": \"SelectionEvent\", \"size\": 1880},\n                                {\"name\": \"TooltipEvent\", \"size\": 1701},\n                                {\"name\": \"VisualizationEvent\", \"size\": 1117}\n                            ]\n                        },\n                        {\n                            \"name\": \"legend\",\n                            \"children\": [\n                                {\"name\": \"Legend\", \"size\": 20859},\n                                {\"name\": \"LegendItem\", \"size\": 4614},\n                                {\"name\": \"LegendRange\", \"size\": 10530}\n                            ]\n                        },\n                        {\n                            \"name\": \"operator\",\n                            \"children\": [\n                                {\n                                    \"name\": \"distortion\",\n                                    \"children\": [\n                                        {\"name\": \"BifocalDistortion\", \"size\": 4461},\n                                        {\"name\": \"Distortion\", \"size\": 6314},\n                                        {\"name\": \"FisheyeDistortion\", \"size\": 3444}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"encoder\",\n                                    \"children\": [\n                                        {\"name\": \"ColorEncoder\", \"size\": 3179},\n                                        {\"name\": \"Encoder\", \"size\": 4060},\n                                        {\"name\": \"PropertyEncoder\", \"size\": 4138},\n                                        {\"name\": \"ShapeEncoder\", \"size\": 1690},\n                                        {\"name\": \"SizeEncoder\", \"size\": 1830}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"filter\",\n                                    \"children\": [\n                                        {\"name\": \"FisheyeTreeFilter\", \"size\": 5219},\n                                        {\"name\": \"GraphDistanceFilter\", \"size\": 3165},\n                                        {\"name\": \"VisibilityFilter\", \"size\": 3509}\n                                    ]\n                                },\n                                {\"name\": \"IOperator\", \"size\": 1286},\n                                {\n                                    \"name\": \"label\",\n                                    \"children\": [\n                                        {\"name\": \"Labeler\", \"size\": 9956},\n                                        {\"name\": \"RadialLabeler\", \"size\": 3899},\n                                        {\"name\": \"StackedAreaLabeler\", \"size\": 3202}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"layout\",\n                                    \"children\": [\n                                        {\"name\": \"AxisLayout\", \"size\": 6725},\n                                        {\"name\": \"BundledEdgeRouter\", \"size\": 3727},\n                                        {\"name\": \"CircleLayout\", \"size\": 9317},\n                                        {\"name\": \"CirclePackingLayout\", \"size\": 12003},\n                                        {\"name\": \"DendrogramLayout\", \"size\": 4853},\n                                        {\"name\": \"ForceDirectedLayout\", \"size\": 8411},\n                                        {\"name\": \"IcicleTreeLayout\", \"size\": 4864},\n                                        {\"name\": \"IndentedTreeLayout\", \"size\": 3174},\n                                        {\"name\": \"Layout\", \"size\": 7881},\n                                        {\"name\": \"NodeLinkTreeLayout\", \"size\": 12870},\n                                        {\"name\": \"PieLayout\", \"size\": 2728},\n                                        {\"name\": \"RadialTreeLayout\", \"size\": 12348},\n                                        {\"name\": \"RandomLayout\", \"size\": 870},\n                                        {\"name\": \"StackedAreaLayout\", \"size\": 9121},\n                                        {\"name\": \"TreeMapLayout\", \"size\": 9191}\n                                    ]\n                                },\n                                {\"name\": \"Operator\", \"size\": 2490},\n                                {\"name\": \"OperatorList\", \"size\": 5248},\n                                {\"name\": \"OperatorSequence\", \"size\": 4190},\n                                {\"name\": \"OperatorSwitch\", \"size\": 2581},\n                                {\"name\": \"SortOperator\", \"size\": 2023}\n                            ]\n                        },\n                        {\"name\": \"Visualization\", \"size\": 16540}\n                    ]\n                }\n            ]\n        }];\n    }\n\n</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/tooltip.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            width: 100%;\n            height: 100%;\n        }\n        .container {\n            position: absolute;\n            top: 0;\n            left: 0;\n        }\n        .container > div {\n            float: left;\n        }\n    </style>\n</head>\n<body>\n<!-- just make a circle to create the tooltip over -->\n<div class=\"container\" style=\"left: 200px;\">\n    <div style=\"height: 20px; width: 100%; float: left; display: inline-block;\"></div>\n    <div style=\"position: relative; margin-top: 10px; margin-left: 10px; margin-bottom: -50px; margin-right: -50px; display: inline-block; width: 300px; height: 300px;\">\n        <div style=\"position: absolute; right: 0; bottom: 0; display: inline-block; width: 110px; height: 110px;\">\n            <svg id=\"test1\">\n                <g transform=\"translate(55, 55)\">\n                    <circle class=\"tooltip_me\" r=\"50\" style=\"stroke-width: 2px; fill: rgb(148, 103, 189); stroke: rgb(148, 103, 189);\"></circle>\n                </g>\n            </svg>\n        </div>\n    </div>\n</div>\n<div class=\"container\">\n    <div style=\"height: 10px; width: 100%; display: inline-block;\"></div>\n    <div style=\"position: relative; margin-top: 20px; margin-left: 20px; margin-bottom: -50px; margin-right: -50px; display: inline-block; width: 300px; height: 400px;\">\n        <div style=\"position: absolute; right: 100; bottom: 0; display: inline-block; width: 300px; height: 300px;\">\n            <svg id=\"test2\">\n            </svg>\n        </div>\n    </div>\n</div>\n<script>\n    var width = 500,\n        height = 20;\n\n    var tooltip = nv.models.tooltip();\n    tooltip.duration(0);\n\n    d3.select('.tooltip_me')\n        .on('mouseover', function(d,i) {\n            console.log(\"mouseover\", d, i);\n            var data = {series: {\n                key: \"title\",\n                value: \"the value\",\n                color: \"#229922\"\n            }};\n            tooltip.data(data).hidden(false);\n        })\n        .on('mouseout', function(d,i) {\n            console.log(\"mouseout\", d, i);\n            tooltip.hidden(true);\n        })\n        .on('mousemove', function(d,i) {\n            console.log(\"mousemove\", d, i);\n            tooltip.position({top: d3.event.pageY, left: d3.event.pageX})();\n        });\n\n\n    // we must also test the scatter/line way of getting position\n    // Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.lineChart()\n                .showXAxis(false)\n                .showLegend(false)\n                .clipVoronoi(false)\n                .showVoronoi(true)\n                .showYAxis(false);\n        d3.select('#test2')\n                .datum(sinAndCos())\n                .call(chart);\n        return chart;\n    });\n\n    function sinAndCos() {\n        var cos = [];\n        for (var i = 0; i < 5; i++) {\n            cos.push({x: i, y: Math.round(.5 * Math.cos(i/10) * 100) / 100});\n        }\n        return [{\n            values: cos,\n            key: \"Cosine Wave\",\n            color: \"#2ca02c\"\n        }];\n    }\n</script>\n</body>\n</html>"
  },
  {
    "path": "index.html",
    "content": "<html><body>\n<style>\nhtml, body, iframe {\n margin: 0px;\n padding: 0px;\n width: 100%;\n height: 100%;\n border: 0px;\n}\n</style>\n<script>\n    // force https to avoid stupid mixed content stuff.\n    // don't force just http because http-everywhere plugins cause infinite redirect loop\n    // can't use relative links because they break when loading the site locally on disk (browsers suck)\n    // if (window.location.protocol == \"http:\")\n    //     window.location.href = \"https:\" + window.location.href.substring(window.location.protocol.length);\n</script>\n<iframe src=\"examples/site.html\"></iframe>\n</body>\n</html>\n"
  },
  {
    "path": "meteor/export.js",
    "content": "/*global nv:true*/  // Meteor creates a file-scope global for exporting. This comment prevents a potential JSHint warning.\nnv = window.nv;\ndelete window.nv;\n\n"
  },
  {
    "path": "package.js",
    "content": "// Package metadata for Meteor.js full stack web framework\n// This file is defined in Meteor documentation at http://docs.meteor.com/#/full/packagejs\n// and used by Meteor https://www.meteor.com/ and its package repository Atmosphere https://atmospherejs.com\n\nPackage.describe({\n    \"name\": 'nvd3:nvd3',\n    summary: 'Nvd3.org charts.',\n    version: '1.8.6-dev',\n    git: \"https://github.com/novus/nvd3.git\"\n});\nPackage.on_use(function (api) {\n    api.versionsFrom(\"METEOR@1.0\");\n    api.use('d3js:d3@3.5.5', 'client');\n    api.add_files('build/nv.d3.js', 'client');\n    api.add_files('build/nv.d3.css', 'client');\n    api.add_files('meteor/export.js', 'client');\n    api.export(\"nv\");\n});\nPackage.onTest(function(api) {\n    api.use(['tinytest', 'test-helpers']);\n    api.use('d3js:d3', 'client');\n    api.addFiles(['build/nv.d3.js', 'meteor/export.js'], \"client\");\n    api.addFiles('test/tinytest/nv-is-defined-test.js', \"client\");\n});\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"nvd3\",\n  \"version\": \"1.8.6-dev\",\n  \"description\": \"A reusable charting library written in d3.js\",\n  \"url\": \"https://github.com/novus/nvd3\",\n  \"main\": \"build/nv.d3.js\",\n  \"scripts\": {\n    \"test\": \"grunt\",\n    \"build\": \"grunt\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/novus/nvd3\"\n  },\n  \"keywords\": [\n    \"nvd3\",\n    \"d3\",\n    \"chart\",\n    \"graph\"\n  ],\n  \"readmeFilename\": \"README.md\",\n  \"license\": \"Apache-2.0\",\n  \"peerDependencies\": {\n    \"d3\": \"^3.4.4\"\n  },\n  \"devDependencies\": {\n    \"autoprefixer\": \"^6.5.0\",\n    \"es6-promise\": \"^4.0.3\",\n    \"grunt\": \"^0.4.5\",\n    \"grunt-cli\": \"^1.2.0\",\n    \"grunt-contrib-concat\": \"~1.0.1\",\n    \"grunt-contrib-copy\": \"~0.4.1\",\n    \"grunt-contrib-cssmin\": \"~0.13.0\",\n    \"grunt-contrib-jshint\": \"^0.11.0\",\n    \"grunt-contrib-uglify\": \"~0.9.1\",\n    \"grunt-contrib-watch\": \"~0.3.1\",\n    \"grunt-karma\": \"^0.9.0\",\n    \"grunt-postcss\": \"^0.8.0\",\n    \"grunt-text-replace\": \"^0.4.0\",\n    \"karma\": \"^0.12.23\",\n    \"karma-chrome-launcher\": \"^0.1.4\",\n    \"karma-coffee-preprocessor\": \"^0.2.1\",\n    \"karma-coverage\": \"^0.2.6\",\n    \"karma-firefox-launcher\": \"^0.1.4\",\n    \"karma-junit-reporter\": \"^0.2.2\",\n    \"karma-mocha\": \"^0.1.9\",\n    \"karma-sinon-chai\": \"^0.2.0\",\n    \"karma-spec-reporter\": \"0.0.13\",\n    \"mocha\": \"^1.21.4\",\n    \"moment\": \"^2.18.1\"\n  }\n}\n"
  },
  {
    "path": "src/core.js",
    "content": "\n// set up main nv object\nvar nv = {};\n\n// the major global objects under the nv namespace\nnv.dev = false; //set false when in production\nnv.tooltip = nv.tooltip || {}; // For the tooltip system\nnv.utils = nv.utils || {}; // Utility subsystem\nnv.models = nv.models || {}; //stores all the possible models/components\nnv.charts = {}; //stores all the ready to use charts\nnv.logs = {}; //stores some statistics and potential error messages\nnv.dom = {}; //DOM manipulation functions\n\n// Node/CommonJS - require D3\nif (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined' && typeof(d3) == 'undefined') {\n    d3 = require('d3');\n}\n\nnv.dispatch = d3.dispatch('render_start', 'render_end');\n\n// Function bind polyfill\n// Needed ONLY for phantomJS as it's missing until version 2.0 which is unreleased as of this comment\n// https://github.com/ariya/phantomjs/issues/10522\n// http://kangax.github.io/compat-table/es5/#Function.prototype.bind\n// phantomJS is used for running the test suite\nif (!Function.prototype.bind) {\n    Function.prototype.bind = function (oThis) {\n        if (typeof this !== \"function\") {\n            // closest thing possible to the ECMAScript 5 internal IsCallable function\n            throw new TypeError(\"Function.prototype.bind - what is trying to be bound is not callable\");\n        }\n\n        var aArgs = Array.prototype.slice.call(arguments, 1),\n            fToBind = this,\n            fNOP = function () {},\n            fBound = function () {\n                return fToBind.apply(this instanceof fNOP && oThis\n                        ? this\n                        : oThis,\n                    aArgs.concat(Array.prototype.slice.call(arguments)));\n            };\n\n        fNOP.prototype = this.prototype;\n        fBound.prototype = new fNOP();\n        return fBound;\n    };\n}\n\n//  Development render timers - disabled if dev = false\nif (nv.dev) {\n    nv.dispatch.on('render_start', function(e) {\n        nv.logs.startTime = +new Date();\n    });\n\n    nv.dispatch.on('render_end', function(e) {\n        nv.logs.endTime = +new Date();\n        nv.logs.totalTime = nv.logs.endTime - nv.logs.startTime;\n        nv.log('total', nv.logs.totalTime); // used for development, to keep track of graph generation times\n    });\n}\n\n// Logs all arguments, and returns the last so you can test things in place\n// Note: in IE8 console.log is an object not a function, and if modernizr is used\n// then calling Function.prototype.bind with with anything other than a function\n// causes a TypeError to be thrown.\nnv.log = function() {\n    if (nv.dev && window.console && console.log && console.log.apply)\n        console.log.apply(console, arguments);\n    else if (nv.dev && window.console && typeof console.log == \"function\" && Function.prototype.bind) {\n        var log = Function.prototype.bind.call(console.log, console);\n        log.apply(console, arguments);\n    }\n    return arguments[arguments.length - 1];\n};\n\n// print console warning, should be used by deprecated functions\nnv.deprecated = function(name, info) {\n    if (console && console.warn) {\n        console.warn('nvd3 warning: `' + name + '` has been deprecated. ', info || '');\n    }\n};\n\n// The nv.render function is used to queue up chart rendering\n// in non-blocking async functions.\n// When all queued charts are done rendering, nv.dispatch.render_end is invoked.\nnv.render = function render(step) {\n    // number of graphs to generate in each timeout loop\n    step = step || 1;\n\n    nv.render.active = true;\n    nv.dispatch.render_start();\n\n    var renderLoop = function() {\n        var chart, graph;\n\n        for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) {\n            chart = graph.generate();\n            if (typeof graph.callback == typeof(Function)) graph.callback(chart);\n        }\n\n        nv.render.queue.splice(0, i);\n\n        if (nv.render.queue.length) {\n            setTimeout(renderLoop);\n        }\n        else {\n            nv.dispatch.render_end();\n            nv.render.active = false;\n        }\n    };\n\n    setTimeout(renderLoop);\n};\n\nnv.render.active = false;\nnv.render.queue = [];\n\n/*\nAdds a chart to the async rendering queue. This method can take arguments in two forms:\nnv.addGraph({\n    generate: <Function>\n    callback: <Function>\n})\n\nor\n\nnv.addGraph(<generate Function>, <callback Function>)\n\nThe generate function should contain code that creates the NVD3 model, sets options\non it, adds data to an SVG element, and invokes the chart model. The generate function\nshould return the chart model.  See examples/lineChart.html for a usage example.\n\nThe callback function is optional, and it is called when the generate function completes.\n*/\nnv.addGraph = function(obj) {\n    if (typeof arguments[0] === typeof(Function)) {\n        obj = {generate: arguments[0], callback: arguments[1]};\n    }\n\n    nv.render.queue.push(obj);\n\n    if (!nv.render.active) {\n        nv.render();\n    }\n};\n\n// Node/CommonJS exports\nif (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined') {\n  module.exports = nv;\n}\n\nif (typeof(window) !== 'undefined') {\n  window.nv = nv;\n}\n"
  },
  {
    "path": "src/css/axis.css",
    "content": ".nvd3 .nv-axis {\r\n    pointer-events:none;\r\n    opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-axis path {\r\n    fill: none;\r\n    stroke: #000;\r\n    stroke-opacity: .75;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-axis path.domain {\r\n    stroke-opacity: .75;\r\n}\r\n\r\n.nvd3 .nv-axis.nv-x path.domain {\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3 .nv-axis line {\r\n    fill: none;\r\n    stroke: #e5e5e5;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-axis .zero line,\r\n    /*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {\r\n    stroke-opacity: .75;\r\n}\r\n\r\n.nvd3 .nv-axis .nv-axisMaxMin text {\r\n    font-weight: bold;\r\n}\r\n\r\n.nvd3 .x  .nv-axis .nv-axisMaxMin text,\r\n.nvd3 .x2 .nv-axis .nv-axisMaxMin text,\r\n.nvd3 .x3 .nv-axis .nv-axisMaxMin text {\r\n    text-anchor: middle;\r\n}\r\n\r\n.nvd3 .nv-axis.nv-disabled {\r\n    opacity: 0;\r\n}\r\n"
  },
  {
    "path": "src/css/bars.css",
    "content": ".nvd3 .nv-bars rect {\r\n    fill-opacity: .75;\r\n\r\n    transition: fill-opacity 250ms linear;\r\n}\n\r\n.nvd3 .nv-bars rect.hover {\r\n    fill-opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-bars .hover rect {\r\n    fill: lightblue;\r\n}\r\n\r\n.nvd3 .nv-bars text {\r\n    fill: rgba(0,0,0,0);\r\n}\r\n\r\n.nvd3 .nv-bars .hover text {\r\n    fill: rgba(0,0,0,1);\r\n}\r\n\r\n.nvd3 .nv-multibar .nv-groups rect,\r\n.nvd3 .nv-multibarHorizontal .nv-groups rect,\r\n.nvd3 .nv-discretebar .nv-groups rect {\r\n    stroke-opacity: 0;\r\n\r\n    transition: fill-opacity 250ms linear;\r\n}\n\r\n.nvd3 .nv-multibar .nv-groups rect:hover,\r\n.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,\r\n.nvd3 .nv-candlestickBar .nv-ticks rect:hover,\r\n.nvd3 .nv-discretebar .nv-groups rect:hover {\r\n    fill-opacity: 1;\r\n}\r\n\r\n.nvd3 .nv-discretebar .nv-groups text,\r\n.nvd3 .nv-multibarHorizontal .nv-groups text {\r\n    font-weight: bold;\r\n    fill: rgba(0,0,0,1);\r\n    stroke: rgba(0,0,0,0);\r\n}\r\n"
  },
  {
    "path": "src/css/boxplot.css",
    "content": "/* boxplot CSS */\n.nvd3 .nv-boxplot circle {\n  fill-opacity: 0.5;\n}\n\n.nvd3 .nv-boxplot circle:hover {\n  fill-opacity: 1;\n}\n\n.nvd3 .nv-boxplot rect:hover {\n  fill-opacity: 1;\n}\n\n.nvd3 line.nv-boxplot-median {\n  stroke: black;\n}\n\n.nv-boxplot-tick:hover {\n  stroke-width: 2.5px;\n}"
  },
  {
    "path": "src/css/bullet.css",
    "content": "/* bullet */\r\n.nvd3.nv-bullet { font: 10px sans-serif; }\r\n.nvd3.nv-bullet .nv-measure { fill-opacity: .8; }\r\n.nvd3.nv-bullet .nv-measure:hover { fill-opacity: 1; }\r\n.nvd3.nv-bullet .nv-marker { stroke: #000; stroke-width: 2px; }\r\n.nvd3.nv-bullet .nv-markerTriangle { stroke: #000; fill: #fff; stroke-width: 1.5px; }\r\n.nvd3.nv-bullet .nv-markerLine { stroke: #000; stroke-width: 1.5px; }\r\n.nvd3.nv-bullet .nv-tick line { stroke: #666; stroke-width: .5px; }\r\n.nvd3.nv-bullet .nv-range.nv-s0 { fill: #eee; }\r\n.nvd3.nv-bullet .nv-range.nv-s1 { fill: #ddd; }\r\n.nvd3.nv-bullet .nv-range.nv-s2 { fill: #ccc; }\r\n.nvd3.nv-bullet .nv-title { font-size: 14px; font-weight: bold; }\r\n.nvd3.nv-bullet .nv-subtitle { fill: #999; }\r\n\r\n.nvd3.nv-bullet .nv-range {\n    fill: #bababa;\r\n    fill-opacity: .4;\r\n}\n\n.nvd3.nv-bullet .nv-range:hover {\r\n    fill-opacity: .7;\r\n}\r\n"
  },
  {
    "path": "src/css/candlestick.css",
    "content": ".nvd3.nv-candlestickBar .nv-ticks .nv-tick {\r\n    stroke-width: 1px;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover {\r\n    stroke-width: 2px;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect {\r\n    stroke: #2ca02c;\r\n    fill: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect {\r\n    stroke: #d62728;\r\n    fill: #d62728;\r\n}\r\n\r\n.with-transitions .nv-candlestickBar .nv-ticks .nv-tick {\r\n    transition: stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-candlestickBar .nv-ticks line {\r\n    stroke: #333;\r\n}\r\n"
  },
  {
    "path": "src/css/forceDirectedGraph.css",
    "content": ".nv-force-node {\n    stroke: #fff;\n    stroke-width: 1.5px;\n}\n\n.nv-force-link {\n    stroke: #999;\n    stroke-opacity: .6;\n}\n\n.nv-force-node text {\n    stroke-width: 0px;\n}\n"
  },
  {
    "path": "src/css/furiousLegend.css",
    "content": ".nvd3 .nv-legend .nv-disabled rect {\n    /*fill-opacity: 0;*/\n}\n\n.nvd3 .nv-check-box .nv-box {\n    fill-opacity:0;\n    stroke-width:2;\n}\n\n.nvd3 .nv-check-box .nv-check {\n    fill-opacity:0;\n    stroke-width:4;\n}\n\n.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check {\n    fill-opacity:0;\n    stroke-opacity:0;\n}\n\n.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check {\n    opacity: 0;\n}\n"
  },
  {
    "path": "src/css/lineplusbar.css",
    "content": "/* line plus bar */\r\n.nvd3.nv-linePlusBar .nv-bar rect {\r\n    fill-opacity: .75;\r\n}\r\n\r\n.nvd3.nv-linePlusBar .nv-bar rect:hover {\r\n    fill-opacity: 1;\r\n}"
  },
  {
    "path": "src/css/lines.css",
    "content": ".nvd3 .nv-groups path.nv-line {\r\n    fill: none;\r\n}\r\n\r\n.nvd3 .nv-groups path.nv-area {\r\n    stroke: none;\r\n}\r\n\r\n.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {\r\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {\r\n    fill-opacity: .5 !important;\r\n    stroke-opacity: .5 !important;\r\n}\r\n\r\n\r\n.with-transitions .nvd3 .nv-groups .nv-point {\r\n    transition: stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-scatter .nv-groups .nv-point.hover,\r\n.nvd3 .nv-groups .nv-point.hover {\r\n    stroke-width: 7px;\r\n    fill-opacity: .95 !important;\r\n    stroke-opacity: .95 !important;\r\n}\r\n\r\n\r\n.nvd3 .nv-point-paths path {\r\n    stroke: #aaa;\r\n    stroke-opacity: 0;\r\n    fill: #eee;\r\n    fill-opacity: 0;\r\n}\r\n\r\n\r\n.nvd3 .nv-indexLine {\n    cursor: ew-resize;\r\n}\r\n"
  },
  {
    "path": "src/css/main.css",
    "content": "/********************\r\n * SVG CSS\r\n */\r\n\r\n/********************\r\n  Default CSS for an svg element nvd3 used\r\n*/\r\nsvg.nvd3-svg {\r\n    user-select: none;\n    display: block;\r\n    width:100%;\r\n    height:100%;\r\n}\r\n\r\n/********************\r\n  Box shadow and border radius styling\r\n*/\r\n.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {\r\n    box-shadow: 0 5px 10px rgba(0,0,0,.2);\n    border-radius: 5px;\n}\r\n\r\n\r\n.nvd3 text {\r\n    font: normal 12px Arial, sans-serif;\r\n}\r\n\r\n.nvd3 .title {\r\n    font: bold 14px Arial, sans-serif;\r\n}\r\n\r\n.nvd3 .nv-background {\r\n    fill: white;\r\n    fill-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-noData {\r\n    font-size: 18px;\r\n    font-weight: bold;\r\n}\r\n\r\n\r\n/**********\r\n*  Brush\r\n*/\r\n\r\n.nv-brush .extent {\r\n    fill-opacity: .125;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nv-brush .resize path {\r\n    fill: #eee;\r\n    stroke: #666;\r\n}\r\n\r\n\r\n/**********\r\n*  Legend\r\n*/\r\n\r\n.nvd3 .nv-legend .nv-series {\r\n    cursor: pointer;\r\n}\r\n\r\n.nvd3 .nv-legend .nv-disabled circle {\r\n    fill-opacity: 0;\r\n}\r\n\r\n/* focus */\r\n.nvd3 .nv-brush .extent {\r\n    fill-opacity: 0 !important;\r\n}\r\n\r\n.nvd3 .nv-brushBackground rect {\r\n    stroke: #000;\r\n    stroke-width: .4;\r\n    fill: #fff;\r\n    fill-opacity: .7;\r\n}\r\n\r\n/**********\r\n*  Print\r\n*/\r\n\r\n@media print {\r\n    .nvd3 text {\n        stroke-width: 0;\n        fill-opacity: 1;\n    }\n}\r\n"
  },
  {
    "path": "src/css/ohlc.css",
    "content": ".nvd3.nv-ohlcBar .nv-ticks .nv-tick {\r\n    stroke-width: 1px;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover {\r\n    stroke-width: 2px;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive {\r\n    stroke: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative {\r\n    stroke: #d62728;\r\n}\r\n\r\n"
  },
  {
    "path": "src/css/parallelcoordinates.css",
    "content": ".nvd3 .background path {\r\n    fill: none;\r\n    stroke: #EEE;\r\n    stroke-opacity: .4;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .foreground path {\r\n    fill: none;\r\n    stroke-opacity: .7;\r\n}\r\n\r\n.nvd3 .nv-parallelCoordinates-brush .extent {\n    fill: #fff;\r\n    fill-opacity: .6;\r\n    stroke: gray;\r\n    shape-rendering: crispEdges;\r\n}\r\n\r\n.nvd3 .nv-parallelCoordinates .hover  {\r\n    fill-opacity: 1;\r\n\tstroke-width: 3px;\r\n}\r\n\r\n\r\n.nvd3 .missingValuesline line {\r\n  fill: none;\r\n  stroke: black;\r\n  stroke-width: 1;\r\n  stroke-opacity: 1;\r\n  stroke-dasharray: 5, 5;\n}\n"
  },
  {
    "path": "src/css/pie.css",
    "content": ".nvd3.nv-pie path {\r\n    stroke-opacity: 0;\r\n    transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-pie .nv-pie-title {\r\n    font-size: 24px;\r\n    fill: rgba(19, 196, 249, 0.59);\r\n}\r\n\r\n.nvd3.nv-pie .nv-slice text {\r\n    stroke: #000;\r\n    stroke-width: 0;\r\n}\r\n\r\n.nvd3.nv-pie path {\r\n    stroke: #fff;\r\n    stroke-width: 1px;\r\n    stroke-opacity: 1;\r\n}\r\n\r\n.nvd3.nv-pie path {\r\n    fill-opacity: .7;\r\n}\n\n.nvd3.nv-pie .hover path {\r\n    fill-opacity: 1;\r\n}\r\n\n.nvd3.nv-pie .nv-label {\n    pointer-events: none;\r\n}\r\n\n.nvd3.nv-pie .nv-label rect {\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n"
  },
  {
    "path": "src/css/scatter.css",
    "content": "/* scatter */\r\n.nvd3 .nv-groups .nv-point.hover {\r\n    stroke-width: 20px;\r\n    stroke-opacity: .5;\r\n}\r\n\r\n.nvd3 .nv-scatter .nv-point.hover {\r\n    fill-opacity: 1;\r\n}\n\n.nv-noninteractive {\r\n    pointer-events: none;\r\n}\r\n\r\n.nv-distx, .nv-disty {\r\n    pointer-events: none;\r\n}\r\n"
  },
  {
    "path": "src/css/sparkline.css",
    "content": "/* sparkline */\r\n.nvd3.nv-sparkline path {\r\n    fill: none;\r\n}\r\n\r\n.nvd3.nv-sparklineplus g.nv-hoverValue {\r\n    pointer-events: none;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-hoverValue line {\r\n    stroke: #333;\r\n    stroke-width: 1.5px;\r\n}\r\n\r\n.nvd3.nv-sparklineplus,\r\n.nvd3.nv-sparklineplus g {\r\n    pointer-events: all;\r\n}\r\n\r\n.nvd3 .nv-hoverArea {\r\n    fill-opacity: 0;\r\n    stroke-opacity: 0;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-xValue,\r\n.nvd3.nv-sparklineplus .nv-yValue {\r\n    stroke-width: 0;\r\n    font-size: .9em;\r\n    font-weight: normal;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-yValue {\r\n    stroke: #f66;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-maxValue {\r\n    stroke: #2ca02c;\r\n    fill: #2ca02c;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-minValue {\r\n    stroke: #d62728;\r\n    fill: #d62728;\r\n}\r\n\r\n.nvd3.nv-sparklineplus .nv-currentValue {\r\n    font-weight: bold;\r\n    font-size: 1.1em;\r\n}"
  },
  {
    "path": "src/css/stackedarea.css",
    "content": "/* stacked area */\r\n.nvd3.nv-stackedarea path.nv-area {\r\n    fill-opacity: .7;\r\n    stroke-opacity: 0;\r\n    transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;\r\n}\n\r\n.nvd3.nv-stackedarea path.nv-area.hover {\r\n    fill-opacity: .9;\r\n}\r\n\r\n\r\n.nvd3.nv-stackedarea .nv-groups .nv-point {\r\n    stroke-opacity: 0;\r\n    fill-opacity: 0;\r\n}\n"
  },
  {
    "path": "src/css/tooltip.css",
    "content": ".nvtooltip {\n    position: absolute;\r\n    background-color: rgba(255,255,255,1.0);\r\n    color: rgba(0,0,0,1.0);\r\n    padding: 1px;\r\n    border: 1px solid rgba(0,0,0,.2);\r\n    z-index: 10000;\r\n    display: block;\r\n\r\n    font-family: Arial, sans-serif;\r\n    font-size: 13px;\r\n    text-align: left;\r\n    pointer-events: none;\r\n\r\n    white-space: nowrap;\r\n\r\n    user-select: none;\n}\n\r\n.nvtooltip {\r\n    background: rgba(255,255,255, 0.8);\r\n    border: 1px solid rgba(0,0,0,0.5);\r\n    border-radius: 4px;\r\n}\r\n\r\n/*Give tooltips that old fade in transition by\r\n    putting a \"with-transitions\" class on the container div.\r\n*/\r\n.nvtooltip.with-transitions, .with-transitions .nvtooltip {\r\n    transition: opacity 50ms linear;\r\n\n    transition-delay: 200ms;\n}\n\r\n.nvtooltip.x-nvtooltip,\r\n.nvtooltip.y-nvtooltip {\r\n    padding: 8px;\r\n}\r\n\r\n.nvtooltip h3 {\r\n    margin: 0;\r\n    padding: 4px 14px;\r\n    line-height: 18px;\r\n    font-weight: normal;\r\n    background-color: rgba(247,247,247,0.75);\r\n    color: rgba(0,0,0,1.0);\r\n    text-align: center;\r\n\r\n    border-bottom: 1px solid #ebebeb;\r\n\r\n    border-radius: 5px 5px 0 0;\n}\r\n\r\n.nvtooltip p {\r\n    margin: 0;\r\n    padding: 5px 14px;\r\n    text-align: center;\r\n}\r\n\r\n.nvtooltip span {\r\n    display: inline-block;\r\n    margin: 2px 0;\r\n}\r\n\r\n.nvtooltip table {\r\n    margin: 6px;\r\n    border-spacing:0;\r\n}\r\n\r\n\r\n.nvtooltip table td {\r\n    padding: 2px 9px 2px 0;\r\n    vertical-align: middle;\r\n}\r\n\r\n.nvtooltip table td.key {\r\n    font-weight: normal;\r\n}\n\n.nvtooltip table td.key.total {\r\n    font-weight: bold;\r\n}\r\n\n.nvtooltip table td.value {\n    text-align: right;\r\n    font-weight: bold;\r\n}\r\n\r\n.nvtooltip table td.percent {\r\n    color: darkgray;\r\n}\r\n\r\n.nvtooltip table tr.highlight td {\r\n    padding: 1px 9px 1px 0;\r\n    border-bottom-style: solid;\r\n    border-bottom-width: 1px;\r\n    border-top-style: solid;\r\n    border-top-width: 1px;\r\n}\r\n\r\n.nvtooltip table td.legend-color-guide div {\r\n    width: 8px;\r\n    height: 8px;\r\n    vertical-align: middle;\r\n}\r\n\r\n.nvtooltip table td.legend-color-guide div {\r\n    width: 12px;\r\n    height: 12px;\r\n    border: 1px solid #999;\r\n}\r\n\r\n.nvtooltip .footer {\r\n    padding: 3px;\r\n    text-align: center;\r\n}\r\n\r\n.nvtooltip-pending-removal {\r\n    pointer-events: none;\r\n    display: none;\r\n}\r\n\r\n\r\n/****\r\nInteractive Layer\r\n*/\r\n.nvd3 .nv-interactiveGuideLine {\r\n    pointer-events:none;\r\n}\n\n.nvd3 line.nv-guideline {\r\n    stroke: #ccc;\r\n}\r\n"
  },
  {
    "path": "src/dom.js",
    "content": "/* Facade for queueing DOM write operations\r\n * with Fastdom (https://github.com/wilsonpage/fastdom)\r\n * if available.\r\n * This could easily be extended to support alternate\r\n * implementations in the future.\r\n */\r\nnv.dom.write = function(callback) {\r\n\tif (window.fastdom !== undefined) {\r\n\t\treturn fastdom.mutate(callback);\r\n\t}\r\n\treturn callback();\r\n};\r\n\r\n/* Facade for queueing DOM read operations\r\n * with Fastdom (https://github.com/wilsonpage/fastdom)\r\n * if available.\r\n * This could easily be extended to support alternate\r\n * implementations in the future.\r\n */\r\nnv.dom.read = function(callback) {\r\n\tif (window.fastdom !== undefined) {\r\n\t\treturn fastdom.measure(callback);\r\n\t}\r\n\treturn callback();\r\n};\r\n"
  },
  {
    "path": "src/interactiveLayer.js",
    "content": "/* Utility class to handle creation of an interactive layer.\n This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch\n containing the X-coordinate. It can also render a vertical line where the mouse is located.\n\n dispatch.elementMousemove is the important event to latch onto.  It is fired whenever the mouse moves over\n the rectangle. The dispatch is given one object which contains the mouseX/Y location.\n It also has 'pointXValue', which is the conversion of mouseX to the x-axis scale.\n */\nnv.interactiveGuideline = function() {\n    \"use strict\";\n\n    var margin = { left: 0, top: 0 } //Pass the chart's top and left magins. Used to calculate the mouseX/Y.\n        ,   width = null\n        ,   height = null\n        ,   xScale = d3.scale.linear()\n        ,   dispatch = d3.dispatch('elementMousemove', 'elementMouseout', 'elementClick', 'elementDblclick', 'elementMouseDown', 'elementMouseUp')\n        ,   showGuideLine = true\n        ,   svgContainer = null // Must pass the chart's svg, we'll use its mousemove event.\n        ,   tooltip = nv.models.tooltip()\n        ,   isMSIE =  window.ActiveXObject// Checkt if IE by looking for activeX. (excludes IE11)\n    ;\n\n    tooltip\n        .duration(0)\n        .hideDelay(0)\n        .hidden(false);\n\n    function layer(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this);\n            var availableWidth = (width || 960), availableHeight = (height || 400);\n            var wrap = container.selectAll(\"g.nv-wrap.nv-interactiveLineLayer\")\n                .data([data]);\n            var wrapEnter = wrap.enter()\n                .append(\"g\").attr(\"class\", \" nv-wrap nv-interactiveLineLayer\");\n            wrapEnter.append(\"g\").attr(\"class\",\"nv-interactiveGuideLine\");\n\n            if (!svgContainer) {\n                return;\n            }\n\n            function mouseHandler() {\n                var mouseX = d3.event.clientX - this.getBoundingClientRect().left;\n                var mouseY = d3.event.clientY - this.getBoundingClientRect().top;\n\n                var subtractMargin = true;\n                var mouseOutAnyReason = false;\n                if (isMSIE) {\n                    /*\n                     D3.js (or maybe SVG.getScreenCTM) has a nasty bug in Internet Explorer 10.\n                     d3.mouse() returns incorrect X,Y mouse coordinates when mouse moving\n                     over a rect in IE 10.\n                     However, d3.event.offsetX/Y also returns the mouse coordinates\n                     relative to the triggering <rect>. So we use offsetX/Y on IE.\n                     */\n                    mouseX = d3.event.offsetX;\n                    mouseY = d3.event.offsetY;\n\n                    /*\n                     On IE, if you attach a mouse event listener to the <svg> container,\n                     it will actually trigger it for all the child elements (like <path>, <circle>, etc).\n                     When this happens on IE, the offsetX/Y is set to where ever the child element\n                     is located.\n                     As a result, we do NOT need to subtract margins to figure out the mouse X/Y\n                     position under this scenario. Removing the line below *will* cause\n                     the interactive layer to not work right on IE.\n                     */\n                    if(d3.event.target.tagName !== \"svg\") {\n                        subtractMargin = false;\n                    }\n\n                    if (d3.event.target.className.baseVal.match(\"nv-legend\")) {\n                        mouseOutAnyReason = true;\n                    }\n\n                }\n\n                if(subtractMargin) {\n                    mouseX -= margin.left;\n                    mouseY -= margin.top;\n                }\n\n                /* If mouseX/Y is outside of the chart's bounds,\n                 trigger a mouseOut event.\n                 */\n                if (d3.event.type === 'mouseout'\n                    || mouseX < 0 || mouseY < 0\n                    || mouseX > availableWidth || mouseY > availableHeight\n                    || (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined)\n                    || mouseOutAnyReason\n                    ) {\n\n                    if (isMSIE) {\n                        if (d3.event.relatedTarget\n                            && d3.event.relatedTarget.ownerSVGElement === undefined\n                            && (d3.event.relatedTarget.className === undefined\n                                || d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass))) {\n\n                            return;\n                        }\n                    }\n                    dispatch.elementMouseout({\n                        mouseX: mouseX,\n                        mouseY: mouseY\n                    });\n                    layer.renderGuideLine(null); //hide the guideline\n                    tooltip.hidden(true);\n                    return;\n                } else {\n                    tooltip.hidden(false);\n                }\n\n\n                var scaleIsOrdinal = typeof xScale.rangeBands === 'function';\n                var pointXValue = undefined;\n\n                // Ordinal scale has no invert method\n                if (scaleIsOrdinal) {\n                    var elementIndex = d3.bisect(xScale.range(), mouseX) - 1;\n                    // Check if mouseX is in the range band\n                    if (xScale.range()[elementIndex] + xScale.rangeBand() >= mouseX) {\n                        pointXValue = xScale.domain()[d3.bisect(xScale.range(), mouseX) - 1];\n                    }\n                    else {\n                        dispatch.elementMouseout({\n                            mouseX: mouseX,\n                            mouseY: mouseY\n                        });\n                        layer.renderGuideLine(null); //hide the guideline\n                        tooltip.hidden(true);\n                        return;\n                    }\n                }\n                else {\n                    pointXValue = xScale.invert(mouseX);\n                }\n\n                dispatch.elementMousemove({\n                    mouseX: mouseX,\n                    mouseY: mouseY,\n                    pointXValue: pointXValue\n                });\n\n                //If user double clicks the layer, fire a elementDblclick\n                if (d3.event.type === \"dblclick\") {\n                    dispatch.elementDblclick({\n                        mouseX: mouseX,\n                        mouseY: mouseY,\n                        pointXValue: pointXValue\n                    });\n                }\n\n                // if user single clicks the layer, fire elementClick\n                if (d3.event.type === 'click') {\n                    dispatch.elementClick({\n                        mouseX: mouseX,\n                        mouseY: mouseY,\n                        pointXValue: pointXValue\n                    });\n                }\n\n                // if user presses mouse down the layer, fire elementMouseDown\n                if (d3.event.type === 'mousedown') {\n                \tdispatch.elementMouseDown({\n                \t\tmouseX: mouseX,\n                \t\tmouseY: mouseY,\n                \t\tpointXValue: pointXValue\n                \t});\n                }\n\n                // if user presses mouse down the layer, fire elementMouseUp\n                if (d3.event.type === 'mouseup') {\n                \tdispatch.elementMouseUp({\n                \t\tmouseX: mouseX,\n                \t\tmouseY: mouseY,\n                \t\tpointXValue: pointXValue\n                \t});\n                }\n            }\n\n            svgContainer\n                .on(\"touchmove\",mouseHandler)\n                .on(\"mousemove\",mouseHandler, true)\n                .on(\"mouseout\" ,mouseHandler,true)\n                .on(\"mousedown\" ,mouseHandler,true)\n                .on(\"mouseup\" ,mouseHandler,true)\n                .on(\"dblclick\" ,mouseHandler)\n                .on(\"click\", mouseHandler)\n            ;\n\n            layer.guideLine = null;\n            //Draws a vertical guideline at the given X postion.\n            layer.renderGuideLine = function(x) {\n                if (!showGuideLine) return;\n                if (layer.guideLine && layer.guideLine.attr(\"x1\") === x) return;\n                nv.dom.write(function() {\n                    var line = wrap.select(\".nv-interactiveGuideLine\")\n                        .selectAll(\"line\")\n                        .data((x != null) ? [nv.utils.NaNtoZero(x)] : [], String);\n                    line.enter()\n                        .append(\"line\")\n                        .attr(\"class\", \"nv-guideline\")\n                        .attr(\"x1\", function(d) { return d;})\n                        .attr(\"x2\", function(d) { return d;})\n                        .attr(\"y1\", availableHeight)\n                        .attr(\"y2\",0);\n                    line.exit().remove();\n                });\n            }\n        });\n    }\n\n    layer.dispatch = dispatch;\n    layer.tooltip = tooltip;\n\n    layer.margin = function(_) {\n        if (!arguments.length) return margin;\n        margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n        margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        return layer;\n    };\n\n    layer.width = function(_) {\n        if (!arguments.length) return width;\n        width = _;\n        return layer;\n    };\n\n    layer.height = function(_) {\n        if (!arguments.length) return height;\n        height = _;\n        return layer;\n    };\n\n    layer.xScale = function(_) {\n        if (!arguments.length) return xScale;\n        xScale = _;\n        return layer;\n    };\n\n    layer.showGuideLine = function(_) {\n        if (!arguments.length) return showGuideLine;\n        showGuideLine = _;\n        return layer;\n    };\n\n    layer.svgContainer = function(_) {\n        if (!arguments.length) return svgContainer;\n        svgContainer = _;\n        return layer;\n    };\n\n    return layer;\n};\n\n/* Utility class that uses d3.bisect to find the index in a given array, where a search value can be inserted.\n This is different from normal bisectLeft; this function finds the nearest index to insert the search value.\n\n For instance, lets say your array is [1,2,3,5,10,30], and you search for 28.\n Normal d3.bisectLeft will return 4, because 28 is inserted after the number 10.  But interactiveBisect will return 5\n because 28 is closer to 30 than 10.\n\n Unit tests can be found in: interactiveBisectTest.html\n\n Has the following known issues:\n * Will not work if the data points move backwards (ie, 10,9,8,7, etc) or if the data points are in random order.\n * Won't work if there are duplicate x coordinate values.\n */\nnv.interactiveBisect = function (values, searchVal, xAccessor) {\n    \"use strict\";\n    if (! (values instanceof Array)) {\n        return null;\n    }\n    var _xAccessor;\n    if (typeof xAccessor !== 'function') {\n        _xAccessor = function(d) {\n            return d.x;\n        }\n    } else {\n        _xAccessor = xAccessor;\n    }\n    var _cmp = function(d, v) {\n        // Accessors are no longer passed the index of the element along with\n        // the element itself when invoked by d3.bisector.\n        //\n        // Starting at D3 v3.4.4, d3.bisector() started inspecting the\n        // function passed to determine if it should consider it an accessor\n        // or a comparator. This meant that accessors that take two arguments\n        // (expecting an index as the second parameter) are treated as\n        // comparators where the second argument is the search value against\n        // which the first argument is compared.\n        return _xAccessor(d) - v;\n    };\n\n    var bisect = d3.bisector(_cmp).left;\n    var index = d3.max([0, bisect(values,searchVal) - 1]);\n    var currentValue = _xAccessor(values[index]);\n\n    if (typeof currentValue === 'undefined') {\n        currentValue = index;\n    }\n\n    if (currentValue === searchVal) {\n        return index; //found exact match\n    }\n\n    var nextIndex = d3.min([index+1, values.length - 1]);\n    var nextValue = _xAccessor(values[nextIndex]);\n\n    if (typeof nextValue === 'undefined') {\n        nextValue = nextIndex;\n    }\n\n    if (Math.abs(nextValue - searchVal) >= Math.abs(currentValue - searchVal)) {\n        return index;\n    } else {\n        return nextIndex\n    }\n};\n\n/*\n Returns the index in the array \"values\" that is closest to searchVal.\n Only returns an index if searchVal is within some \"threshold\".\n Otherwise, returns null.\n */\nnv.nearestValueIndex = function (values, searchVal, threshold) {\n    \"use strict\";\n    var yDistMax = Infinity, indexToHighlight = null;\n    values.forEach(function(d,i) {\n        var delta = Math.abs(searchVal - d);\n        if ( d != null && delta <= yDistMax && delta < threshold) {\n            yDistMax = delta;\n            indexToHighlight = i;\n        }\n    });\n    return indexToHighlight;\n};\n"
  },
  {
    "path": "src/models/axis.js",
    "content": "nv.models.axis = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var axis = d3.svg.axis();\n    var scale = d3.scale.linear();\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 75 //only used for tickLabel currently\n        , height = 60 //only used for tickLabel currently\n        , axisLabelText = null\n        , showMaxMin = true //TODO: showMaxMin should be disabled on all ordinal scaled axes\n        , rotateLabels = 0\n        , rotateYLabel = true\n        , staggerLabels = false\n        , isOrdinal = false\n        , ticks = null\n        , axisLabelDistance = 0\n        , fontSize = undefined\n        , duration = 250\n        , dispatch = d3.dispatch('renderEnd')\n        , tickFormatMaxMin\n        ;\n    axis\n        .scale(scale)\n        .orient('bottom')\n        .tickFormat(function(d) { return d })\n    ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var scale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-axis').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-axis');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            if (ticks !== null)\n                axis.ticks(ticks);\n            else if (axis.orient() == 'top' || axis.orient() == 'bottom')\n                axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100);\n\n            //TODO: consider calculating width/height based on whether or not label is added, for reference in charts using this component\n            g.watchTransition(renderWatch, 'axis').call(axis);\n\n            scale0 = scale0 || axis.scale();\n\n            var fmt = axis.tickFormat();\n            if (fmt == null) {\n                fmt = scale0.tickFormat();\n            }\n\n            var axisLabel = g.selectAll('text.nv-axislabel')\n                .data([axisLabelText || null]);\n            axisLabel.exit().remove();\n\n            //only skip when fontSize is undefined so it can be cleared with a null or blank string\n            if (fontSize !== undefined) {\n                g.selectAll('g').select(\"text\").style('font-size', fontSize);\n            }\n\n            var xLabelMargin;\n            var axisMaxMin;\n            var w;\n            switch (axis.orient()) {\n                case 'top':\n                    xLabelMargin = axisLabelDistance + 36;\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                  w = 0;\n                  if (scale.range().length === 1) {\n                    w = isOrdinal ? scale.range()[0] * 2 + scale.rangeBand() : 0;\n                  } else if (scale.range().length === 2) {\n                    w = isOrdinal ? scale.range()[0] + scale.range()[1] + scale.rangeBand() : scale.range()[1];\n                  } else if ( scale.range().length > 2){\n                    w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]);\n                  };\n                    axisLabel\n                        .attr('text-anchor', 'middle')\n                        .attr('y', -xLabelMargin)\n                        .attr('x', w/2);\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ')\n                        }).append('text');\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero(scale(d)) + ',0)'\n                            })\n                            .select('text')\n                            .attr('dy', '-0.5em')\n                            .attr('y', -axis.tickPadding())\n                            .attr('text-anchor', 'middle')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max top')\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero(scale.range()[i]) + ',0)'\n                            });\n                    }\n                    break;\n                case 'bottom':\n                    xLabelMargin = axisLabelDistance + 36;\n                    var maxTextWidth = 30;\n                    var textHeight = 0;\n                    var xTicks = g.selectAll('g').select(\"text\");\n                    var rotateLabelsRule = '';\n                    if (rotateLabels%360) {\n                        //Reset transform on ticks so textHeight can be calculated correctly\n                        xTicks.attr('transform', '');\n                        //Calculate the longest xTick width\n                        xTicks.each(function(d,i){\n                            var box = this.getBoundingClientRect();\n                            var width = box.width;\n                            textHeight = box.height;\n                            if(width > maxTextWidth) maxTextWidth = width;\n                        });\n                        rotateLabelsRule = 'rotate(' + rotateLabels + ' 0,' + (textHeight/2 + axis.tickPadding()) + ')';\n                        //Convert to radians before calculating sin. Add 30 to margin for healthy padding.\n                        var sin = Math.abs(Math.sin(rotateLabels*Math.PI/180));\n                        xLabelMargin = (sin ? sin*maxTextWidth : maxTextWidth)+30;\n                        //Rotate all xTicks\n                        xTicks\n                            .attr('transform', rotateLabelsRule)\n                            .style('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');\n                    } else {\n                        if (staggerLabels) {\n                            xTicks\n                                .attr('transform', function(d,i) {\n                                    return 'translate(0,' + (i % 2 == 0 ? '0' : '12') + ')'\n                                });\n                        } else {\n                            xTicks.attr('transform', \"translate(0,0)\");\n                        }\n                    }\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    w = 0;\n                    if (scale.range().length === 1) {\n                        w = isOrdinal ? scale.range()[0] * 2 + scale.rangeBand() : 0;\n                    } else if (scale.range().length === 2) {\n                        w = isOrdinal ? scale.range()[0] + scale.range()[1] + scale.rangeBand() : scale.range()[1];\n                    } else if ( scale.range().length > 2){\n                        w = scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]);\n                    };\n                    axisLabel\n                        .attr('text-anchor', 'middle')\n                        .attr('y', xLabelMargin)\n                        .attr('x', w/2);\n                    if (showMaxMin) {\n                        //if (showMaxMin && !isOrdinal) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            //.data(scale.domain())\n                            .data([scale.domain()[0], scale.domain()[scale.domain().length - 1]]);\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-x',(i == 0 ? 'nv-axisMin-x':'nv-axisMax-x')].join(' ')\n                        }).append('text');\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)'\n                            })\n                            .select('text')\n                            .attr('dy', '.71em')\n                            .attr('y', axis.tickPadding())\n                            .attr('transform', rotateLabelsRule)\n                            .style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max bottom')\n                            .attr('transform', function(d,i) {\n                                return 'translate(' + nv.utils.NaNtoZero((scale(d) + (isOrdinal ? scale.rangeBand() / 2 : 0))) + ',0)'\n                            });\n                    }\n\n                    break;\n                case 'right':\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    axisLabel\n                        .style('text-anchor', rotateYLabel ? 'middle' : 'begin')\n                        .attr('transform', rotateYLabel ? 'rotate(90)' : '')\n                        .attr('y', rotateYLabel ? (-Math.max(margin.right, width) + 12 - (axisLabelDistance || 0)) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart\n                        .attr('x', rotateYLabel ? (d3.max(scale.range()) / 2) : axis.tickPadding());\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                       \taxisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ')\n                        }).append('text')\n                            .style('opacity', 0);\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale(d)) + ')'\n                            })\n                            .select('text')\n                            .attr('dy', '.32em')\n                            .attr('y', 0)\n                            .attr('x', axis.tickPadding())\n                            .style('text-anchor', 'start')\n                            .text(function(d, i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max right')\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')'\n                            })\n                            .select('text')\n                            .style('opacity', 1);\n                    }\n                    break;\n                case 'left':\n                    /*\n                     //For dynamically placing the label. Can be used with dynamically-sized chart axis margins\n                     var yTicks = g.selectAll('g').select(\"text\");\n                     yTicks.each(function(d,i){\n                     var labelPadding = this.getBoundingClientRect().width + axis.tickPadding() + 16;\n                     if(labelPadding > width) width = labelPadding;\n                     });\n                     */\n                    axisLabel.enter().append('text').attr('class', 'nv-axislabel');\n                    axisLabel\n                        .style('text-anchor', rotateYLabel ? 'middle' : 'end')\n                        .attr('transform', rotateYLabel ? 'rotate(-90)' : '')\n                        .attr('y', rotateYLabel ? (-Math.max(margin.left, width) + 25 - (axisLabelDistance || 0)) : -10)\n                        .attr('x', rotateYLabel ? (-d3.max(scale.range()) / 2) : -axis.tickPadding());\n                    if (showMaxMin) {\n                        axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')\n                            .data(scale.domain());\n                        axisMaxMin.enter().append('g').attr('class',function(d,i){\n                                return ['nv-axisMaxMin','nv-axisMaxMin-y',(i == 0 ? 'nv-axisMin-y':'nv-axisMax-y')].join(' ')\n                        }).append('text')\n                            .style('opacity', 0);\n                        axisMaxMin.exit().remove();\n                        axisMaxMin\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale0(d)) + ')'\n                            })\n                            .select('text')\n                            .attr('dy', '.32em')\n                            .attr('y', 0)\n                            .attr('x', -axis.tickPadding())\n                            .attr('text-anchor', 'end')\n                            .text(function(d,i) {\n                                var formatter = tickFormatMaxMin || fmt;\n                                var v = formatter(d);\n                                return ('' + v).match('NaN') ? '' : v;\n                            });\n                        axisMaxMin.watchTransition(renderWatch, 'min-max right')\n                            .attr('transform', function(d,i) {\n                                return 'translate(0,' + nv.utils.NaNtoZero(scale.range()[i]) + ')'\n                            })\n                            .select('text')\n                            .style('opacity', 1);\n                    }\n                    break;\n            }\n            axisLabel.text(function(d) { return d });\n\n            if (showMaxMin && (axis.orient() === 'left' || axis.orient() === 'right')) {\n                //check if max and min overlap other values, if so, hide the values that overlap\n                g.selectAll('g') // the g's wrapping each tick\n                    .each(function(d,i) {\n                        d3.select(this).select('text').attr('opacity', 1);\n                        if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it!\n                            if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL\n                                d3.select(this).attr('opacity', 0);\n\n                            d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!!\n                        }\n                    });\n\n                //if Max and Min = 0 only show min, Issue #281\n                if (scale.domain()[0] == scale.domain()[1] && scale.domain()[0] == 0) {\n                    wrap.selectAll('g.nv-axisMaxMin').style('opacity', function (d, i) {\n                        return !i ? 1 : 0\n                    });\n                }\n            }\n\n            if (showMaxMin && (axis.orient() === 'top' || axis.orient() === 'bottom')) {\n                var maxMinRange = [];\n                wrap.selectAll('g.nv-axisMaxMin')\n                    .each(function(d,i) {\n                        try {\n                            if (i) // i== 1, max position\n                                maxMinRange.push(scale(d) - this.getBoundingClientRect().width - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)\n                            else // i==0, min position\n                                maxMinRange.push(scale(d) + this.getBoundingClientRect().width + 4)\n                        }catch (err) {\n                            if (i) // i== 1, max position\n                                maxMinRange.push(scale(d) - 4);  //assuming the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)\n                            else // i==0, min position\n                                maxMinRange.push(scale(d) + 4);\n                        }\n                    });\n                // the g's wrapping each tick\n                g.selectAll('g').each(function(d, i) {\n                    if (scale(d) < maxMinRange[0] || scale(d) > maxMinRange[1]) {\n                        if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL\n                            d3.select(this).remove();\n                        else\n                            d3.select(this).select('text').remove(); // Don't remove the ZERO line!!\n                    }\n                });\n            }\n\n            //Highlight zero tick line\n            g.selectAll('.tick')\n                .filter(function (d) {\n                    /*\n                    The filter needs to return only ticks at or near zero.\n                    Numbers like 0.00001 need to count as zero as well,\n                    and the arithmetic trick below solves that.\n                    */\n                    return !parseFloat(Math.round(d * 100000) / 1000000) && (d !== undefined)\n                })\n                .classed('zero', true);\n\n            //store old scales for use in transitions on update\n            scale0 = scale.copy();\n\n        });\n\n        renderWatch.renderEnd('axis immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.axis = axis;\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        axisLabelDistance: {get: function(){return axisLabelDistance;}, set: function(_){axisLabelDistance=_;}},\n        staggerLabels:     {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:      {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        rotateYLabel:      {get: function(){return rotateYLabel;}, set: function(_){rotateYLabel=_;}},\n        showMaxMin:        {get: function(){return showMaxMin;}, set: function(_){showMaxMin=_;}},\n        axisLabel:         {get: function(){return axisLabelText;}, set: function(_){axisLabelText=_;}},\n        height:            {get: function(){return height;}, set: function(_){height=_;}},\n        ticks:             {get: function(){return ticks;}, set: function(_){ticks=_;}},\n        width:             {get: function(){return width;}, set: function(_){width=_;}},\n        fontSize:          {get: function(){return fontSize;}, set: function(_){fontSize=_;}},\n        tickFormatMaxMin:  {get: function(){return tickFormatMaxMin;}, set: function(_){tickFormatMaxMin=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top !== undefined    ? _.top    : margin.top;\n            margin.right  = _.right !== undefined  ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left !== undefined   ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration=_;\n            renderWatch.reset(duration);\n        }},\n        scale: {get: function(){return scale;}, set: function(_){\n            scale = _;\n            axis.scale(scale);\n            isOrdinal = typeof scale.rangeBands === 'function';\n            nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    nv.utils.inheritOptionsD3(chart, axis, ['orient', 'tickValues', 'tickSubdivide', 'tickSize', 'tickPadding', 'tickFormat']);\n    nv.utils.inheritOptionsD3(chart, scale, ['domain', 'range', 'rangeBand', 'rangeBands']);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/boxPlot.js",
    "content": "nv.models.boxPlot = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0},\n        width = 960,\n        height = 500,\n        id = Math.floor(Math.random() * 10000), // Create semi-unique ID in case user doesn't select one\n        xScale = d3.scale.ordinal(),\n        yScale = d3.scale.linear(),\n        getX  = function(d) { return d.label }, // Default data model selectors.\n        getQ1 = function(d) { return d.values.Q1 },\n        getQ2 = function(d) { return d.values.Q2 },\n        getQ3 = function(d) { return d.values.Q3 },\n        getWl = function(d) { return d.values.whisker_low },\n        getWh = function(d) { return d.values.whisker_high },\n        getColor = function(d) { return d.color },\n        getOlItems  = function(d) { return d.values.outliers },\n        getOlValue = function(d, i, j) { return d },\n        getOlLabel = function(d, i, j) { return d },\n        getOlColor = function(d, i, j) { return undefined },\n        color = nv.utils.defaultColor(),\n        container = null,\n        xDomain, xRange,\n        yDomain, yRange,\n        dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd'),\n        duration = 250,\n        maxBoxWidth = null;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var xScale0, yScale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            xScale.domain(xDomain || data.map(function(d,i) { return getX(d,i); }))\n                .rangeBands(xRange || [0, availableWidth], 0.1);\n\n            // if we know yDomain, no need to calculate\n            var yData = []\n            if (!yDomain) {\n                // (y-range is based on quartiles, whiskers and outliers)\n                var values = [], yMin, yMax;\n                data.forEach(function (d, i) {\n                    var q1 = getQ1(d), q3 = getQ3(d), wl = getWl(d), wh = getWh(d);\n                    var olItems = getOlItems(d);\n                    if (olItems) {\n                        olItems.forEach(function (e, i) {\n                            values.push(getOlValue(e, i, undefined));\n                        });\n                    }\n                    if (wl) { values.push(wl) }\n                    if (q1) { values.push(q1) }\n                    if (q3) { values.push(q3) }\n                    if (wh) { values.push(wh) }\n                });\n                yMin = d3.min(values);\n                yMax = d3.max(values);\n                yData = [ yMin, yMax ] ;\n            }\n\n            yScale.domain(yDomain || yData);\n            yScale.range(yRange || [availableHeight, 0]);\n\n            //store old scales if they exist\n            xScale0 = xScale0 || xScale;\n            yScale0 = yScale0 || yScale.copy().range([yScale(0),yScale(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var boxplots = wrap.selectAll('.nv-boxplot').data(function(d) { return d });\n            var boxEnter = boxplots.enter().append('g').style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6);\n            boxplots\n                .attr('class', 'nv-boxplot')\n                .attr('transform', function(d,i,j) { return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)'; })\n                .classed('hover', function(d) { return d.hover });\n            boxplots\n                .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', 0.75)\n                .delay(function(d,i) { return i * duration / data.length })\n                .attr('transform', function(d,i) {\n                    return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)';\n                });\n            boxplots.exit().remove();\n\n            // ----- add the SVG elements for each boxPlot -----\n\n            // conditionally append whisker lines\n            boxEnter.each(function(d,i) {\n                var box = d3.select(this);\n                [getWl, getWh].forEach(function (f) {\n                    if (f(d) !== undefined && f(d) !== null) {\n                        var key = (f === getWl) ? 'low' : 'high';\n                        box.append('line')\n                          .style('stroke', getColor(d) || color(d,i))\n                          .attr('class', 'nv-boxplot-whisker nv-boxplot-' + key);\n                        box.append('line')\n                          .style('stroke', getColor(d) || color(d,i))\n                          .attr('class', 'nv-boxplot-tick nv-boxplot-' + key);\n                    }\n                });\n            });\n\n            var box_width = function() { return (maxBoxWidth === null ? xScale.rangeBand() * 0.9 : Math.min(75, xScale.rangeBand() * 0.9)); };\n            var box_left  = function() { return xScale.rangeBand() * 0.45 - box_width()/2; };\n            var box_right = function() { return xScale.rangeBand() * 0.45 + box_width()/2; };\n\n            // update whisker lines and ticks\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                var endpoint = (f === getWl) ? getQ1 : getQ3;\n                boxplots.select('line.nv-boxplot-whisker.nv-boxplot-' + key)\n                  .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                    .attr('x1', xScale.rangeBand() * 0.45 )\n                    .attr('y1', function(d,i) { return yScale(f(d)); })\n                    .attr('x2', xScale.rangeBand() * 0.45 )\n                    .attr('y2', function(d,i) { return yScale(endpoint(d)); });\n                boxplots.select('line.nv-boxplot-tick.nv-boxplot-' + key)\n                  .watchTransition(renderWatch, 'nv-boxplot: boxplots')\n                    .attr('x1', box_left )\n                    .attr('y1', function(d,i) { return yScale(f(d)); })\n                    .attr('x2', box_right )\n                    .attr('y2', function(d,i) { return yScale(f(d)); });\n            });\n\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                boxEnter.selectAll('.nv-boxplot-' + key)\n                  .on('mouseover', function(d,i,j) {\n                      d3.select(this).classed('hover', true);\n                      dispatch.elementMouseover({\n                          series: { key: f(d), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mouseout', function(d,i,j) {\n                      d3.select(this).classed('hover', false);\n                      dispatch.elementMouseout({\n                          series: { key: f(d), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mousemove', function(d,i) {\n                      dispatch.elementMousemove({e: d3.event});\n                  });\n            });\n\n            // boxes\n            boxEnter.append('rect')\n                .attr('class', 'nv-boxplot-box')\n                // tooltip events\n                .on('mouseover', function(d,i) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        key: getX(d),\n                        value: getX(d),\n                        series: [\n                            { key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        key: getX(d),\n                        value: getX(d),\n                        series: [\n                            { key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },\n                            { key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n            // box transitions\n            boxplots.select('rect.nv-boxplot-box')\n              .watchTransition(renderWatch, 'nv-boxplot: boxes')\n                .attr('y', function(d,i) { return yScale(getQ3(d)); })\n                .attr('width', box_width)\n                .attr('x', box_left )\n                .attr('height', function(d,i) { return Math.abs(yScale(getQ3(d)) - yScale(getQ1(d))) || 1 })\n                .style('fill', function(d,i) { return getColor(d) || color(d,i) })\n                .style('stroke', function(d,i) { return getColor(d) || color(d,i) });\n\n            // median line\n            boxEnter.append('line').attr('class', 'nv-boxplot-median');\n\n            boxplots.select('line.nv-boxplot-median')\n              .watchTransition(renderWatch, 'nv-boxplot: boxplots line')\n                .attr('x1', box_left)\n                .attr('y1', function(d,i) { return yScale(getQ2(d)); })\n                .attr('x2', box_right)\n                .attr('y2', function(d,i) { return yScale(getQ2(d)); });\n\n            // outliers\n            var outliers = boxplots.selectAll('.nv-boxplot-outlier').data(function(d) {\n                return getOlItems(d) || [];\n            });\n            outliers.enter().append('circle')\n                .style('fill', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })\n                .style('stroke', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })\n                .style('z-index', 9000)\n                .on('mouseover', function(d,i,j) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n            outliers.attr('class', 'nv-boxplot-outlier');\n            outliers\n              .watchTransition(renderWatch, 'nv-boxplot: nv-boxplot-outlier')\n                .attr('cx', xScale.rangeBand() * 0.45)\n                .attr('cy', function(d,i,j) { return yScale(getOlValue(d,i,j)); })\n                .attr('r', '3');\n            outliers.exit().remove();\n\n            //store old scales for use in transitions on update\n            xScale0 = xScale.copy();\n            yScale0 = yScale.copy();\n        });\n\n        renderWatch.renderEnd('nv-boxplot immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:       {get: function(){return width;}, set: function(_){width=_;}},\n        height:      {get: function(){return height;}, set: function(_){height=_;}},\n        maxBoxWidth: {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}},\n        x:           {get: function(){return getX;}, set: function(_){getX=_;}},\n        q1: {get: function(){return getQ1;}, set: function(_){getQ1=_;}},\n        q2: {get: function(){return getQ2;}, set: function(_){getQ2=_;}},\n        q3: {get: function(){return getQ3;}, set: function(_){getQ3=_;}},\n        wl: {get: function(){return getWl;}, set: function(_){getWl=_;}},\n        wh: {get: function(){return getWh;}, set: function(_){getWh=_;}},\n        itemColor:    {get: function(){return getColor;}, set: function(_){getColor=_;}},\n        outliers:     {get: function(){return getOlItems;}, set: function(_){getOlItems=_;}},\n        outlierValue: {get: function(){return getOlValue;}, set: function(_){getOlValue=_;}},\n        outlierLabel: {get: function(){return getOlLabel;}, set: function(_){getOlLabel=_;}},\n        outlierColor: {get: function(){return getOlColor;}, set: function(_){getOlColor=_;}},\n        xScale:  {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:  {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        // rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}},\n        y: {\n            get: function() {\n                console.warn('BoxPlot \\'y\\' chart option is deprecated. Please use model overrides instead.');\n                return {};\n            },\n            set: function(_) {\n                console.warn('BoxPlot \\'y\\' chart option is deprecated. Please use model overrides instead.');\n            }\n        },\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/boxPlotChart.js",
    "content": "nv.models.boxPlotChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var boxplot = nv.models.boxPlot(),\n        xAxis = nv.models.axis(),\n        yAxis = nv.models.axis();\n\n    var margin = {top: 15, right: 10, bottom: 50, left: 60},\n        width = null,\n        height = null,\n        color = nv.utils.getColor(),\n        showXAxis = true,\n        showYAxis = true,\n        rightAlignYAxis = false,\n        staggerLabels = false,\n        tooltip = nv.models.tooltip(),\n        x, y,\n        noData = 'No Data Available.',\n        dispatch = d3.dispatch('beforeUpdate', 'renderEnd'),\n        duration = 250;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip.duration(0);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(boxplot);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this), that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = (width  || parseInt(container.style('width')) || 960) - margin.left - margin.right;\n            var availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // TODO still need to find a way to validate quartile data presence using boxPlot callbacks.\n            // Display No Data message if there's nothing to show. (quartiles required at minimum).\n            if (!data || !data.length) {\n                var noDataText = container.selectAll('.nv-noData').data([noData]);\n\n                noDataText.enter().append('text')\n                    .attr('class', 'nvd3 nv-noData')\n                    .attr('dy', '-.7em')\n                    .style('text-anchor', 'middle');\n\n                noDataText\n                    .attr('x', margin.left + availableWidth / 2)\n                    .attr('y', margin.top + availableHeight / 2)\n                    .text(function(d) { return d });\n\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = boxplot.xScale();\n            y = boxplot.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-boxPlotWithAxes').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-boxPlotWithAxes').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(' + availableWidth + ',0)');\n            }\n\n            // Main Chart Component(s)\n            boxplot.width(availableWidth).height(availableHeight);\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }))\n\n            barsWrap.transition().call(boxplot);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + boxplot.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + boxplot.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    .ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis').attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 === 0 ? '5' : '17') + ')' })\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    .ticks( Math.floor(availableHeight/36) ) // can't use nv.utils.calcTicksY with Object data\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select('.nv-zeroLine line')\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', y(0))\n                .attr('y2', y(0))\n            ;\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n        });\n\n        renderWatch.renderEnd('nv-boxplot chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    boxplot.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    boxplot.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.data(evt).hidden(true);\n    });\n\n    boxplot.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.boxplot = boxplot;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        tooltipContent:    {get: function(){return tooltip;}, set: function(_){tooltip=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            boxplot.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            boxplot.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, boxplot);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n"
  },
  {
    "path": "src/models/bullet.js",
    "content": "\n// Chart design based on the recommendations of Stephen Few. Implementation\n// based on the work of Clint Ivy, Jamie Love, and Jason Davies.\n// http://projects.instantcognition.com/protovis/bulletchart/\n\nnv.models.bullet = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , orient = 'left' // TODO top & bottom\n        , reverse = false\n        , ranges = function(d) { return d.ranges }\n        , markers = function(d) { return d.markers ? d.markers : [] }\n        , markerLines = function(d) { return d.markerLines ? d.markerLines : [0] }\n        , measures = function(d) { return d.measures }\n        , rangeLabels = function(d) { return d.rangeLabels ? d.rangeLabels : [] }\n        , markerLabels = function(d) { return d.markerLabels ? d.markerLabels : []  }\n        , markerLineLabels = function(d) { return d.markerLineLabels ? d.markerLineLabels : []  }\n        , measureLabels = function(d) { return d.measureLabels ? d.measureLabels : []  }\n        , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)\n        , width = 380\n        , height = 30\n        , container = null\n        , tickFormat = null\n        , color = nv.utils.getColor(['#1f77b4'])\n        , dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove')\n        , defaultRangeLabels = [\"Maximum\", \"Mean\", \"Minimum\"]\n        , legacyRangeClassNames = [\"Max\", \"Avg\", \"Min\"]\n        , duration = 1000\n        ;\n\n    function sortLabels(labels, values){\n        var lz = labels.slice();\n        labels.sort(function(a, b){\n            var iA = lz.indexOf(a);\n            var iB = lz.indexOf(b);\n            return d3.descending(values[iA], values[iB]);\n        });\n    };\n\n    function chart(selection) {\n        selection.each(function(d, i) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var rangez = ranges.call(this, d, i).slice(),\n                markerz = markers.call(this, d, i).slice(),\n                markerLinez = markerLines.call(this, d, i).slice(),\n                measurez = measures.call(this, d, i).slice(),\n                rangeLabelz = rangeLabels.call(this, d, i).slice(),\n                markerLabelz = markerLabels.call(this, d, i).slice(),\n                markerLineLabelz = markerLineLabels.call(this, d, i).slice(),\n                measureLabelz = measureLabels.call(this, d, i).slice();\n\n            // Sort labels according to their sorted values\n            sortLabels(rangeLabelz, rangez);\n            sortLabels(markerLabelz, markerz);\n            sortLabels(markerLineLabelz, markerLinez);\n            sortLabels(measureLabelz, measurez);\n\n            // sort values descending\n            rangez.sort(d3.descending);\n            markerz.sort(d3.descending);\n            markerLinez.sort(d3.descending);\n            measurez.sort(d3.descending);\n\n            // Setup Scales\n            // Compute the new x-scale.\n            var x1 = d3.scale.linear()\n                .domain( d3.extent(d3.merge([forceX, rangez])) )\n                .range(reverse ? [availableWidth, 0] : [0, availableWidth]);\n\n            // Retrieve the old x-scale, if this is an update.\n            var x0 = this.__chart__ || d3.scale.linear()\n                .domain([0, Infinity])\n                .range(x1.range());\n\n            // Stash the new scale.\n            this.__chart__ = x1;\n\n            var rangeMin = d3.min(rangez), //rangez[2]\n                rangeMax = d3.max(rangez), //rangez[0]\n                rangeAvg = rangez[1];\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            for(var i=0,il=rangez.length; i<il; i++){\n                var rangeClassNames = 'nv-range nv-range'+i;\n                if(i <= 2){\n                    rangeClassNames = rangeClassNames + ' nv-range'+legacyRangeClassNames[i];\n                }\n                gEnter.append('rect').attr('class', rangeClassNames);\n            }\n\n            gEnter.append('rect').attr('class', 'nv-measure');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)\n                w1 = function(d) { return Math.abs(x1(d) - x1(0)) };\n            var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },\n                xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };\n\n            for(var i=0,il=rangez.length; i<il; i++){\n                var range = rangez[i];\n                g.select('rect.nv-range'+i)\n                    .datum(range)\n                    .attr('height', availableHeight)\n                    .transition()\n                    .duration(duration)\n                    .attr('width', w1(range))\n                    .attr('x', xp1(range))\n            }\n\n            g.select('rect.nv-measure')\n                .style('fill', color)\n                .attr('height', availableHeight / 3)\n                .attr('y', availableHeight / 3)\n                .on('mouseover', function() {\n                    dispatch.elementMouseover({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mousemove', function() {\n                    dispatch.elementMousemove({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mouseout', function() {\n                    dispatch.elementMouseout({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Current',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .transition()\n                .duration(duration)\n                .attr('width', measurez < 0 ?\n                    x1(0) - x1(measurez[0])\n                    : x1(measurez[0]) - x1(0))\n                .attr('x', xp1(measurez));\n\n            var h3 =  availableHeight / 6;\n\n            var markerData = markerz.map( function(marker, index) {\n                return {value: marker, label: markerLabelz[index]}\n            });\n            gEnter\n              .selectAll(\"path.nv-markerTriangle\")\n              .data(markerData)\n              .enter()\n              .append('path')\n              .attr('class', 'nv-markerTriangle')\n              .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z')\n              .on('mouseover', function(d) {\n                dispatch.elementMouseover({\n                  value: d.value,\n                  label: d.label || 'Previous',\n                  color: d3.select(this).style(\"fill\"),\n                  pos: [x1(d.value), availableHeight/2]\n                })\n\n              })\n              .on('mousemove', function(d) {\n                  dispatch.elementMousemove({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              })\n              .on('mouseout', function(d, i) {\n                  dispatch.elementMouseout({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              });\n\n            g.selectAll(\"path.nv-markerTriangle\")\n              .data(markerData)\n              .transition()\n              .duration(duration)\n              .attr('transform', function(d) { return 'translate(' + x1(d.value) + ',' + (availableHeight / 2) + ')' });\n\n            var markerLinesData = markerLinez.map( function(marker, index) {\n                return {value: marker, label: markerLineLabelz[index]}\n            });\n            gEnter\n              .selectAll(\"line.nv-markerLine\")\n              .data(markerLinesData)\n              .enter()\n              .append('line')\n              .attr('cursor', '')\n              .attr('class', 'nv-markerLine')\n              .attr('x1', function(d) { return x1(d.value) })\n              .attr('y1', '2')\n              .attr('x2', function(d) { return x1(d.value) })\n              .attr('y2', availableHeight - 2)\n              .on('mouseover', function(d) {\n                dispatch.elementMouseover({\n                  value: d.value,\n                  label: d.label || 'Previous',\n                  color: d3.select(this).style(\"fill\"),\n                  pos: [x1(d.value), availableHeight/2]\n                })\n\n              })\n              .on('mousemove', function(d) {\n                  dispatch.elementMousemove({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              })\n              .on('mouseout', function(d, i) {\n                  dispatch.elementMouseout({\n                      value: d.value,\n                      label: d.label || 'Previous',\n                      color: d3.select(this).style(\"fill\")\n                  })\n              });\n\n            g.selectAll(\"line.nv-markerLine\")\n              .data(markerLinesData)\n              .transition()\n              .duration(duration)\n              .attr('x1', function(d) { return x1(d.value) })\n              .attr('x2', function(d) { return x1(d.value) });\n\n            wrap.selectAll('.nv-range')\n                .on('mouseover', function(d,i) {\n                    var label = rangeLabelz[i] || defaultRangeLabels[i];\n                    dispatch.elementMouseover({\n                        value: d,\n                        label: label,\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mousemove', function() {\n                    dispatch.elementMousemove({\n                        value: measurez[0],\n                        label: measureLabelz[0] || 'Previous',\n                        color: d3.select(this).style(\"fill\")\n                    })\n                })\n                .on('mouseout', function(d,i) {\n                    var label = rangeLabelz[i] || defaultRangeLabels[i];\n                    dispatch.elementMouseout({\n                        value: d,\n                        label: label,\n                        color: d3.select(this).style(\"fill\")\n                    })\n                });\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        ranges:      {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good)\n        markers:     {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal)\n        measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast)\n        forceX:      {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n        tickFormat:    {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}},\n        duration:    {get: function(){return duration;}, set: function(_){duration=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom\n            orient = _;\n            reverse = orient == 'right' || orient == 'bottom';\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n\n\n"
  },
  {
    "path": "src/models/bulletChart.js",
    "content": "\n// Chart design based on the recommendations of Stephen Few. Implementation\n// based on the work of Clint Ivy, Jamie Love, and Jason Davies.\n// http://projects.instantcognition.com/protovis/bulletchart/\nnv.models.bulletChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var bullet = nv.models.bullet();\n    var tooltip = nv.models.tooltip();\n\n    var orient = 'left' // TODO top & bottom\n        , reverse = false\n        , margin = {top: 5, right: 40, bottom: 20, left: 120}\n        , ranges = function(d) { return d.ranges }\n        , markers = function(d) { return d.markers ? d.markers : [] }\n        , measures = function(d) { return d.measures }\n        , width = null\n        , height = 55\n        , tickFormat = null\n        , ticks = null\n        , noData = null\n        , dispatch = d3.dispatch()\n        ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false);\n\n    function chart(selection) {\n        selection.each(function(d, i) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = height - margin.top - margin.bottom,\n                that = this;\n\n            chart.update = function() { chart(selection) };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!d || !ranges.call(this, d, i)) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var rangez = ranges.call(this, d, i).slice().sort(d3.descending),\n                markerz = markers.call(this, d, i).slice().sort(d3.descending),\n                measurez = measures.call(this, d, i).slice().sort(d3.descending);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-bulletChart').data([d]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bulletChart');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-bulletWrap');\n            gEnter.append('g').attr('class', 'nv-titles');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Compute the new x-scale.\n            var x1 = d3.scale.linear()\n                .domain([0, Math.max(rangez[0], (markerz[0] || 0), measurez[0])])  // TODO: need to allow forceX and forceY, and xDomain, yDomain\n                .range(reverse ? [availableWidth, 0] : [0, availableWidth]);\n\n            // Retrieve the old x-scale, if this is an update.\n            var x0 = this.__chart__ || d3.scale.linear()\n                .domain([0, Infinity])\n                .range(x1.range());\n\n            // Stash the new scale.\n            this.__chart__ = x1;\n\n            var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)\n                w1 = function(d) { return Math.abs(x1(d) - x1(0)) };\n\n            var title = gEnter.select('.nv-titles').append('g')\n                .attr('text-anchor', 'end')\n                .attr('transform', 'translate(-6,' + (height - margin.top - margin.bottom) / 2 + ')');\n            title.append('text')\n                .attr('class', 'nv-title')\n                .text(function(d) { return d.title; });\n\n            title.append('text')\n                .attr('class', 'nv-subtitle')\n                .attr('dy', '1em')\n                .text(function(d) { return d.subtitle; });\n\n            bullet\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var bulletWrap = g.select('.nv-bulletWrap');\n            d3.transition(bulletWrap).call(bullet);\n\n            // Compute the tick format.\n            var format = tickFormat || x1.tickFormat( availableWidth / 100 );\n\n            // Update the tick groups.\n            var tick = g.selectAll('g.nv-tick')\n                .data(x1.ticks( ticks ? ticks : (availableWidth / 50) ), function(d) {\n                    return this.textContent || format(d);\n                });\n\n            // Initialize the ticks with the old scale, x0.\n            var tickEnter = tick.enter().append('g')\n                .attr('class', 'nv-tick')\n                .attr('transform', function(d) { return 'translate(' + x0(d) + ',0)' })\n                .style('opacity', 1e-6);\n\n            tickEnter.append('line')\n                .attr('y1', availableHeight)\n                .attr('y2', availableHeight * 7 / 6);\n\n            tickEnter.append('text')\n                .attr('text-anchor', 'middle')\n                .attr('dy', '1em')\n                .attr('y', availableHeight * 7 / 6)\n                .text(format);\n\n            // Transition the updating ticks to the new scale, x1.\n            var tickUpdate = d3.transition(tick)\n                .transition()\n                .duration(bullet.duration())\n                .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' })\n                .style('opacity', 1);\n\n            tickUpdate.select('line')\n                .attr('y1', availableHeight)\n                .attr('y2', availableHeight * 7 / 6);\n\n            tickUpdate.select('text')\n                .attr('y', availableHeight * 7 / 6);\n\n            // Transition the exiting ticks to the new scale, x1.\n            d3.transition(tick.exit())\n                .transition()\n                .duration(bullet.duration())\n                .attr('transform', function(d) { return 'translate(' + x1(d) + ',0)' })\n                .style('opacity', 1e-6)\n                .remove();\n        });\n\n        d3.timer.flush();\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    bullet.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: evt.label,\n            value: evt.value,\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    bullet.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bullet.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.bullet = bullet;\n    chart.dispatch = dispatch;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        ranges:      {get: function(){return ranges;}, set: function(_){ranges=_;}}, // ranges (bad, satisfactory, good)\n        markers:     {get: function(){return markers;}, set: function(_){markers=_;}}, // markers (previous, goal)\n        measures: {get: function(){return measures;}, set: function(_){measures=_;}}, // measures (actual, forecast)\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n        tickFormat:    {get: function(){return tickFormat;}, set: function(_){tickFormat=_;}},\n        ticks:    {get: function(){return ticks;}, set: function(_){ticks=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        orient: {get: function(){return orient;}, set: function(_){ // left, right, top, bottom\n            orient = _;\n            reverse = orient == 'right' || orient == 'bottom';\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, bullet);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\n\n"
  },
  {
    "path": "src/models/candlestickBar.js",
    "content": "\nnv.models.candlestickBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getOpen = function(d) { return d.open }\n        , getClose = function(d) { return d.close }\n        , getHigh = function(d) { return d.high }\n        , getLow = function(d) { return d.low }\n        , forceX = []\n        , forceY = []\n        , padData     = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , interactive = false\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // Width of the candlestick bars.\n            var barWidth = (availableWidth / data[0].values.length) * .45;\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [5 + barWidth / 2, availableWidth - barWidth / 2 - 5]);\n\n            y.domain(yDomain || [\n                    d3.min(data[0].values.map(getLow).concat(forceY)),\n                    d3.max(data[0].values.map(getHigh).concat(forceY))\n                ]\n            ).range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-candlestickBar').data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-candlestickBar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-ticks');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')\n                .data(function(d) { return d });\n            ticks.exit().remove();\n\n            var tickGroups = ticks.enter().append('g');\n\n            // The colors are currently controlled by CSS.\n            ticks\n                .attr('class', function(d, i, j) { return (getOpen(d, i) > getClose(d, i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i});\n\n            var lines = tickGroups.append('line')\n                .attr('class', 'nv-candlestick-lines')\n                .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; })\n                .attr('x1', 0)\n                .attr('y1', function(d, i) { return y(getHigh(d, i)); })\n                .attr('x2', 0)\n                .attr('y2', function(d, i) { return y(getLow(d, i)); });\n\n            var rects = tickGroups.append('rect')\n                .attr('class', 'nv-candlestick-rects nv-bars')\n                .attr('transform', function(d, i) {\n                    return 'translate(' + (x(getX(d, i)) - barWidth/2) + ','\n                    + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0))\n                    + ')';\n                })\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('width', barWidth)\n                .attr('height', function(d, i) {\n                    var open = getOpen(d, i);\n                    var close = getClose(d, i);\n                    return open > close ? y(close) - y(open) : y(open) - y(close);\n                });\n\n            ticks.select('.nv-candlestick-lines').transition()\n                .attr('transform', function(d, i) { return 'translate(' + x(getX(d, i)) + ',0)'; })\n                .attr('x1', 0)\n                .attr('y1', function(d, i) { return y(getHigh(d, i)); })\n                .attr('x2', 0)\n                .attr('y2', function(d, i) { return y(getLow(d, i)); });\n\n            ticks.select('.nv-candlestick-rects').transition()\n                .attr('transform', function(d, i) {\n                    return 'translate(' + (x(getX(d, i)) - barWidth/2) + ','\n                    + (y(getY(d, i)) - (getOpen(d, i) > getClose(d, i) ? (y(getClose(d, i)) - y(getOpen(d, i))) : 0))\n                    + ')';\n                })\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('width', barWidth)\n                .attr('height', function(d, i) {\n                    var open = getOpen(d, i);\n                    var close = getClose(d, i);\n                    return open > close ? y(close) - y(open) : y(open) - y(close);\n                });\n        });\n\n        return chart;\n    }\n\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        chart.clearHighlights();\n        container.select(\".nv-candlestickBar .nv-tick-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container.select(\".nv-candlestickBar .nv-tick.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:   {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:   {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:   {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:   {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:   {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceX:   {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:   {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData:  {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:       {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        x:     {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:     {get: function(){return getY;}, set: function(_){getY=_;}},\n        open:  {get: function(){return getOpen();}, set: function(_){getOpen=_;}},\n        close: {get: function(){return getClose();}, set: function(_){getClose=_;}},\n        high:  {get: function(){return getHigh;}, set: function(_){getHigh=_;}},\n        low:   {get: function(){return getLow;}, set: function(_){getLow=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/cumulativeLineChart.js",
    "content": "\nnv.models.cumulativeLineChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 30, bottom: 50, left: 60}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = true\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , showControls = true\n        , useInteractiveGuideline = false\n        , rescaleY = true\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , id = lines.id()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , average = function(d) { return d.average }\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , transitionDuration = 250\n        , duration = 250\n        , noErrorCheck = false  //if set to TRUE, will bypass an error check in the indexify function.\n        ;\n\n    state.index = 0;\n    state.rescaleY = rescaleY;\n\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient((rightAlignYAxis) ? 'right' : 'left');\n\n    tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var dx = d3.scale.linear()\n        , index = {i: 0, x: 0}\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        , currentYDomain\n        ;\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                index: index.i,\n                rescaleY: rescaleY\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.index !== undefined)\n                index.i = state.index;\n            if (state.rescaleY !== undefined)\n                rescaleY = state.rescaleY;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(lines);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            container.classed('nv-chart-' + id, true);\n            var that = this;\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition().duration(duration).call(chart)\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            var indexDrag = d3.behavior.drag()\n                .on('dragstart', dragStart)\n                .on('drag', dragMove)\n                .on('dragend', dragEnd);\n\n\n            function dragStart(d,i) {\n                d3.select(chart.container)\n                    .style('cursor', 'ew-resize');\n            }\n\n            function dragMove(d,i) {\n                index.x = d3.event.x;\n                index.i = Math.round(dx.invert(index.x));\n                updateZero();\n            }\n\n            function dragEnd(d,i) {\n                d3.select(chart.container)\n                    .style('cursor', 'auto');\n\n                // update state and send stateChange with new index\n                state.index = index.i;\n                dispatch.stateChange(state);\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = lines.xScale();\n            y = lines.yScale();\n\n\n            dx.domain([0, data[0].values.length - 1]) //Assumes all series have same length\n                .range([0, availableWidth])\n                .clamp(true);\n\n            var data = indexify(index.i, data);\n\n            // initialize the starting yDomain for the not-rescale case after indexify (to have calculated point.display)\n            if (typeof(currentYDomain) === \"undefined\") {\n                currentYDomain = getCurrentYDomain(data);\n            }\n\n            if (!rescaleY) {\n                lines.yDomain(currentYDomain);\n                lines.clipEdge(true);\n            } else {\n                lines.yDomain(null);\n            }\n\n            // Setup containers and skeleton of chart\n            var interactivePointerEvents = (useInteractiveGuideline) ? \"none\" : \"all\";\n            var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-cumulativeLine').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-interactive');\n            gEnter.append('g').attr('class', 'nv-x nv-axis').style(\"pointer-events\",\"none\");\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-background');\n            gEnter.append('g').attr('class', 'nv-linesWrap').style(\"pointer-events\",interactivePointerEvents);\n            gEnter.append('g').attr('class', 'nv-avgLinesWrap').style(\"pointer-events\",\"none\");\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                g.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: 'Re-scale y-axis', disabled: !rescaleY }\n                ];\n\n                controls\n                    .width(140)\n                    .color(['#444', '#444', '#444'])\n                    .rightAlign(false)\n                    .margin({top: 5, right: 0, bottom: 5, left: 20})\n                ;\n\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n                    .call(controls);\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Show error if index point value is 0 (division by zero avoided)\n            var tempDisabled = data.filter(function(d) { return d.tempDisabled });\n\n            wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates\n            if (tempDisabled.length) {\n                wrap.append('text').attr('class', 'tempDisabled')\n                    .attr('x', availableWidth / 2)\n                    .attr('y', '-.71em')\n                    .style('text-anchor', 'end')\n                    .text(tempDisabled.map(function(d) { return d.key }).join(', ') + ' values cannot be calculated for this time period.');\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left,top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            gEnter.select('.nv-background')\n                .append('rect');\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            lines\n                //.x(function(d) { return d.x })\n                .y(function(d) { return d.display.y })\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled && !data[i].tempDisabled; }));\n\n            var linesWrap = g.select('.nv-linesWrap')\n                .datum(data.filter(function(d) { return  !d.disabled && !d.tempDisabled }));\n\n            linesWrap.call(lines);\n\n            //Store a series index number in the data array.\n            data.forEach(function(d,i) {\n                d.seriesIndex = i;\n            });\n\n            var avgLineData = data.filter(function(d) {\n                return !d.disabled && !!average(d);\n            });\n\n            var avgLines = g.select(\".nv-avgLinesWrap\").selectAll(\"line\")\n                .data(avgLineData, function(d) { return d.key; });\n\n            var getAvgLineY = function(d) {\n                //If average lines go off the svg element, clamp them to the svg bounds.\n                var yVal = y(average(d));\n                if (yVal < 0) return 0;\n                if (yVal > availableHeight) return availableHeight;\n                return yVal;\n            };\n\n            avgLines.enter()\n                .append('line')\n                .style('stroke-width',2)\n                .style('stroke-dasharray','10,10')\n                .style('stroke',function (d,i) {\n                    return lines.color()(d,d.seriesIndex);\n                })\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', getAvgLineY)\n                .attr('y2', getAvgLineY);\n\n            avgLines\n                .style('stroke-opacity',function(d){\n                    //If average lines go offscreen, make them transparent\n                    var yVal = y(average(d));\n                    if (yVal < 0 || yVal > availableHeight) return 0;\n                    return 1;\n                })\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', getAvgLineY)\n                .attr('y2', getAvgLineY);\n\n            avgLines.exit().remove();\n\n            //Create index line\n            var indexLine = linesWrap.selectAll('.nv-indexLine')\n                .data([index]);\n            indexLine.enter().append('rect').attr('class', 'nv-indexLine')\n                .attr('width', 3)\n                .attr('x', -2)\n                .attr('fill', 'red')\n                .attr('fill-opacity', .5)\n                .style(\"pointer-events\",\"all\")\n                .call(indexDrag);\n\n            indexLine\n                .attr('transform', function(d) { return 'translate(' + dx(d.i) + ',0)' })\n                .attr('height', availableHeight);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/70, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            function updateZero() {\n                indexLine\n                    .data([index]);\n\n                //When dragging the index line, turn off line transitions.\n                // Then turn them back on when done dragging.\n                var oldDuration = chart.duration();\n                chart.duration(0);\n                chart.update();\n                chart.duration(oldDuration);\n            }\n\n            g.select('.nv-background rect')\n                .on('click', function() {\n                    index.x = d3.mouse(this)[0];\n                    index.i = Math.round(dx.invert(index.x));\n\n                    // update state and send stateChange with new index\n                    state.index = index.i;\n                    dispatch.stateChange(state);\n\n                    updateZero();\n                });\n\n            lines.dispatch.on('elementClick', function(e) {\n                index.i = e.pointIndex;\n                index.x = dx(index.i);\n\n                // update state and send stateChange with new index\n                state.index = index.i;\n                dispatch.stateChange(state);\n\n                updateZero();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                d.disabled = !d.disabled;\n                rescaleY = !d.disabled;\n                state.rescaleY = rescaleY;\n                if (!rescaleY) {\n                    currentYDomain = getCurrentYDomain(data); // rescale is turned off, so set the currentYDomain\n                }\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                lines.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !(series.disabled || series.tempDisabled);\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        lines.highlightPoint(i, pointIndex, true);\n                        var point = series.values[pointIndex];\n                        if (typeof point === 'undefined') return;\n                        if (typeof singlePoint === 'undefined') singlePoint = point;\n                        if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: chart.y()(point, pointIndex),\n                            color: color(series,series.seriesIndex)\n                        });\n                    });\n\n                //Highlight the tooltip entry based on which point the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);\n                    var threshold = 0.03 * domainExtent;\n                    var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold);\n                    if (indexToHighlight !== null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex), pointIndex);\n                interactiveLayer.tooltip\n                    .valueFormatter(function(d,i) {\n                        return yAxis.tickFormat()(d);\n                    })\n                    .data(\n                    {\n                        value: xValue,\n                        series: allData\n                    }\n                )();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                lines.clearHighlights();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.index !== 'undefined') {\n                    index.i = e.index;\n                    index.x = dx(index.i);\n\n                    state.index = e.index;\n\n                    indexLine\n                        .data([index]);\n                }\n\n                if (typeof e.rescaleY !== 'undefined') {\n                    rescaleY = e.rescaleY;\n                }\n\n                chart.update();\n            });\n\n        });\n\n        renderWatch.renderEnd('cumulativeLineChart immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        var point = {\n            x: chart.x()(evt.point),\n            y: chart.y()(evt.point),\n            color: evt.point.color\n        };\n        evt.point = point;\n        tooltip.data(evt).hidden(false);\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n\n    //============================================================\n    // Functions\n    //------------------------------------------------------------\n\n    var indexifyYGetter = null;\n    /* Normalize the data according to an index point. */\n    function indexify(idx, data) {\n        if (!indexifyYGetter) indexifyYGetter = lines.y();\n        return data.map(function(line, i) {\n            if (!line.values) {\n                return line;\n            }\n            var indexValue = line.values[idx];\n            if (indexValue == null) {\n                return line;\n            }\n            var v = indexifyYGetter(indexValue, idx);\n\n            // avoid divide by zero\n            if (Math.abs(v) < 0.00001 && !noErrorCheck) {\n                line.tempDisabled = true;\n                return line;\n            }\n\n            line.tempDisabled = false;\n\n            line.values = line.values.map(function(point, pointIndex) {\n                point.display = {'y': (indexifyYGetter(point, pointIndex) - v) / v };\n                return point;\n            });\n\n            return line;\n        })\n    }\n\n    function getCurrentYDomain(data) {\n        var seriesDomains = data\n            .filter(function(series) { return !(series.disabled || series.tempDisabled)})\n            .map(function(series,i) {\n                return d3.extent(series.values, function (d) { return d.display.y });\n            });\n\n        return [\n            d3.min(seriesDomains, function(d) { return d[0] }),\n            d3.max(seriesDomains, function(d) { return d[1] })\n        ];\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.lines = lines;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.state = state;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showControls:     {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        average: {get: function(){return average;}, set: function(_){average=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        showXAxis:    {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        noErrorCheck:    {get: function(){return noErrorCheck;}, set: function(_){noErrorCheck=_;}},\n\n        // options that require extra logic in the setter\n        rescaleY:     {get: function(){return rescaleY;}, set: function(_){\n            rescaleY = _;\n            chart.state.rescaleY = _; // also update state\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (_ === true) {\n                chart.interactive(false);\n                chart.useVoronoi(false);\n            }\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        duration:    {get: function(){return duration;}, set: function(_){\n            duration = _;\n            lines.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/differenceChart.js",
    "content": "'use strict';\n\nnv.models.differenceChart = function () {\n  'use strict';\n\n  var container = void 0;\n  var multiChart = nv.models.multiChart();\n  var focus = nv.models.focus(nv.models.line());\n  // const dispatch = d3.dispatch();\n  // yAccessor for multi chart\n  // Not modifiable by end user. They can\n  // overload yAccessor which is used during the processData step\n  var yForMultiChart = function yForMultiChart(d) {\n    // check if the data is for an area chart\n    // which has y0 and y1 values\n    if (isDefined(d.y0)) {\n      return d.y0;\n    }\n    // otherwise assume it's for a line chart\n    return d.y;\n  };\n  var xForMultiChart = function xForMultiChart(d) {\n    return d.x;\n  };\n  var xAccessor = function xAccessor(d) {\n    return d.x;\n  };\n  var keyForXValue = 'x';\n  var yAccessor = function yAccessor(d) {\n    return d.y;\n  };\n  var duration = 300;\n  var keyForActualLessThanPredicted = null;\n  var keyForActualGreaterThanPredicted = null;\n  var height = null;\n  var width = null;\n  var margin = { top: 30, right: 50, bottom: 20, left: 70 };\n  var focusMargin = { top: 0, right: 0, bottom: 0, left: 0 };\n  var showPredictedLine = true;\n  var interpolate = 'linear';\n  var strokeWidth = 1;\n  var xScale = d3.time.scale();\n  var tickFormat = d3.time.format.multi([['%I:%M', function (d) {\n    return d.getMinutes();\n  }], ['%I %p', function (d) {\n    return d.getHours();\n  }], ['%a %d', function (d) {\n    return d.getDay() && d.getDate() != 1;\n  }], ['%b %d', function (d) {\n    return d.getDate() != 1;\n  }], ['%B', function (d) {\n    return d.getMonth();\n  }], ['%Y', function () {\n    return true;\n  }]]);\n\n  function chart(selection) {\n    selection.each(function (data) {\n      container = d3.select(this);\n      var dataWithoutDisabledSeries = (data || []).filter(function (dataset) {\n        return !dataset.disabled;\n      });\n      if (!data || !dataWithoutDisabledSeries.length) {\n        nv.utils.noData(chart, container);\n        return chart;\n      }\n      var processedData = processData(data);\n      var availableHeight = nv.utils.availableHeight(height, container, margin) - focus.height();\n      var availableWidth = nv.utils.availableWidth(width, container, margin);\n\n      container.attr('class', 'nv-differenceChart');\n\n      nv.utils.initSVG(container);\n\n      chart.container = this;\n\n      multiChart.margin(margin).color(d3.scale.category10().range()).y(yForMultiChart).width(width).height(availableHeight).interpolate(interpolate).useInteractiveGuideline(true);\n\n      multiChart.interactiveLayer.tooltip.valueFormatter(function (value, i, datum) {\n        if (datum.key === keyForActualGreaterThanPredicted || datum.key === keyForActualLessThanPredicted) {\n          var diff = Math.abs(datum.data.y0 - datum.data.y1);\n          if (diff === 0) {\n            return '-';\n          }\n          return diff;\n        }\n        return value;\n      });\n\n      multiChart.stack1.areaY1(function (d) {\n        return multiChart.stack1.scatter.yScale()(d.display.y);\n      });\n\n      multiChart.stack1.transformData(function (d) {\n        d.display = { y: d.y1, y0: d.y0 };\n      });\n      multiChart.xAxis.scale(xScale);\n      multiChart.xAxis.tickFormat(tickFormat);\n      var allValues = processedData.filter(function (dataset) {\n        return !dataset.disabled;\n      }).map(function (dataset) {\n        return dataset.values;\n      });\n      var dateExtent = d3.extent(d3.merge(allValues), function (d) {\n        return xForMultiChart(d);\n      });\n      multiChart.xAxis.domain(dateExtent).range([0, availableWidth]);\n\n      var yExtent = d3.extent(d3.merge(allValues), function (d) {\n        return yForMultiChart(d);\n      });\n      multiChart.yDomain1(yExtent);\n      multiChart.yAxis1.tickFormat(d3.format(',.1f'));\n      multiChart.yAxis2.tickFormat(d3.format(',.1f'));\n\n      focus.width(availableWidth);\n      focus.margin(focusMargin);\n      focus.xScale(xScale.copy());\n      focus.xAxis.tickFormat(tickFormat);\n      focus.xAxis.rotateLabels(0);\n\n      container.append('g').attr('class', 'nv-focusWrap').style('display', 'initial').attr('transform', 'translate(' + margin.left + ', ' + (availableHeight + focus.margin().top) + ')').datum(processedData.filter(function (dataset) {\n        return dataset.type === 'line';\n      })).call(focus);\n\n      container.datum(processedData).call(multiChart);\n\n      focus.dispatch.on('onBrush', function (extent) {\n        var filteredData = processedData.map(function (datum) {\n          var leftIndex = -1;\n          var rightIndex = -1;\n          datum.values.some(function (val, index) {\n            if (leftIndex === -1 && val.x >= extent[0]) {\n              leftIndex = index;\n            }\n\n            if (rightIndex === -1 && val.x >= extent[1]) {\n              rightIndex = index;\n              return true;\n            }\n            return false;\n          });\n          var filteredValues = datum.values.slice(leftIndex, rightIndex);\n          var iterations = 0;\n          // don't want to end up with an empty dataset as this will\n          // break the viewfinder.\n          while (filteredValues.length < 2 && iterations < 5) {\n            leftIndex -= 1;\n            rightIndex += 1;\n            filteredValues = datum.values.slice(leftIndex, rightIndex);\n            iterations++;\n          }\n\n          return Object.assign({}, datum, {\n            values: filteredValues\n          });\n        });\n\n        container.datum(filteredData);\n\n        multiChart.xAxis.domain(extent);\n\n        multiChart.update();\n      });\n\n      chart.update = function () {\n        container.selectAll('*').remove();\n\n        if (duration === 0) {\n          container.call(chart);\n        } else {\n          container.transition().duration(duration).call(chart);\n        }\n      };\n\n      return chart;\n    });\n  }\n\n  chart.options = nv.utils.optionsFunc.bind(chart);\n\n  chart._options = Object.create({}, {\n    width: {\n      get: function get() {\n        return width;\n      },\n      set: function set(_) {\n        width = _;\n      }\n    },\n    height: {\n      get: function get() {\n        return height;\n      },\n      set: function set(_) {\n        height = _;\n      }\n    },\n    strokeWidth: {\n      get: function get() {\n        return strokeWidth;\n      },\n      set: function set(_) {\n        strokeWidth = _;\n      }\n    },\n    x: {\n      get: function get() {\n        return xAccessor;\n      },\n      set: function set(_) {\n        xAccessor = _;\n      }\n    },\n    keyForXValue: {\n      get: function get() {\n        return keyForXValue;\n      },\n      set: function set(_) {\n        keyForXValue = _;\n      }\n    },\n    y: {\n      get: function get() {\n        return yAccessor;\n      },\n      set: function set(_) {\n        yAccessor = _;\n      }\n    },\n    xScale: {\n      get: function get() {\n        return xScale;\n      },\n      set: function set(_) {\n        xScale = _;\n      }\n    },\n    keyForActualLessThanPredicted: {\n      get: function get() {\n        return keyForActualLessThanPredicted;\n      },\n      set: function set(_) {\n        keyForActualLessThanPredicted = _;\n      }\n    },\n    keyForActualGreaterThanPredicted: {\n      get: function get() {\n        return keyForActualGreaterThanPredicted;\n      },\n      set: function set(_) {\n        keyForActualGreaterThanPredicted = _;\n      }\n    },\n    showPredictedLine: {\n      get: function get() {\n        return showPredictedLine;\n      },\n      set: function set(_) {\n        showPredictedLine = _;\n      }\n    },\n    tickFormat: {\n      get: function get() {\n        return tickFormat;\n      },\n      set: function set(_) {\n        tickFormat = _;\n      }\n    },\n    interpolate: {\n      get: function get() {\n        return interpolate;\n      },\n      set: function set(_) {\n        interpolate = _;\n      }\n    },\n    focusMargin: {\n      get: function get() {\n        return focusMargin;\n      },\n      set: function set(_) {\n        focusMargin.top = _.top !== undefined ? _.top : focusMargin.top;\n        focusMargin.right = _.right !== undefined ? _.right : focusMargin.right;\n        focusMargin.bottom = _.bottom !== undefined ? _.bottom : focusMargin.bottom;\n        focusMargin.left = _.left !== undefined ? _.left : focusMargin.left;\n      }\n    },\n    margin: {\n      get: function get() {\n        return margin;\n      },\n      set: function set(_) {\n        margin.top = _.top !== undefined ? _.top : margin.top;\n        margin.right = _.right !== undefined ? _.right : margin.right;\n        margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n        margin.left = _.left !== undefined ? _.left : margin.left;\n      }\n    }\n  });\n\n  function processData(data) {\n    var clonedData = data.slice(0);\n    var allProcessed = clonedData.every(function (dataset) {\n      return dataset.processed;\n    });\n    var actualData = clonedData.filter(function (dataSet) {\n      return dataSet.type === 'actual';\n    });\n    var predictedData = clonedData.filter(function (dataSet) {\n      return dataSet.type === 'expected';\n    });\n\n    if (allProcessed) {\n      return clonedData;\n    } else if (!actualData.length || !predictedData.length) {\n      return [];\n    }\n\n    var defaultKeyForActualLessThanPredicted = predictedData[0].key + ' minus ' + actualData[0].key + ' (Predicted > Actual)';\n    var defaultKeyForActualGreaterThanPredicted = predictedData[0].key + ' minus ' + actualData[0].key + ' (Predicted < Actual)';\n    // processedData is mapped as follows:\n    //  [0] => Savings (actual under predicted) area\n    //  [1] => 'Loss' (actual over predicted) area\n    //  [2] => Actual profile\n    //  [3] => Predicted profile\n    var processedData = [{\n      key: keyForActualLessThanPredicted || defaultKeyForActualLessThanPredicted,\n      type: 'area',\n      values: [],\n      yAxis: 1,\n      color: 'rgba(44,160,44,.9)',\n      processed: true,\n      noHighlightSeries: true\n    }, {\n      key: keyForActualGreaterThanPredicted || defaultKeyForActualGreaterThanPredicted,\n      type: 'area',\n      values: [],\n      yAxis: 1,\n      color: 'rgba(234,39,40,.9)',\n      processed: true,\n      noHighlightSeries: true\n    }, {\n      key: actualData[0].key,\n      type: 'line',\n      values: [],\n      yAxis: 1,\n      color: '#666666',\n      processed: true,\n      strokeWidth: strokeWidth\n    }];\n\n    if (showPredictedLine) {\n      processedData[3] = {\n        key: predictedData[0].key,\n        type: 'line',\n        values: [],\n        yAxis: 1,\n        color: '#aec7e8',\n        processed: true,\n        strokeWidth: strokeWidth\n      };\n    }\n\n    var actualDataAsMap = actualData[0].values.reduce(function (result, datum, idx) {\n      result[xAccessor(datum)] = yAccessor(datum);\n      return result;\n    }, {});\n\n    var predictedDataAsMap = predictedData[0].values.reduce(function (result, datum, idx) {\n      result[xAccessor(datum)] = yAccessor(datum);\n      return result;\n    }, {});\n\n    Object.keys(actualDataAsMap).forEach(function (stringifiedXValue, idx) {\n      var actualUsage = actualDataAsMap[stringifiedXValue];\n      var predictedUsage = predictedDataAsMap[stringifiedXValue];\n      var fakeDatumToGetProperXValue = {};\n      // NB - stringifiedXValue will not be the correct data type\n      // e.g. you might want to use a number/date. Pass the stringified\n      // version back through xAccessor.\n      fakeDatumToGetProperXValue[keyForXValue] = stringifiedXValue;\n      var correctlyFormattedXValue = xAccessor(fakeDatumToGetProperXValue);\n\n      var predictedActualDelta = predictedUsage - actualUsage;\n      // The below code generates data for the difference chart.\n      // We have four series: two for the area (processedData[0] and processedData[1]) charts\n      // and two for the line charts ([2] and [3]). The way we achieve difference chart\n      // is that for each datapoint, we calculate whether it represents a 'savings'\n      // (actual less than predicted) or a 'loss' (actual greater than predicted).\n      // The two areas are different colours (e.g. out of the box, a loss is red and a\n      // saving is green).\n      // If it's a loss, then we add an area datapoint in the loss dataset ranging from actual to predicted\n      // (the area represents the magnitude of the loss).\n      // At the same time, for the savings dataset, we make the datapoint equivalent to actual usage so that\n      // a dot renders rather than a proper area. This basically makes the savings area invisible\n      // when there is a loss.\n      //\n      // The opposite occurs when predicted is greater than savings (a saving).\n      if (isNaN(predictedActualDelta)) {\n        // if there is no predicted value for this point, just use actual usage\n        processedData[1].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: actualUsage\n        };\n        processedData[0].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: actualUsage\n        };\n      }\n      else if (predictedActualDelta < 0) {\n        // actual greater than predicted - this is a loss\n        // add area for loss between actualUsage (y0) and predictedUsage(y1)\n        processedData[1].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: predictedUsage\n        };\n        // for the saving data series, render a dot (y0 and y1) at actualUsage - need\n        // this rather than NaN because otherwise if the next datapoint is a saving,\n        // D3 won't be able to link the two areas together\n        processedData[0].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: actualUsage\n        };\n      } else {\n        processedData[0].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: predictedUsage\n        };\n        processedData[1].values[idx] = {\n          x: correctlyFormattedXValue,\n          y0: actualUsage,\n          y1: actualUsage\n        };\n      }\n      // Set actual\n      processedData[2].values[idx] = { x: correctlyFormattedXValue, y: actualUsage };\n      // Set predicted\n      if (showPredictedLine) {\n        processedData[3].values[idx] = { x: correctlyFormattedXValue, y: predictedUsage };\n      }\n    });\n\n    return processedData;\n  }\n\n  function isDefined(thingToCheck) {\n    // NB: void 0 === undefined\n    return thingToCheck !== void 0;\n  }\n\n  chart.xAxis = multiChart.xAxis;\n  chart.yAxis = multiChart.yAxis1;\n  chart.multiChart = multiChart;\n  chart.focus = focus;\n  chart.processData = processData;\n  nv.utils.inheritOptions(chart, multiChart);\n  nv.utils.initOptions(chart);\n\n  return chart;\n};\n"
  },
  {
    "path": "src/models/discreteBar.js",
    "content": "//TODO: consider deprecating by adding necessary features to multiBar model\nnv.models.discreteBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , color = nv.utils.defaultColor()\n        , cornerRadius = 0 // sets corner radius (in pixels) to each bar\n        , showValues = false\n        , valueFormat = d3.format(',.2f')\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , rectClass = 'discreteBar'\n        , duration = 250\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            //add series index to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                });\n            });\n\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0 }\n                    })\n                });\n\n            x   .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableWidth], .1);\n            y   .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y }).concat(forceY)));\n\n            // If showValues, pad the Y axis range to account for label height\n            if (showValues) y.range(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);\n            else y.range(yRange || [availableHeight, 0]);\n\n            //store old scales if they exist\n            x0 = x0 || x;\n            y0 = y0 || y.copy().range([y(0),y(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-discretebar').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discretebar');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            //TODO: by definition, the discrete bar should not have multiple groups, will modify/remove later\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit()\n                .watchTransition(renderWatch, 'discreteBar: exit groups')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6)\n                .remove();\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover });\n            groups\n                .watchTransition(renderWatch, 'discreteBar: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', .75);\n\n            var bars = groups.selectAll('g.nv-bar')\n                .data(function(d) { return d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('g')\n                .attr('transform', function(d,i,j) {\n                    return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'\n                })\n                .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            barsEnter.append('rect')\n                .attr('height', 0)\n                .attr('width', x.rangeBand() * .9 / data.length )\n\n            if (showValues) {\n                barsEnter.append('text')\n                    .attr('text-anchor', 'middle')\n                ;\n\n                bars.select('text')\n                    .text(function(d,i) { return valueFormat(getY(d,i)) })\n                    .watchTransition(renderWatch, 'discreteBar: bars text')\n                    .attr('x', x.rangeBand() * .9 / 2)\n                    .attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 })\n\n                ;\n            } else {\n                bars.selectAll('text').remove();\n            }\n\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive' })\n                .style('fill', function(d,i) { return d.color || color(d,i) })\n                .style('stroke', function(d,i) { return d.color || color(d,i) })\n                .select('rect')\n                .attr('rx', cornerRadius)\n                .attr('class', rectClass)\n                .watchTransition(renderWatch, 'discreteBar: bars rect')\n                .attr('width', x.rangeBand() * .9 / data.length);\n            bars.watchTransition(renderWatch, 'discreteBar: bars')\n                //.delay(function(d,i) { return i * 1200 / data[0].values.length })\n                .attr('transform', function(d,i) {\n                    var left = x(getX(d,i)) + x.rangeBand() * .05,\n                        top = getY(d,i) < 0 ?\n                            y(0) :\n                                y(0) - y(getY(d,i)) < 1 ?\n                            y(0) - 1 : //make 1 px positive bars show up above y=0\n                            y(getY(d,i));\n\n                    return 'translate(' + left + ', ' + top + ')'\n                })\n                .select('rect')\n                .attr('height', function(d,i) {\n                    return  Math.max(Math.abs(y(getY(d,i)) - y(0)), 1)\n                });\n\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('discreteBar immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}},\n        cornerRadius:      {get: function(){return cornerRadius;}, set: function(_){cornerRadius=_}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        valueFormat:    {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/discreteBarChart.js",
    "content": "\nnv.models.discreteBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var discretebar = nv.models.discreteBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n\t, legend = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 15, right: 10, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.getColor()\n\t, showLegend = false\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , staggerLabels = false\n        , wrapLabels = false\n        , rotateLabels = 0\n        , x\n        , y\n        , noData = null\n        , dispatch = d3.dispatch('beforeUpdate','renderEnd')\n        , duration = 250\n        ;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .keyFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(discretebar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = discretebar.xScale();\n            y = discretebar.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-discreteBarWithAxes').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-discreteBarWithAxes').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n\t    gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Main Chart Component(s)\n            discretebar\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.transition().call(discretebar);\n\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + discretebar.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + discretebar.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + (y.range()[0] + ((discretebar.showValues() && y.domain()[0] < 0) ? 16 : 0)) + ')');\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 == 0 ? '5' : '17') + ')' })\n                }\n\n                if (rotateLabels) {\n                    xTicks\n                        .selectAll('.tick text')\n                        .attr('transform', 'rotate(' + rotateLabels + ' 0,0)')\n                        .style('text-anchor', rotateLabels > 0 ? 'start' : 'end');\n                }\n\n                if (wrapLabels) {\n                    g.selectAll('.tick text')\n                        .call(nv.utils.wrapTicks, chart.xAxis.rangeBand())\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data, discretebar.y()) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select(\".nv-zeroLine line\")\n                .attr(\"x1\",0)\n                .attr(\"x2\",(rightAlignYAxis) ? -availableWidth : availableWidth)\n                .attr(\"y1\", y(0))\n                .attr(\"y2\", y(0))\n            ;\n        });\n\n        renderWatch.renderEnd('discreteBar chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    discretebar.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    discretebar.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    discretebar.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.discretebar = discretebar;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n\tshowLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:  {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        wrapLabels:  {get: function(){return wrapLabels;}, set: function(_){wrapLabels=!!_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            discretebar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            discretebar.color(color);\n\t    legend.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, discretebar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n"
  },
  {
    "path": "src/models/distribution.js",
    "content": "\nnv.models.distribution = function() {\n    \"use strict\";\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 400 //technically width or height depending on x or y....\n        , size = 8\n        , axis = 'x' // 'x' or 'y'... horizontal or vertical\n        , getData = function(d) { return d[axis] }  // defaults d.x or d.y\n        , color = nv.utils.defaultColor()\n        , scale = d3.scale.linear()\n        , domain\n        , duration = 250\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n\n    //============================================================\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var scale0;\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    //============================================================\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableLength = width - (axis === 'x' ? margin.left + margin.right : margin.top + margin.bottom),\n                naxis = axis == 'x' ? 'y' : 'x',\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            //------------------------------------------------------------\n            // Setup Scales\n\n            scale0 = scale0 || scale;\n\n            //------------------------------------------------------------\n\n\n            //------------------------------------------------------------\n            // Setup containers and skeleton of chart\n\n            var wrap = container.selectAll('g.nv-distribution').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-distribution');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')\n\n            //------------------------------------------------------------\n\n\n            var distWrap = g.selectAll('g.nv-dist')\n                .data(function(d) { return d }, function(d) { return d.key });\n\n            distWrap.enter().append('g');\n            distWrap\n                .attr('class', function(d,i) { return 'nv-dist nv-series-' + i })\n                .style('stroke', function(d,i) { return color(d, i) });\n\n            var dist = distWrap.selectAll('line.nv-dist' + axis)\n                .data(function(d) { return d.values })\n            dist.enter().append('line')\n                .attr(axis + '1', function(d,i) { return scale0(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale0(getData(d,i)) })\n            renderWatch.transition(distWrap.exit().selectAll('line.nv-dist' + axis), 'dist exit')\n                // .transition()\n                .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })\n                .style('stroke-opacity', 0)\n                .remove();\n            dist\n                .attr('class', function(d,i) { return 'nv-dist' + axis + ' nv-dist' + axis + '-' + i })\n                .attr(naxis + '1', 0)\n                .attr(naxis + '2', size);\n            renderWatch.transition(dist, 'dist')\n                // .transition()\n                .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })\n                .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })\n\n\n            scale0 = scale.copy();\n\n        });\n        renderWatch.renderEnd('distribution immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart.dispatch = dispatch;\n\n    chart.margin = function(_) {\n        if (!arguments.length) return margin;\n        margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n        margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;\n        margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;\n        margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        return chart;\n    };\n\n    chart.width = function(_) {\n        if (!arguments.length) return width;\n        width = _;\n        return chart;\n    };\n\n    chart.axis = function(_) {\n        if (!arguments.length) return axis;\n        axis = _;\n        return chart;\n    };\n\n    chart.size = function(_) {\n        if (!arguments.length) return size;\n        size = _;\n        return chart;\n    };\n\n    chart.getData = function(_) {\n        if (!arguments.length) return getData;\n        getData = d3.functor(_);\n        return chart;\n    };\n\n    chart.scale = function(_) {\n        if (!arguments.length) return scale;\n        scale = _;\n        return chart;\n    };\n\n    chart.color = function(_) {\n        if (!arguments.length) return color;\n        color = nv.utils.getColor(_);\n        return chart;\n    };\n\n    chart.duration = function(_) {\n        if (!arguments.length) return duration;\n        duration = _;\n        renderWatch.reset(duration);\n        return chart;\n    };\n    //============================================================\n\n\n    return chart;\n}\n"
  },
  {
    "path": "src/models/distroPlot.js",
    "content": "nv.models.distroPlot = function() {\n    \"use strict\";\n\n    // IMPROVEMENTS:\n    // - cleanup tooltip to look like candlestick example (don't need color square for everything)\n    // - extend y scale range to min/max data better visually\n    // - tips of violins need to be cut off if very long\n    // - transition from box to violin not great since box only has a few points, and violin has many - need to generate box with as many points as violin\n    // - when providing colorGroup, should color boxes by either parent or child group category (e.g. isolator)\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0},\n        width = 960,\n        height = 500,\n        id = Math.floor(Math.random() * 10000), // Create semi-unique ID in case user doesn't select one\n        xScale = d3.scale.ordinal(),\n        yScale = d3.scale.linear(),\n        getX  = function(d) { return d.label }, // Default data model selectors.\n        getY  = function(d) { return d.value },\n        getColor = function(d) { return d.color },\n        getQ1 = function(d) { return d.values.q1 },\n        getQ2 = function(d) { return d.values.q2 },\n        getQ3 = function(d) { return d.values.q3 },\n        getNl = function(d) { return (centralTendency == 'mean' ? getMean(d) : getQ2(d)) - d.values.notch },\n        getNu = function(d) { return (centralTendency == 'mean' ? getMean(d) : getQ2(d)) + d.values.notch },\n        getMean = function(d) { return d.values.mean },\n        getWl = function(d) { return d.values.wl[whiskerDef] },\n        getWh = function(d) { return d.values.wu[whiskerDef] },\n        getMin = function(d) { return d.values.min },\n        getMax = function(d) { return d.values.max },\n        getDev = function(d) { return d.values.dev },\n        getValsObj = function(d) { return d.values.observations; },\n        getValsArr = function(d) { return d.values.observations.map(function(e) { return e.y }); },\n        plotType, // type of background: 'box', 'violin', 'none'/false - default: 'box' - 'none' will activate random scatter automatically\n        observationType = false, // type of observations to show: 'random', 'swarm', 'line', 'centered' - default: false (don't show any observations, even if an outlier)\n        whiskerDef = 'iqr', // type of whisker to render: 'iqr', 'minmax', 'stddev' - default: iqr\n        hideWhiskers = false,\n        notchBox = false, // bool whether to notch box\n        colorGroup = false, // if specified, each x-category will be split into groups, each colored\n        centralTendency = false,\n        showOnlyOutliers = true, // show only outliers in box plot\n        jitter = 0.7, // faction of that jitter should take up in 'random' observationType, must be in range [0,1]; see jitterX(), default 0.7\n        squash = true, // whether to remove the x-axis positions for empty data groups, default is true\n        bandwidth = 'scott', // bandwidth for kde calculation, can be float or str, if str, must be one of scott or silverman\n        clampViolin = true, // whether to clamp the \"tails\" of the violin; prevents long 0-density area\n        resolution = 50,\n        pointSize = 3,\n        color = nv.utils.defaultColor(),\n        container = null,\n        xDomain, xRange,\n        yDomain, yRange,\n        dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd'),\n        duration = 250,\n        maxBoxWidth = null;\n\n    //============================================================\n    // Helper Functions\n    //------------------------------------------------------------\n\n\n    /* Returns the smaller of std(X, ddof=1) or normalized IQR(X) over axis 0.\n     *\n     * @param (list) x - input x formatted as a single list of values\n     *\n     * @return float\n     *\n     * Source: https://github.com/statsmodels/statsmodels/blob/master/statsmodels/nonparametric/bandwidths.py#L9\n     */\n    function select_sigma(x) {\n        var sorted = x.sort(d3.ascending); // sort our dat\n        var normalize = 1.349;\n        var IQR = (d3.quantile(sorted, 0.75) - d3.quantile(sorted, 0.25))/normalize; // normalized IQR\n        return d3.min([d3.deviation(sorted), IQR]);\n    }\n\n    /*\n    Scott's Rule of Thumb\n\n    Parameters\n    ----------\n    x : array-like\n        Array for which to get the bandwidth\n    type : string\n           The type of estimate to use, must be one of scott or silverman\n\n    Returns\n    -------\n    bw : float\n        The estimate of the bandwidth\n\n    Notes\n    -----\n    Returns 1.059 * A * n ** (-1/5.) where ::\n       A = min(std(x, ddof=1), IQR/1.349)\n       IQR = np.subtract.reduce(np.percentile(x, [75,25]))\n\n    References\n    ----------\n    Scott, D.W. (1992) Multivariate Density Estimation: Theory, Practice, and\n        Visualization.\n     */\n    function calcBandwidth(x, type) {\n\n        if (typeof type === 'undefined') type = 'scott';\n\n        // TODO: consider using https://github.com/jasondavies/science.js\n        var A = select_sigma(x);\n        var n = x.length;\n        return type==='scott' ? Math.pow(1.059 * A * n, -0.2) : Math.pow(.9 * A * n, -0.2);\n    }\n\n\n\n    /*\n     * Prep data for use with distroPlot by grouping data\n     * by .x() option set by user and then calculating\n     * count, sum, mean, q1, q2 (median), q3, lower whisker (wl)\n     * upper whisker (wu), iqr, min, max, and standard dev.\n     *\n     * NOTE: preparing this data can be resource intensive, and\n     *       is therefore only run once on plot load. It can\n     *       manually be run by calling recalcData(). This should\n     *       be re-run any time the axis accessors are changed or\n     *       when bandwidth/resolution are updated.\n     *\n     * NOTE: this will also setup the individual vertical scales\n     *       for the violins.\n     *\n     * @param (list) dat - input data formatted as list of objects,\n     *   with an object key that must exist when accessed by getX()\n     *\n     * @return prepared data in the form for box plotType:\n     * [{\n     *    key : YY,\n     *    values: {\n     *      count: XX,\n     *      sum: XX,\n     *      mean: XX,\n     *      q1: XX,\n     *      q2: XX,\n     *      q3: XX,\n     *      wl: XX,\n     *      wu: XX,\n     *      iqr: XX,\n     *      min: XX,\n     *      max: XX,\n     *      dev: XX,\n     *      observations: [{y:XX,..},..],\n     *      key: XX,\n     *      kdeDat: XX,\n     *      notch: XX,\n     *    }\n     *  },\n     *  ...\n     *  ]\n     * for violin plotType:\n     * [{\n     *    key : YY,\n     *    values: {\n     *      original: [{y:XX,..},..]\n     *    }\n     *  },\n     *  ...\n     *  ]\n     * where YY are those keys in dat that define the\n     * x-axis and which are defined by .x()\n     */\n    function prepData(dat) {\n\n        // helper function to calcuate the various boxplot stats\n        function calcStats(g, xGroup) {\n\n            // sort data by Y so we can calc quartiles\n            var v = g.map(function(d) {\n                if (colorGroup) allColorGroups.add(colorGroup(d)); // list of all colorGroups; used to set x-axis\n                return getY(d);\n            }).sort(d3.ascending);\n\n            var q1 = d3.quantile(v, 0.25);\n            var q3 = d3.quantile(v, 0.75);\n            var iqr = q3 - q1;\n            var upper = q3 + 1.5 * iqr;\n            var lower = q1 - 1.5 * iqr;\n\n            /* whisker definitions:\n             *  - iqr: also known as Tukey boxplot, the lowest datum still within 1.5 IQR of the lower quartile, and the highest datum still within 1.5 IQR of the upper quartile\n             *  - minmax: the minimum and maximum of all of the data\n             *  - sttdev: one standard deviation above and below the mean of the data\n             * Note that the central tendency type (median or mean) does not impact the whisker location\n             */\n            var wl = {iqr: d3.max([d3.min(v),  d3.min(v.filter(function(d) {return d > lower}))]), minmax: d3.min(v), stddev: d3.mean(v) - d3.deviation(v)};\n            var wu = {iqr: d3.min([d3.max(v), d3.max(v.filter(function(d) {return d < upper}))]), minmax: d3.max(v), stddev: d3.mean(v) + d3.deviation(v)};\n            var median = d3.median(v);\n            var mean = d3.mean(v);\n            var observations = [];\n\n\n            // d3-beeswarm library must be externally loaded if being used\n            // https://github.com/Kcnarf/d3-beeswarm\n            if (typeof d3.beeswarm !== 'undefined') {\n                observations = d3.beeswarm()\n                    .data(g.map(function(e) { return getY(e); }))\n                    .radius(pointSize+1)\n                    .orientation('vertical')\n                    .side('symmetric')\n                    .distributeOn(function(e) { return yScale(e); })\n                    .arrange()\n\n                // add group info for tooltip\n                observations.map(function(e,i) {\n                    e.key = xGroup;\n                    e.object_constancy = g[i].object_constancy;\n                    e.isOutlier = (e.datum < wl.iqr || e.datum > wu.iqr) // add isOulier meta for proper class assignment\n                    e.isOutlierStdDev = (e.datum < wl.stddev || e.datum > wu.stddev) // add isOulier meta for proper class assignment\n                    e.randX = Math.random() * jitter * (Math.floor(Math.random()*2) == 1 ? 1 : -1) // calculate random x-position only once for each point\n                })\n            } else {\n                v.forEach(function(e,i) {\n                    observations.push({\n                        object_constancy: e.object_constancy,\n                        datum: e,\n                        key: xGroup,\n                        isOutlier: (e < wl.iqr || e > wu.iqr), // add isOulier meta for proper class assignment\n                        isOutlierStdDev: (e < wl.stddev || e > wu.stddev), // add isOulier meta for proper class assignment\n                        randX: Math.random() * jitter * (Math.floor(Math.random()*2) == 1 ? 1 : -1)\n                    })\n                })\n            }\n\n\n            // calculate bandwidth if no number is provided\n            if(isNaN(parseFloat(bandwidth))) { // if not is float\n                var bandwidthCalc;\n                if (['scott','silverman'].indexOf(bandwidth) != -1) {\n                    bandwidthCalc = calcBandwidth(v, bandwidth);\n                } else {\n                    bandwidthCalc = calcBandwidth(v); // calculate with default 'scott'\n                }\n            }\n            var kde = kernelDensityEstimator(eKernel(bandwidthCalc), yScale.ticks(resolution));\n            var kdeDat = clampViolin ? clampViolinKDE(kde(v), d3.extent(v)) : kde(v);\n\n\n            // make a new vertical scale for each group\n            var tmpScale = d3.scale.linear()\n                .domain([0, d3.max(kdeDat, function (e) { return e.y;})])\n                .clamp(true);\n            yVScale.push(tmpScale);\n\n            var reformat = {\n                count: v.length,\n                num_outlier: observations.filter(function (e) { return e.isOutlier; }).length,\n                sum: d3.sum(v),\n                mean: mean,\n                q1: q1,\n                q2: median,\n                q3: q3,\n                wl: wl,\n                wu: wu,\n                iqr: iqr,\n                min: d3.min(v),\n                max: d3.max(v),\n                dev: d3.deviation(v),\n                observations: observations,\n                key: xGroup,\n                kde: kdeDat,\n                notch: 1.57 * iqr / Math.sqrt(v.length), // notch distance from mean/median\n            };\n\n            if (colorGroup) {reformatDatFlat.push({key: xGroup, values: reformat});}\n\n            return reformat;\n        }\n\n        // assign a unique identifier for each point for object constancy\n        // this makes updating data possible\n        dat.forEach(function(d,i) { d.object_constancy = i + '_' + getY(d) + '_' + getX(d); })\n\n\n        // TODO not DRY\n        // couldn't find a conditional way of doing the key() grouping\n        var formatted;\n        if (!colorGroup) {\n            formatted = d3.nest()\n                .key(function(d) { return getX(d); })\n                .rollup(function(v,i) {\n                    return calcStats(v);\n                })\n                .entries(dat);\n        } else {\n            allColorGroups = d3.set() // reset\n            var tmp = d3.nest()\n                .key(function(d) { return getX(d); })\n                .key(function(d) { return colorGroup(d); })\n                .rollup(function(v) {\n                    return calcStats(v, getX(v[0]));\n                })\n                .entries(dat);\n\n            // generate a final list of all x & colorGroup combinations\n            // this is used to properly set the x-axis domain\n            allColorGroups = allColorGroups.values(); // convert from d3.set to list\n            var xGroups = tmp.map(function(d) { return d.key; });\n            var allGroups = [];\n            for (var i = 0; i < xGroups.length; i++) {\n                for (var j = 0; j < allColorGroups.length; j++) {\n                    allGroups.push(xGroups[i] + '_' + allColorGroups[j]);\n                }\n            }\n            allColorGroups = allGroups;\n\n            // flatten the inner most level so that\n            // the plot retains the same DOM structure\n            // to allow for smooth updating between\n            // all groups.\n            formatted = [];\n            tmp.forEach(function(d) {\n                d.values.forEach(function(e) { e.key = d.key +'_'+e.key }) // generate a combo key so that each boxplot has a distinct x-position\n                formatted.push.apply(formatted, d.values)\n            });\n\n        }\n        return formatted;\n    }\n\n    // https://bl.ocks.org/mbostock/4341954\n    function kernelDensityEstimator(kernel, X) {\n        return function (sample) {\n            return X.map(function(x) {\n                var y = d3.mean(sample, function (v) {return kernel(x - v);});\n                return {x:x, y:y};\n            });\n        };\n    }\n\n    /*\n     * Limit whether the density extends past the extreme datapoints\n     * of the violin.\n     *\n     * @param (list) kde - x & y kde cooridinates\n     * @param (list) extent - min/max y-values used for clamping violing\n     */\n    function clampViolinKDE(kde, extent) {\n\n        // this handles the case when all the x-values are equal\n        // which means no kde could be properly calculated\n        // just return the kde data so we can continue plotting successfully\n        if (extent[0] === extent[1]) return kde;\n\n        var clamped = kde.reduce(function(res, d) {\n            if (d.x >= extent[0] && d.x <= extent[1]) res.push(d);\n            return res;\n        },[]);\n\n        // add the extreme data points back in\n        if (extent[0] < clamped[0].x) clamped.unshift({x:extent[0], y:clamped[0].y})\n        if (extent[1] > clamped[clamped.length-1].x) clamped.push({x:extent[1], y:clamped[clamped.length-1].y})\n\n        return clamped;\n\n    }\n\n    // https://bl.ocks.org/mbostock/4341954\n    function eKernel(scale) {\n        return function (u) {\n            return Math.abs(u /= scale) <= 1 ? .75 * (1 - u * u) / scale : 0;\n        };\n    }\n\n    /**\n     * Makes the svg polygon string for a boxplot in either a notched\n     * or square version\n     *\n     * NOTE: this actually only draws the left half of the box, since\n     * the shape is symmetric (and since this is how violins are drawn)\n     * we can simply generate half the box and mirror it.\n     *\n     * @param boxLeft {float} - left position of box\n     * @param notchLeft {float} - left position of notch\n     * @param dat {obj} - box plot data that was run through prepDat, must contain\n     *      data for Q1, median, Q2, notch upper and notch lower\n     * @returns {string} A string in the proper format for a svg polygon\n     */\n    function makeNotchBox(boxLeft, notchLeft, boxCenter, dat) {\n\n        var boxPoints;\n        var y = centralTendency == 'mean' ? getMean(dat) : getQ2(dat); // if centralTendency is not specified, we still want to notch boxes on 'median'\n        if (notchBox) {\n            boxPoints = [\n                    {x:boxCenter, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getNl(dat))},\n                    {x:notchLeft, y:yScale(y)},\n                    {x:boxLeft, y:yScale(getNu(dat))},\n                    {x:boxLeft, y:yScale(getQ3(dat))},\n                    {x:boxCenter, y:yScale(getQ3(dat))},\n                ];\n        } else {\n            boxPoints = [\n                    {x:boxCenter, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(getQ1(dat))},\n                    {x:boxLeft, y:yScale(y)}, // repeated point so that transition between notched/regular more smooth\n                    {x:boxLeft, y:yScale(y)},\n                    {x:boxLeft, y:yScale(y)}, // repeated point so that transition between notched/regular more smooth\n                    {x:boxLeft, y:yScale(getQ3(dat))},\n                    {x:boxCenter, y:yScale(getQ3(dat))},\n                ];\n        }\n\n        return boxPoints;\n    }\n\n    /**\n     * Given an x-axis group, return the available color groups within it\n     * provided that colorGroups is set, if not, x-axis group is returned\n     */\n    function getAvailableColorGroups(x) {\n        if (!colorGroup) return x;\n        var tmp = reformatDat.find(function(d) { return d.key == x });\n        return tmp.values.map(function(d) { return d.key }).sort(d3.ascending);\n    }\n\n    // return true if point is an outlier\n    function isOutlier(d) {\n        return (whiskerDef == 'iqr' && d.isOutlier) || (whiskerDef == 'stddev' && d.isOutlierStdDev)\n    }\n\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var allColorGroups = d3.set()\n    var yVScale = [], reformatDat, reformatDatFlat = [];\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var availableWidth, availableHeight;\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            availableWidth = width - margin.left - margin.right,\n            availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup y-scale so that beeswarm layout can use it in prepData()\n            yScale.domain(yDomain || d3.extent(data.map(function(d) { return getY(d)}))).nice()\n                .range(yRange || [availableHeight, 0]);\n\n\n            if (typeof reformatDat === 'undefined') reformatDat = prepData(data); // this prevents us from recalculating data all the time\n\n            // Setup x-scale\n            xScale.rangeBands(xRange || [0, availableWidth], 0.1)\n                  .domain(xDomain || (colorGroup && !squash) ? allColorGroups : reformatDat.map(function(d) { return d.key }))\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([reformatDat]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap');\n            wrap.watchTransition(renderWatch, 'nv-wrap: wrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var areaEnter,\n                distroplots = wrap.selectAll('.nv-distroplot-x-group')\n                    .data(function(d) { return d; });\n\n            // rebind new data\n            // we don't rebuild individual x-axis groups so that we can update transition them\n            // however the data associated with each x-axis group needs to be updated\n            // so we manually update it here\n            distroplots.each(function(d,i) {\n                d3.select(this).selectAll('line.nv-distroplot-middle').datum(d);\n            })\n\n            areaEnter = distroplots.enter()\n                .append('g')\n                .attr('class', 'nv-distroplot-x-group')\n                .style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6)\n                .style('fill', function(d,i) { return getColor(d) || color(d,i) })\n                .style('stroke', function(d,i) { return getColor(d) || color(d,i) })\n\n            distroplots.exit().remove();\n\n            var rangeBand = function() { return xScale.rangeBand() };\n            var areaWidth = function() { return d3.min([maxBoxWidth,rangeBand() * 0.9]); };\n            var areaCenter = function() { return areaWidth()/2; };\n            var areaLeft  = function() { return areaCenter() - areaWidth()/2; };\n            var areaRight = function() { return areaCenter() + areaWidth()/2; };\n            var tickLeft  = function() { return areaCenter() - areaWidth()/5; };\n            var tickRight = function() { return areaCenter() + areaWidth()/5; };\n\n            areaEnter.attr('transform', function(d) {\n                    return 'translate(' + (xScale(d.key) + (rangeBand() - areaWidth()) * 0.5) + ', 0)';\n                });\n\n            distroplots\n                .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', 0.5)\n                .attr('transform', function(d) {\n                    return 'translate(' + (xScale(d.key) + (rangeBand() - areaWidth()) * 0.5) + ', 0)';\n                });\n\n            // set range for violin scale\n            yVScale.map(function(d) { d.range([areaWidth()/2, 0]) });\n\n            // ----- add the SVG elements for each plot type -----\n\n            // scatter plot type\n            if (!plotType) {\n                showOnlyOutliers = false; // force all observations to be seen\n                if (!observationType) observationType = 'random'\n            }\n\n            // conditionally append whisker lines\n            areaEnter.each(function(d,i) {\n                var box = d3.select(this);\n                [getWl, getWh].forEach(function (f) {\n                    var key = (f === getWl) ? 'low' : 'high';\n                    box.append('line')\n                      .style('opacity', function() { return !hideWhiskers ? '0' : '1' })\n                      .attr('class', 'nv-distroplot-whisker nv-distroplot-' + key)\n                    box.append('line')\n                      .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n                      .attr('class', 'nv-distroplot-tick nv-distroplot-' + key)\n                });\n            });\n\n\n            // update whisker lines and ticks\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                var endpoint = (f === getWl) ? getQ1 : getQ3;\n                distroplots.select('line.nv-distroplot-whisker.nv-distroplot-' + key)\n                  .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                    .attr('x1', areaCenter())\n                    .attr('y1', function(d) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .attr('x2', areaCenter())\n                    .attr('y2', function(d) { return plotType=='box' ? yScale(endpoint(d)) : yScale(getQ2(d)); })\n                    .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n                distroplots.select('line.nv-distroplot-tick.nv-distroplot-' + key)\n                  .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots')\n                    .attr('x1', function(d) { return plotType!='violin' ? tickLeft() : areaCenter()} )\n                    .attr('y1', function(d,i) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .attr('x2', function(d) { return plotType!='violin' ? tickRight() : areaCenter()} )\n                    .attr('y2', function(d,i) { return plotType!='violin' ? yScale(f(d)) : yScale(getQ2(d)); })\n                    .style('opacity', function() { return hideWhiskers ? '0' : '1' })\n            });\n\n            [getWl, getWh].forEach(function (f) {\n                var key = (f === getWl) ? 'low' : 'high';\n                areaEnter.selectAll('.nv-distroplot-' + key)\n                  .on('mouseover', function(d,i,j) {\n                      d3.select(this.parentNode).selectAll('line.nv-distroplot-'+key).classed('hover',true);\n                      dispatch.elementMouseover({\n                          value: key == 'low' ? 'Lower whisker' : 'Upper whisker',\n                          series: { key: f(d).toFixed(2), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mouseout', function(d,i,j) {\n                      d3.select(this.parentNode).selectAll('line.nv-distroplot-'+key).classed('hover',false);\n                      dispatch.elementMouseout({\n                          value: key == 'low' ? 'Lower whisker' : 'Upper whisker',\n                          series: { key: f(d).toFixed(2), color: getColor(d) || color(d,j) },\n                          e: d3.event\n                      });\n                  })\n                  .on('mousemove', function(d,i) {\n                      dispatch.elementMousemove({e: d3.event});\n                  });\n            });\n\n            // setup boxes as 4 parts: left-area, left-line, right-area, right-line,\n            // this way we can transition to a violin\n            areaEnter.each(function(d,i) {\n                var violin = d3.select(this);\n\n                ['left','right'].forEach(function(side) {\n                    ['line','area'].forEach(function(d) {\n                        violin.append('path')\n                            .attr('class', 'nv-distribution-' + d + ' nv-distribution-' + side)\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')); // rotate violin\n                    })\n\n                })\n\n                areaEnter.selectAll('.nv-distribution-line')\n                    .style('fill','none')\n                areaEnter.selectAll('.nv-distribution-area')\n                    .style('stroke','none')\n                    .style('opacity',0.7)\n\n            });\n\n            // transitions\n            distroplots.each(function(d,i) {\n                var violin = d3.select(this);\n                var objData = plotType == 'box' ? makeNotchBox(areaLeft(), tickLeft(), areaCenter(), d) : d.values.kde;\n\n                violin.selectAll('path')\n                    .datum(objData)\n\n                var tmpScale = yVScale[i];\n\n                var interp = plotType=='box' ? 'linear' : 'basis';\n\n                if (plotType == 'box' || plotType == 'violin') {\n                    ['left','right'].forEach(function(side) {\n\n                        // line\n                        distroplots.selectAll('.nv-distribution-line.nv-distribution-' + side)\n                          //.watchTransition(renderWatch, 'nv-distribution-line: distroplots') // disable transition for now because it's jaring\n                            .attr(\"d\", d3.svg.line()\n                                    .x(function(e) { return plotType=='box' ? e.y : yScale(e.x); })\n                                    .y(function(e) { return plotType=='box' ? e.x : tmpScale(e.y) })\n                                    .interpolate(interp)\n                            )\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')) // rotate violin\n                            .style('opacity', !plotType ? '0' : '1');\n\n                        // area\n                        distroplots.selectAll('.nv-distribution-area.nv-distribution-' + side)\n                          //.watchTransition(renderWatch, 'nv-distribution-line: distroplots') // disable transition for now because it's jaring\n                            .attr(\"d\", d3.svg.area()\n                                    .x(function(e) { return plotType=='box' ? e.y : yScale(e.x); })\n                                    .y(function(e) { return plotType=='box' ? e.x : tmpScale(e.y) })\n                                    .y0(areaWidth()/2)\n                                    .interpolate(interp)\n                            )\n                            .attr(\"transform\", \"rotate(90,0,0)   translate(0,\" + (side == 'left' ? -areaWidth() : 0) + \")\" + (side == 'left' ? '' : ' scale(1,-1)')) // rotate violin\n                            .style('opacity', !plotType ? '0' : '1');\n\n                    })\n                } else { // scatter type, hide areas\n                    distroplots.selectAll('.nv-distribution-area')\n                        .watchTransition(renderWatch, 'nv-distribution-area: distroplots')\n                        .style('opacity', !plotType ? '0' : '1');\n\n                    distroplots.selectAll('.nv-distribution-line')\n                        .watchTransition(renderWatch, 'nv-distribution-line: distroplots')\n                        .style('opacity', !plotType ? '0' : '1');\n                }\n\n            })\n\n            // tooltip events\n            distroplots.selectAll('path')\n                .on('mouseover', function(d,i,j) {\n                    d = d3.select(this.parentNode).datum(); // grab data from parent g\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        key: d.key,\n                        value: 'Group ' + d.key + ' stats',\n                        series: [\n                            { key: 'max', value: getMax(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q3', value: getQ3(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q2', value: getQ2(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q1', value: getQ1(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'min', value: getMin(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'mean', value: getMean(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'std. dev.', value: getDev(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'count', value: d.values.count, color: getColor(d) || color(d,j) },\n                            { key: 'num. outliers', value: d.values.num_outlier, color: getColor(d) || color(d,j) },\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    d = d3.select(this.parentNode).datum(); // grab data from parent g\n                    dispatch.elementMouseout({\n                        key: d.key,\n                        value: 'Group ' + d.key + ' stats',\n                        series: [\n                            { key: 'max', value: getMax(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q3', value: getQ3(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q2', value: getQ2(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'Q1', value: getQ1(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'min', value: getMin(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'mean', value: getMean(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'std. dev.', value: getDev(d).toFixed(2), color: getColor(d) || color(d,j) },\n                            { key: 'count', value: d.values.count, color: getColor(d) || color(d,j) },\n                            { key: 'num. outliers', value: d.values.num_outlier, color: getColor(d) || color(d,j) },\n                        ],\n                        data: d,\n                        index: i,\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n\n            // median/mean line\n            areaEnter.append('line')\n                .attr('class', function(d) { return 'nv-distroplot-middle'})\n\n\n            distroplots.selectAll('line.nv-distroplot-middle')\n                .watchTransition(renderWatch, 'nv-distroplot-x-group: distroplots line')\n                .attr('x1', notchBox ? tickLeft : plotType != 'violin' ? areaLeft : tickLeft())\n                .attr('y1', function(d,i,j) { return centralTendency == 'mean' ? yScale(getMean(d)) : yScale(getQ2(d)); })\n                .attr('x2', notchBox ? tickRight : plotType != 'violin' ? areaRight : tickRight())\n                .attr('y2', function(d,i) { return centralTendency == 'mean' ? yScale(getMean(d)) : yScale(getQ2(d)); })\n                .style('opacity', centralTendency ? '1' : '0');\n\n\n            // tooltip\n            distroplots.selectAll('.nv-distroplot-middle')\n                .on('mouseover', function(d,i,j) {\n                    if (d3.select(this).style('opacity') == 0) return; // don't show tooltip for hidden lines\n                    var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        value: centralTendency == 'mean' ? 'Mean' : 'Median',\n                        series: { key: centralTendency == 'mean' ? getMean(d).toFixed(2) : getQ2(d).toFixed(2), color: fillColor },\n                        e: d3.event\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    if (d3.select(this).style('opacity') == 0) return; // don't show tooltip for hidden lines\n                    d3.select(this).classed('hover', false);\n                    var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                    dispatch.elementMouseout({\n                        value: centralTendency == 'mean' ? 'Mean' : 'Median',\n                        series: { key: centralTendency == 'mean' ? getMean(d).toFixed(2) : getQ2(d).toFixed(2), color: fillColor },\n                        e: d3.event\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                });\n\n\n            // setup observations\n            // create DOMs even if not requested (and hide them), so that\n            // we can do transitions on them\n            var obsWrap = distroplots.selectAll('g.nv-distroplot-observation')\n                .data(function(d) { return getValsObj(d) }, function(d) {  return d.object_constancy; });\n\n            var obsGroup = obsWrap.enter()\n                .append('g')\n                .attr('class', 'nv-distroplot-observation')\n\n            obsGroup.append('circle')\n                .style({'opacity': 0})\n\n            obsGroup.append('line')\n                .style('stroke-width', 1)\n                .style({'stroke': d3.rgb(85, 85, 85), 'opacity': 0})\n\n            obsWrap.exit().remove();\n            obsWrap.attr('class', function(d) { return 'nv-distroplot-observation ' + (isOutlier(d) && plotType == 'box' ? 'nv-distroplot-outlier' : 'nv-distroplot-non-outlier')})\n\n            // transition observations\n            if (observationType == 'line') {\n                distroplots.selectAll('g.nv-distroplot-observation line')\n                  .watchTransition(renderWatch, 'nv-distrolot-x-group: nv-distoplot-observation')\n                    .attr(\"x1\", tickLeft() + areaWidth()/4)\n                    .attr(\"x2\", tickRight() - areaWidth()/4)\n                    .attr('y1', function(d) { return yScale(d.datum)})\n                    .attr('y2', function(d) { return yScale(d.datum)});\n            } else {\n                distroplots.selectAll('g.nv-distroplot-observation circle')\n                  .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                    .attr('cy', function(d) { return yScale(d.datum); })\n                    .attr('r', pointSize);\n\n                // NOTE: this update can be slow when re-sizing window when many point visible \n                // TODO: filter selection down to only visible points, no need to update x-position\n                //       of the hidden points\n                distroplots.selectAll('g.nv-distroplot-observation circle')\n                  .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                    .attr('cx', function(d) { return observationType == 'swarm' ? d.x + areaWidth()/2 : observationType == 'random' ? areaWidth()/2 + d.randX * areaWidth()/2 : areaWidth()/2; })\n\n            }\n\n            // set opacity on outliers/non-outliers\n            // any circle/line entering has opacity 0\n            if (observationType !== false) { // observationType is False when hidding all circle/lines\n                if (!showOnlyOutliers) { // show all line/circle\n                    distroplots.selectAll(observationType== 'line' ? 'line':'circle')\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',1)\n                } else { // show only outliers\n                    distroplots.selectAll('.nv-distroplot-outlier '+ (observationType== 'line' ? 'line':'circle'))\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',1)\n                    distroplots.selectAll('.nv-distroplot-non-outlier '+ (observationType== 'line' ? 'line':'circle'))\n                      .watchTransition(renderWatch, 'nv-distroplot: nv-distroplot-observation')\n                        .style('opacity',0)\n                }\n            }\n\n            // hide all other observations\n            distroplots.selectAll('.nv-distroplot-observation' + (observationType=='line'?' circle':' line'))\n              .watchTransition(renderWatch, 'nv-distroplot: nv-distoplot-observation')\n                .style('opacity',0)\n\n            // tooltip events for observations\n            distroplots.selectAll('.nv-distroplot-observation')\n                    .on('mouseover', function(d,i,j) {\n                        var pt = d3.select(this);\n                        if (showOnlyOutliers && plotType == 'box' && !isOutlier(d)) return; // don't show tooltip for hidden observation\n                        var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                        pt.classed('hover', true);\n                        dispatch.elementMouseover({\n                            value: (plotType == 'box' && isOutlier(d)) ? 'Outlier' : 'Observation',\n                            series: { key: d.datum.toFixed(2), color: fillColor },\n                            e: d3.event\n                        });\n                    })\n                    .on('mouseout', function(d,i,j) {\n                        var pt = d3.select(this);\n                        var fillColor = d3.select(this.parentNode).style('fill'); // color set by parent g fill\n                        pt.classed('hover', false);\n                        dispatch.elementMouseout({\n                            value: (plotType == 'box' && isOutlier(d)) ? 'Outlier' : 'Observation',\n                            series: { key: d.datum.toFixed(2), color: fillColor },\n                            e: d3.event\n                        });\n                    })\n                    .on('mousemove', function(d,i) {\n                        dispatch.elementMousemove({e: d3.event});\n                    });\n\n        });\n\n        renderWatch.renderEnd('nv-distroplot-x-group immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:            {get: function(){return width;}, set: function(_){width=_;}},\n        height:           {get: function(){return height;}, set: function(_){height=_;}},\n        maxBoxWidth:      {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}},\n        x:                {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:                {get: function(){return getY;}, set: function(_){getY=_;}},\n        plotType:         {get: function(){return plotType;}, set: function(_){plotType=_;}}, // plotType of background: 'box', 'violin' - default: 'box'\n        observationType:  {get: function(){return observationType;}, set: function(_){observationType=_;}}, // type of observations to show: 'random', 'swarm', 'line', 'point' - default: false (don't show observations)\n        whiskerDef:       {get: function(){return whiskerDef;}, set: function(_){whiskerDef=_;}}, // type of whisker to render: 'iqr', 'minmax', 'stddev' - default: iqr\n        notchBox:         {get: function(){return notchBox;}, set: function(_){notchBox=_;}}, // bool whether to notch box\n        hideWhiskers:     {get: function(){return hideWhiskers;}, set: function(_){hideWhiskers=_;}},\n        colorGroup:       {get: function(){return colorGroup;}, set: function(_){colorGroup=_;}}, // data key to use to set color group of each x-category - default: don't group\n        centralTendency:       {get: function(){return centralTendency;}, set: function(_){centralTendency=_;}}, // add a mean or median line to the data - default: don't show, must be one of 'mean' or 'median'\n        bandwidth:        {get: function(){return bandwidth;}, set: function(_){bandwidth=_;}}, // bandwidth for kde calculation, can be float or str, if str, must be one of scott or silverman\n        clampViolin:           {get: function(){return clampViolin;}, set: function(_){clampViolin=_;}},\n        resolution:       {get: function(){return resolution;}, set: function(_){resolution=_;}}, // resolution for kde calculation, default 50\n        xScale:           {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:           {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        showOnlyOutliers: {get: function(){return showOnlyOutliers;}, set: function(_){showOnlyOutliers=_;}}, // show only outliers in box plot, default true\n        jitter:           {get: function(){return jitter;}, set: function(_){jitter=_;}}, // faction of that jitter should take up in 'random' observationType, must be in range [0,1]; see jitterX(), default 0.7\n        squash:           {get: function(){return squash;}, set: function(_){squash=_;}}, // whether to squash sparse distribution of color groups towards middle of x-axis position\n        pointSize:     {get: function(){return pointSize;}, set: function(_){pointSize=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        recalcData:   {get: function() { reformatDat = prepData(container.datum()); } },\n        itemColor:    {get: function(){return getColor;}, set: function(_){getColor=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/distroPlotChart.js",
    "content": "nv.models.distroPlotChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var distroplot = nv.models.distroPlot(),\n        xAxis = nv.models.axis(),\n        yAxis = nv.models.axis()\n\n    var margin = {top: 25, right: 10, bottom: 40, left: 60},\n        width = null,\n        height = null,\n        color = nv.utils.getColor(),\n        showXAxis = true,\n        showYAxis = true,\n        rightAlignYAxis = false,\n        staggerLabels = false,\n        xLabel = false,\n        yLabel = false,\n        tooltip = nv.models.tooltip(),\n        x, y,\n        noData = 'No Data Available.',\n        dispatch = d3.dispatch('stateChange', 'beforeUpdate', 'renderEnd'),\n        duration = 500;\n\n    xAxis\n        .orient('bottom')\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip.duration(0);\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var colorGroup0, marginTop0 = margin.top, x0, y0, resolution0, bandwidth0, clampViolin0;\n    var dataCache;\n\n\n    // return true if data has changed somehow after\n    // an .update() was called\n    // works by comparing current data set to the\n    // one previously cached\n    // TODO - since we keep another version of the dataset\n    // around for comparison, it doubles the memory usage :(\n    function dataHasChanged(d) {\n        if (arraysEqual(d, dataCache)) {\n            return false;\n        } else {\n            dataCache = JSON.parse(JSON.stringify(d)) // deep copy\n            return true;\n        }\n    }\n\n    // return true if array of objects equivalent\n    function arraysEqual(arr1, arr2) {\n        if(arr1.length !== arr2.length) return false;\n\n        for(var i = arr1.length; i--;) {\n            if ('object_constancy' in arr1[i]) delete arr1[i].object_constancy\n            if ('object_constancy' in arr2[i]) delete arr2[i].object_constancy\n\n            if(!objectEquals(arr1[i], arr2[i])) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    // return true if objects are equivalent\n    function objectEquals(a, b) {\n        // Create arrays of property names\n        var aProps = Object.getOwnPropertyNames(a);\n        var bProps = Object.getOwnPropertyNames(b);\n\n        // If number of properties is different,\n        // objects are not equivalent\n        if (aProps.length != bProps.length) {\n            return false;\n        }\n\n        for (var i = 0; i < aProps.length; i++) {\n            var propName = aProps[i];\n\n            // If values of same property are not equal,\n            // objects are not equivalent\n            if (a[propName] !== b[propName]) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(distroplot);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this), that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = (width  || parseInt(container.style('width')) || 960) - margin.left - margin.right;\n            var availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;\n\n            if (typeof dataCache === 'undefined') {\n                dataCache = JSON.parse(JSON.stringify(data)) // deep copy\n            }\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                var opts = distroplot.options()\n                if (colorGroup0 !== opts.colorGroup() || // recalc data when any of the axis accessors are changed\n                    x0 !== opts.x() ||\n                    y0 !== opts.y() ||\n                    bandwidth0 !== opts.bandwidth() ||\n                    resolution0 !== opts.resolution() ||\n                    clampViolin0 !== opts.clampViolin() ||\n                    dataHasChanged(data)\n                ) {\n                    distroplot.recalcData();\n                }\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n\n            if (typeof d3.beeswarm !== 'function' && chart.options().observationType() == 'swarm') {\n                var xPos = margin.left + availableWidth/2;\n                noData = 'Please include the library https://github.com/Kcnarf/d3-beeswarm to use \"swarm\".'\n                nv.utils.noData(chart, container);\n                return chart;\n            } else if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = distroplot.xScale();\n            y = distroplot.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-distroPlot').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-distroPlot').append('g');\n            var defsEnter = gEnter.append('defs');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n\n            gEnter.append('g').attr('class', 'nv-distroWrap');\n            gEnter.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            g.watchTransition(renderWatch, 'nv-wrap: wrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(' + availableWidth + ',0)');\n            }\n\n\n            // Main Chart Component(s)\n            distroplot.width(availableWidth).height(availableHeight);\n\n            var distroWrap = g.select('.nv-distroWrap')\n                .datum(data)\n\n            distroWrap.transition().call(distroplot);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-x-label-clip-' + distroplot.id())\n                .append('rect');\n\n            g.select('#nv-x-label-clip-' + distroplot.id() + ' rect')\n                .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))\n                .attr('height', 16)\n                .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    .ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis').attr('transform', 'translate(0,' + y.range()[0] + ')')\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                //g.select('.nv-x.nv-axis').select('.nv-axislabel')\n                //    .style('font-size', d3.min([availableWidth * 0.05,20]) + 'px')\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n                if (staggerLabels) {\n                    xTicks\n                        .selectAll('text')\n                        .attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 === 0 ? '5' : '17') + ')' })\n                }\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    .ticks( Math.floor(availableHeight/36) ) // can't use nv.utils.calcTicksY with Object data\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis').call(yAxis);\n\n                //g.select('.nv-y.nv-axis').select('.nv-axislabel')\n                //    .style('font-size', d3.min([availableHeight * 0.05,20]) + 'px')\n            }\n\n\n\n\n            // Zero line on chart bottom\n            g.select('.nv-zeroLine line')\n                .attr('x1',0)\n                .attr('x2',availableWidth)\n                .attr('y1', y(0))\n                .attr('y2', y(0))\n            ;\n\n            // store original values so that we can\n            // call 'recalcData()' if needed\n            colorGroup0 = distroplot.options().colorGroup();\n            x0 = distroplot.options().x();\n            y0 = distroplot.options().y();\n            bandwidth0 = distroplot.options().bandwidth();\n            resolution0 = distroplot.options().resolution();\n            clampViolin0 = distroplot.options().clampViolin();\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n        });\n\n        renderWatch.renderEnd('nv-distroplot chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    distroplot.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    distroplot.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.data(evt).hidden(true);\n    });\n\n    distroplot.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.distroplot = distroplot;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        tooltipContent:    {get: function(){return tooltip;}, set: function(_){tooltip=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            distroplot.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            distroplot.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        xLabel:  {get: function(){return xLabel;}, set: function(_){\n            xLabel=_;\n            xAxis.axisLabel(xLabel);\n        }},\n        yLabel:  {get: function(){return yLabel;}, set: function(_){\n            yLabel=_;\n            yAxis.axisLabel(yLabel);\n        }},\n    });\n\n\n    nv.utils.inheritOptions(chart, distroplot);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n"
  },
  {
    "path": "src/models/focus.js",
    "content": "nv.models.focus = function(content) {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var content = content || nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , brush = d3.svg.brush()\n        ;\n\n    var margin = {top: 10, right: 0, bottom: 30, left: 0}\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = 70\n        , showXAxis = true\n        , showYAxis = false\n        , rightAlignYAxis = false\n        , ticks = null\n        , x\n        , y\n        , brushExtent = null\n        , duration = 250\n        , dispatch = d3.dispatch('brush', 'onBrush', 'renderEnd')\n        , syncBrushing = true\n        ;\n\n    content.interactive(false);\n    content.pointActive(function(d) { return false; });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(content);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = height - margin.top - margin.bottom;\n\n            chart.update = function() { \n                if( duration === 0 ) {\n                    container.call( chart );\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = this;\n\n            // Setup Scales\n            x = content.xScale();\n            y = content.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-focus').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-focus').append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            gEnter.append('g').attr('class', 'nv-background').append('rect');\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-contentWrap');\n            gEnter.append('g').attr('class', 'nv-brushBackground');\n            gEnter.append('g').attr('class', 'nv-x nv-brush');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n                \n            content\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var contentWrap = g.select('.nv-contentWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n            d3.transition(contentWrap).call(content);\n            \n            // Setup Brush\n            brush\n                .x(x)\n                .on('brush', function() {\n                    onBrush(syncBrushing);\n                });\n\n            brush.on('brushend', function () {\n                if (!syncBrushing) {\n                    dispatch.onBrush(brush.empty() ? x.domain() : brush.extent());\n                }\n            });\n\n            if (brushExtent) brush.extent(brushExtent);\n\n            var brushBG = g.select('.nv-brushBackground').selectAll('g')\n                .data([brushExtent || brush.extent()]);\n    \n            var brushBGenter = brushBG.enter()\n                .append('g');\n\n            brushBGenter.append('rect')\n                .attr('class', 'left')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight);\n\n            brushBGenter.append('rect')\n                .attr('class', 'right')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight);\n\n            var gBrush = g.select('.nv-x.nv-brush')\n                .call(brush);\n            gBrush.selectAll('rect')\n                .attr('height', availableHeight);\n            gBrush.selectAll('.resize').append('path').attr('d', resizePath);\n\n            onBrush(true);\n\n            g.select('.nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            if (showXAxis) {\n                xAxis.scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n  \n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                d3.transition(g.select('.nv-x.nv-axis'))\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                d3.transition(g.select('.nv-y.nv-axis'))\n                    .call(yAxis);\n            }\n            \n            g.select('.nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + y.range()[0] + ')');\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n    \n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight / 3;\n                return 'M' + (0.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (0.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n    \n    \n            function updateBrushBG() {\n                if (!brush.empty()) brush.extent(brushExtent);\n                brushBG\n                    .data([brush.empty() ? x.domain() : brushExtent])\n                    .each(function(d,i) {\n                        var leftWidth = x(d[0]) - x.range()[0],\n                            rightWidth = availableWidth - x(d[1]);\n                        d3.select(this).select('.left')\n                            .attr('width',  leftWidth < 0 ? 0 : leftWidth);\n    \n                        d3.select(this).select('.right')\n                            .attr('x', x(d[1]))\n                            .attr('width', rightWidth < 0 ? 0 : rightWidth);\n                    });\n            }\n\n\n            function onBrush(shouldDispatch) {\n                brushExtent = brush.empty() ? null : brush.extent();\n                var extent = brush.empty() ? x.domain() : brush.extent();\n                dispatch.brush({extent: extent, brush: brush});\n                updateBrushBG();\n                if (shouldDispatch) {\n                    dispatch.onBrush(extent);\n                }\n            }\n        });\n\n        renderWatch.renderEnd('focus immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.content = content;\n    chart.brush = brush;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        brushExtent: {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}},\n        syncBrushing: {get: function(){return syncBrushing;}, set: function(_){syncBrushing=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            content.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            content.color(color);\n        }},\n        interpolate: {get: function(){return content.interpolate();}, set: function(_){\n            content.interpolate(_);\n        }},\n        xTickFormat: {get: function(){return xAxis.tickFormat();}, set: function(_){\n            xAxis.tickFormat(_);\n        }},\n        yTickFormat: {get: function(){return yAxis.tickFormat();}, set: function(_){\n            yAxis.tickFormat(_);\n        }},\n        x: {get: function(){return content.x();}, set: function(_){\n            content.x(_);\n        }},\n        y: {get: function(){return content.y();}, set: function(_){\n            content.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, content);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/forceDirectedGraph.js",
    "content": "nv.models.forceDirectedGraph = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n    var margin = {top: 2, right: 0, bottom: 2, left: 0}\n        , width = 400\n        , height = 32\n        , container = null\n        , dispatch = d3.dispatch('renderEnd')\n        , color = nv.utils.getColor(['#000'])\n        , tooltip      = nv.models.tooltip()\n        , noData = null\n        // Force directed graph specific parameters [default values]\n        , linkStrength = 0.1\n        , friction = 0.9\n        , linkDist = 30\n        , charge = -120\n        , gravity = 0.1\n        , theta = 0.8\n        , alpha = 0.1\n        , radius = 5\n        // These functions allow to add extra attributes to ndes and links\n        ,nodeExtras = function(nodes) { /* Do nothing */ }\n        ,linkExtras = function(links) { /* Do nothing */ }\n        , getX=d3.functor(0.0)\n        , getY=d3.functor(0.0)\n        ;\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n\n        selection.each(function(data) {\n          container = d3.select(this);\n          nv.utils.initSVG(container);\n\n          var availableWidth = nv.utils.availableWidth(width, container, margin),\n              availableHeight = nv.utils.availableHeight(height, container, margin);\n\n          container\n                  .attr(\"width\", availableWidth)\n                  .attr(\"height\", availableHeight);\n\n          // Display No Data message if there's nothing to show.\n          if (!data || !data.links || !data.nodes) {\n              nv.utils.noData(chart, container)\n              return chart;\n          } else {\n              container.selectAll('.nv-noData').remove();\n          }\n          container.selectAll('*').remove();\n\n          // Collect names of all fields in the nodes\n          var nodeFieldSet = new Set();\n          data.nodes.forEach(function(node) {\n            var keys = Object.keys(node);\n            keys.forEach(function(key) {\n              nodeFieldSet.add(key);\n            });\n          });\n\n          var force = d3.layout.force()\n                .nodes(data.nodes)\n                .links(data.links)\n                .size([availableWidth, availableHeight])\n                .linkStrength(linkStrength)\n                .friction(friction)\n                .linkDistance(linkDist)\n                .charge(charge)\n                .gravity(gravity)\n                .theta(theta)\n                .alpha(alpha)\n                .start();\n\n          var link = container.selectAll(\".link\")\n                .data(data.links)\n                .enter().append(\"line\")\n                .attr(\"class\", \"nv-force-link\")\n                .style(\"stroke-width\", function(d) { return Math.sqrt(d.value); });\n\n          var node = container.selectAll(\".node\")\n                .data(data.nodes)\n                .enter()\n                .append(\"g\")\n                .attr(\"class\", \"nv-force-node\")\n                .call(force.drag);\n\n          node\n            .append(\"circle\")\n            .attr(\"r\", radius)\n            .style(\"fill\", function(d) { return color(d) } )\n            .on(\"mouseover\", function(evt) {\n              container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                  .attr('y1', evt.py);\n              container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                  .attr('x2', evt.px);\n\n              // Add 'series' object to\n              var nodeColor = color(evt);\n              evt.series = [];\n              nodeFieldSet.forEach(function(field) {\n                evt.series.push({\n                  color: nodeColor,\n                  key:   field,\n                  value: evt[field]\n                });\n              });\n              tooltip.data(evt).hidden(false);\n            })\n            .on(\"mouseout\",  function(d) {\n              tooltip.hidden(true);\n            });\n\n          tooltip.headerFormatter(function(d) {return \"Node\";});\n\n          // Apply extra attributes to nodes and links (if any)\n          linkExtras(link);\n          nodeExtras(node);\n\n          force.on(\"tick\", function() {\n              link.attr(\"x1\", function(d) { return d.source.x; })\n                  .attr(\"y1\", function(d) { return d.source.y; })\n                  .attr(\"x2\", function(d) { return d.target.x; })\n                  .attr(\"y2\", function(d) { return d.target.y; });\n\n              node.attr(\"transform\", function(d) {\n                return \"translate(\" + d.x + \", \" + d.y + \")\";\n              });\n            });\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:     {get: function(){return width;}, set: function(_){width=_;}},\n        height:    {get: function(){return height;}, set: function(_){height=_;}},\n\n        // Force directed graph specific parameters\n        linkStrength:{get: function(){return linkStrength;}, set: function(_){linkStrength=_;}},\n        friction:    {get: function(){return friction;}, set: function(_){friction=_;}},\n        linkDist:    {get: function(){return linkDist;}, set: function(_){linkDist=_;}},\n        charge:      {get: function(){return charge;}, set: function(_){charge=_;}},\n        gravity:     {get: function(){return gravity;}, set: function(_){gravity=_;}},\n        theta:       {get: function(){return theta;}, set: function(_){theta=_;}},\n        alpha:       {get: function(){return alpha;}, set: function(_){alpha=_;}},\n        radius:      {get: function(){return radius;}, set: function(_){radius=_;}},\n\n        //functor options\n        x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},\n        y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        nodeExtras: {get: function(){return nodeExtras;}, set: function(_){\n            nodeExtras = _;\n        }},\n        linkExtras: {get: function(){return linkExtras;}, set: function(_){\n            linkExtras = _;\n        }}\n    });\n\n    chart.dispatch = dispatch;\n    chart.tooltip = tooltip;\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/furiousLegend.js",
    "content": "nv.models.furiousLegend = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , width = 400\n        , height = 20\n        , getKey = function(d) { return d.key }\n        , keyFormatter = function (d) { return d }\n        , color = nv.utils.getColor()\n        , maxKeyLength = 20 //default value for key lengths\n        , align = true\n        , padding = 28 //define how much space between legend items. - recommend 32 for furious version\n        , rightAlign = true\n        , updateState = true   //If true, legend will update data.disabled and trigger a 'stateChange' dispatch.\n        , radioButtonMode = false   //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time)\n        , expanded = false\n        , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange')\n        , vers = 'classic' //Options are \"classic\" and \"furious\"\n        ;\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-legend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var series = g.selectAll('.nv-series')\n                .data(function(d) {\n                    if(vers != 'furious') return d;\n\n                    return d.filter(function(n) {\n                        return expanded ? true : !n.disengaged;\n                    });\n                });\n            var seriesEnter = series.enter().append('g').attr('class', 'nv-series')\n\n            var seriesShape;\n\n            if(vers == 'classic') {\n                seriesEnter.append('circle')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('r', 5);\n\n                seriesShape = series.select('circle');\n            } else if (vers == 'furious') {\n                seriesEnter.append('rect')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('rx', 3)\n                    .attr('ry', 3);\n\n                seriesShape = series.select('rect');\n\n                seriesEnter.append('g')\n                    .attr('class', 'nv-check-box')\n                    .property('innerHTML','<path d=\"M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z\" class=\"nv-box\"></path><path d=\"M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511\" class=\"nv-check\"></path>')\n                    .attr('transform', 'translate(-10,-8)scale(0.5)');\n\n                var seriesCheckbox = series.select('.nv-check-box');\n\n                seriesCheckbox.each(function(d,i) {\n                    d3.select(this).selectAll('path')\n                        .attr('stroke', setTextColor(d,i));\n                });\n            }\n\n            seriesEnter.append('text')\n                .attr('text-anchor', 'start')\n                .attr('class','nv-legend-text')\n                .attr('dy', '.32em')\n                .attr('dx', '8');\n\n            var seriesText = series.select('text.nv-legend-text');\n\n            series\n                .on('mouseover', function(d,i) {\n                    dispatch.legendMouseover(d,i);  //TODO: Make consistent with other event objects\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.legendMouseout(d,i);\n                })\n                .on('click', function(d,i) {\n                    dispatch.legendClick(d,i);\n                    // make sure we re-get data in case it was modified\n                    var data = series.data();\n                    if (updateState) {\n                        if(vers =='classic') {\n                            if (radioButtonMode) {\n                                //Radio button mode: set every series to disabled,\n                                //  and enable the clicked series.\n                                data.forEach(function(series) { series.disabled = true});\n                                d.disabled = false;\n                            }\n                            else {\n                                d.disabled = !d.disabled;\n                                if (data.every(function(series) { return series.disabled})) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) { series.disabled = false});\n                                }\n                            }\n                        } else if(vers == 'furious') {\n                            if(expanded) {\n                                d.disengaged = !d.disengaged;\n                                d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled;\n                                d.disabled = d.disengaged || d.userDisabled;\n                            } else if (!expanded) {\n                                d.disabled = !d.disabled;\n                                d.userDisabled = d.disabled;\n                                var engaged = data.filter(function(d) { return !d.disengaged; });\n                                if (engaged.every(function(series) { return series.userDisabled })) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) {\n                                        series.disabled = series.userDisabled = false;\n                                    });\n                                }\n                            }\n                        }\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled }),\n                            disengaged: data.map(function(d) { return !!d.disengaged })\n                        });\n\n                    }\n                })\n                .on('dblclick', function(d,i) {\n                    if(vers == 'furious' && expanded) return;\n                    dispatch.legendDblclick(d,i);\n                    if (updateState) {\n                        // make sure we re-get data in case it was modified\n                        var data = series.data();\n                        //the default behavior of NVD3 legends, when double clicking one,\n                        // is to set all other series' to false, and make the double clicked series enabled.\n                        data.forEach(function(series) {\n                            series.disabled = true;\n                            if(vers == 'furious') series.userDisabled = series.disabled;\n                        });\n                        d.disabled = false;\n                        if(vers == 'furious') d.userDisabled = d.disabled;\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled })\n                        });\n                    }\n                });\n\n            series.classed('nv-disabled', function(d) { return d.userDisabled });\n            series.exit().remove();\n\n            seriesText\n                .attr('fill', setTextColor)\n                .text(function (d) { return keyFormatter(getKey(d)) });\n\n            //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option)\n            // NEW ALIGNING CODE, TODO: clean up\n\n            var versPadding;\n            switch(vers) {\n                case 'furious' :\n                    versPadding = 23;\n                    break;\n                case 'classic' :\n                    versPadding = 20;\n            }\n\n            if (align) {\n\n                var seriesWidths = [];\n                series.each(function(d,i) {\n                    var legendText;\n                    if (keyFormatter(getKey(d)) && keyFormatter(getKey(d)).length > maxKeyLength) {\n                        var trimmedKey = keyFormatter(getKey(d)).substring(0, maxKeyLength);\n                        legendText = d3.select(this).select('text').text(trimmedKey + \"...\");\n                        d3.select(this).append(\"svg:title\").text(keyFormatter(getKey(d)));\n                    } else {\n                        legendText = d3.select(this).select('text');\n                    }\n                    var nodeTextLength;\n                    try {\n                        nodeTextLength = legendText.node().getComputedTextLength();\n                        // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead\n                        if(nodeTextLength <= 0) throw Error();\n                    }\n                    catch(e) {\n                        nodeTextLength = nv.utils.calcApproxTextWidth(legendText);\n                    }\n\n                    seriesWidths.push(nodeTextLength + padding);\n                });\n\n                var seriesPerRow = 0;\n                var legendWidth = 0;\n                var columnWidths = [];\n\n                while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {\n                    columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];\n                    legendWidth += seriesWidths[seriesPerRow++];\n                }\n                if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row\n\n                while ( legendWidth > availableWidth && seriesPerRow > 1 ) {\n                    columnWidths = [];\n                    seriesPerRow--;\n\n                    for (var k = 0; k < seriesWidths.length; k++) {\n                        if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )\n                            columnWidths[k % seriesPerRow] = seriesWidths[k];\n                    }\n\n                    legendWidth = columnWidths.reduce(function(prev, cur, index, array) {\n                        return prev + cur;\n                    });\n                }\n\n                var xPositions = [];\n                for (var i = 0, curX = 0; i < seriesPerRow; i++) {\n                    xPositions[i] = curX;\n                    curX += columnWidths[i];\n                }\n\n                series\n                    .attr('transform', function(d, i) {\n                        return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                if (rightAlign) {\n                    g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');\n                }\n                else {\n                    g.attr('transform', 'translate(0' + ',' + margin.top + ')');\n                }\n\n                height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding);\n\n            } else {\n\n                var ypos = 5,\n                    newxpos = 5,\n                    maxwidth = 0,\n                    xpos;\n                series\n                    .attr('transform', function(d, i) {\n                        var length = d3.select(this).select('text').node().getComputedTextLength() + padding;\n                        xpos = newxpos;\n\n                        if (width < margin.left + margin.right + xpos + length) {\n                            newxpos = xpos = 5;\n                            ypos += versPadding;\n                        }\n\n                        newxpos += length;\n                        if (newxpos > maxwidth) maxwidth = newxpos;\n\n                        return 'translate(' + xpos + ',' + ypos + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');\n\n                height = margin.top + margin.bottom + ypos + 15;\n            }\n\n            if(vers == 'furious') {\n                // Size rectangles after text is placed\n                seriesShape\n                    .attr('width', function(d,i) {\n                        return seriesText[0][i].getComputedTextLength() + 27;\n                    })\n                    .attr('height', 18)\n                    .attr('y', -9)\n                    .attr('x', -15)\n            }\n\n            seriesShape\n                .style('fill', setBGColor)\n                .style('stroke', function(d,i) { return d.color || color(d, i) });\n        });\n\n        function setTextColor(d,i) {\n            if(vers != 'furious') return '#000';\n            if(expanded) {\n                return d.disengaged ? color(d,i) : '#fff';\n            } else if (!expanded) {\n                return !!d.disabled ? color(d,i) : '#fff';\n            }\n        }\n\n        function setBGColor(d,i) {\n            if(expanded && vers == 'furious') {\n                return d.disengaged ? '#fff' : color(d,i);\n            } else {\n                return !!d.disabled ? '#fff' : color(d,i);\n            }\n        }\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:          {get: function(){return width;}, set: function(_){width=_;}},\n        height:         {get: function(){return height;}, set: function(_){height=_;}},\n        key:            {get: function(){return getKey;}, set: function(_){getKey=_;}},\n        keyFormatter:   {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        align:          {get: function(){return align;}, set: function(_){align=_;}},\n        rightAlign:     {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}},\n        maxKeyLength:   {get: function(){return maxKeyLength;}, set: function(_){maxKeyLength=_;}},\n        padding:        {get: function(){return padding;}, set: function(_){padding=_;}},\n        updateState:    {get: function(){return updateState;}, set: function(_){updateState=_;}},\n        radioButtonMode:{get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}},\n        expanded:       {get: function(){return expanded;}, set: function(_){expanded=_;}},\n        vers:           {get: function(){return vers;}, set: function(_){vers=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/heatMap.js",
    "content": "/* \nImprovements:\n- consistenly apply no-hover classes to rect isntead of to containing g, see example CSS style for .no-hover rect, rect.no-hover\n- row/column order (user specified) or 'ascending' / 'descending'\n- I haven't tested for transitions between changing datasets\n*/\n\nnv.models.heatMap = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container\n        , xScale = d3.scale.ordinal()\n        , yScale = d3.scale.ordinal()\n        , colorScale = false\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getCellValue = function(d) { return d.value }\n        , showCellValues = true\n        , cellValueFormat = function(d) { return typeof d === 'number' ? d.toFixed(0) : d }\n        , cellAspectRatio = false // width / height of cell\n        , cellRadius = 2\n        , cellBorderWidth = 4 // pixels between cells\n        , normalize = false\n        , highContrastText = true\n        , xDomain\n        , yDomain\n        , xMetaColorScale = nv.utils.defaultColor()\n        , yMetaColorScale = nv.utils.defaultColor()\n        , missingDataColor = '#bcbcbc'\n        , missingDataLabel = ''\n        , metaOffset = 5 // spacing between meta rects and cells\n        , xRange\n        , yRange\n        , xMeta\n        , yMeta\n        , colorRange\n        , colorDomain\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , duration = 250\n        , xMetaHeight = function(d) { return cellHeight / 3 }\n        , yMetaWidth = function(d) { return cellWidth / 3 }\n        , showGrid = false\n        ;\n\n\n\n    //============================================================\n    // Aux helper function for heatmap\n    //------------------------------------------------------------\n    // choose high contrast text color based on background\n    // shameful steal: https://github.com/alexandersimoes/d3plus/blob/master/src/color/text.coffee\n    function cellTextColor(bgColor) {\n\n        if (highContrastText) {\n            var rgbColor = d3.rgb(bgColor);\n            var r = rgbColor.r;\n            var g = rgbColor.g;\n            var b = rgbColor.b;\n            var yiq = (r * 299 + g * 587 + b * 114) / 1000;\n            return yiq >= 128 ? \"#404040\" : \"#EDEDED\"; // dark text else light text\n        } else {\n            return 'black';\n        }\n    }\n\n    /* go through heatmap data and generate array of values\n     * for each row/column or for entire dataset; for use in\n     * calculating means/medians of data for normalizing\n     * @param {str} axis - 'row', 'col' or null\n     *\n     * @returns {row/column index: [array of values for row/col]}\n     * note that if axis is not specified, the return will be\n     * {0: [all values in heatmap]}\n     */\n    function getHeatmapValues(data, axis) {\n        var vals = {};\n\n        data.forEach(function(cell, i) {\n            if (axis == 'row') {\n                if (!(getIY(cell) in vals)) vals[getIY(cell)] = [];\n                vals[getIY(cell)].push(getCellValue(cell));\n            } else if (axis == 'col') {\n                if (!(getIX(cell) in vals)) vals[getIX(cell)] = [];\n                vals[getIX(cell)].push(getCellValue(cell));\n            } else if (axis == null) { // if calculating stat over entire dataset\n                if (!(0 in vals)) vals[0] = [];\n                vals[0].push(getCellValue(cell)); \n            }\n        })\n\n        return vals;\n    }\n\n    // calculate the median absolute deviation of the given array of data\n    // https://en.wikipedia.org/wiki/Median_absolute_deviation\n    // MAD = median(abs(Xi - median(X)))\n    function mad(dat) {\n        var med = d3.median(dat);\n        var vals = dat.map(function(d) { return Math.abs(d - med); })\n        return d3.median(vals);\n    }\n\n\n    // set cell color based on cell value\n    // depending on whether it should be normalized or not\n    function cellColor(d) {\n        var colorVal = normalize ? getNorm(d) : getCellValue(d);\n        return (cellsAreNumeric() && !isNaN(colorVal) || typeof colorVal !== 'undefined') ? colorScale(colorVal) : missingDataColor;\n    }\n\n    // return the domain of the color data\n    // if ordinal data is given for the cells, this will\n    // return all possible cells values; otherwise it\n    // returns the extent of the cell values\n    // will take into account normalization if specified\n    function getColorDomain() {\n    \n        if (cellsAreNumeric()) { // if cell values are numeric\n            return normalize ? d3.extent(prepedData, function(d) { return getNorm(d); }) : d3.extent(uniqueColor);\n        } else if (!cellsAreNumeric()) { // if cell values are ordinal\n            return uniqueColor;\n        }\n    }\n\n    // return true if cells are numeric\n    // as opposed to categorical\n    function cellsAreNumeric() {\n        return typeof uniqueColor[0] === 'number';\n    }\n\n    /*\n     * Normalize input data\n     *\n     * normalize must be one of centerX, robustCenterX, centerScaleX, robustCenterScaleX, centerAll, \n     * robustCenterAll, centerScaleAll, robustCenterScaleAll where X is either 'Row' or 'Column'\n     *\n     * - centerX: subtract row/column mean from cell\n     * - centerAll: subtract mean of whole data set from cell\n     * - centerScaleX: scale so that row/column has mean 0 and variance 1 (Z-score)\n     * - centerScaleAll: scale by overall normalization factor so that the whole data set has mean 0 and variance 1 (Z-score)\n     * - robustCenterX: subtract row/column median from cell\n     * - robustCenterScaleX: subtract row/column median from cell and then scale row/column by median absolute deviation\n     * - robustCenterAll: subtract median of whole data set from cell\n     * - robustCenterScaleAll: subtract overall median from cell and scale by overall median absolute deviation\n     */\n    function normalizeData(dat) {\n        \n        var normTypes = ['centerRow',\n            'robustCenterRow',\n            'centerScaleRow',\n            'robustCenterScaleRow',\n            'centerColumn',\n            'robustCenterColumn',\n            'centerScaleColumn',\n            'robustCenterScaleColumn',\n            'centerAll',\n            'robustCenterAll',\n            'centerScaleAll',\n            'robustCenterScaleAll'];\n\n\n        if(normTypes.indexOf(normalize) != -1) {\n\n            var xVals = Object.keys(uniqueX), yVals = Object.keys(uniqueY);\n\n            // setup normalization options\n            var scale = normalize.includes('Scale') ? true: false,\n                agg = normalize.includes('robust') ? 'median': 'mean',\n                axis = normalize.includes('Row') ? 'row' : normalize.includes('Column') ? 'col' : null,\n                vals = getHeatmapValues(dat, axis);\n\n            // calculate mean or median\n            // calculate standard dev or median absolute deviation\n            var stat = {};\n            var dev = {};\n            for (var key in vals) {\n                stat[key] = agg == 'mean' ? d3.mean(vals[key]) : d3.median(vals[key]);\n                if (scale) dev[key] = agg == 'mean' ? d3.deviation(vals[key]) : mad(vals[key]);\n            }\n\n\n            // do the normalizing\n            dat.forEach(function(cell, i) {\n                if (cellsAreNumeric()) {\n                    if (axis == 'row') {\n                        var key = getIY(cell);\n                    } else if (axis == 'col') {\n                        var key = getIX(cell);\n                    } else if (axis == null) {  // if calculating stat over entire dataset\n                        var key = 0;\n                    }\n\n                    var normVal = getCellValue(cell) - stat[key];\n                    if (scale) {\n                        cell._cellPos.norm = normVal / dev[key];\n                    } else {\n                        cell._cellPos.norm = normVal;\n                    }\n                } else {\n                    cell._cellPos.norm = getCellValue(cell); // if trying to normalize ordinal cells, just set norm to cell value\n                }\n            })\n\n        } else {\n            normalize = false; // proper normalize option was not provided, disable it so heatmap still shows colors\n        }\n\n        return dat;\n    }\n\n    /*\n     * Process incoming data for use with heatmap including:\n     * - adding a unique key indexer to each data point (idx)\n     * - getting a unique list of all x & y values\n     * - generating a position index (x & y) for each data point\n     * - sorting that data for correct traversal when generating rect\n     * - generating placeholders for missing data\n     *\n     * In order to allow for the flexibility of the user providing either\n     * categorical or quantitative data, we're going to position the cells\n     * through indices that we increment based on previously seen data\n     * this way we can use ordinal() axes even if the data is quantitative.\n     *\n     * When we generate the SVG elements, we assumes traversal occures from\n     * top to bottom and from left to right.\n     *\n     * @param data {list} - input data organize as a list of objects\n     *\n     * @return - copy of input data with additional '_cellPos' key\n     *           formatted as {idx: XXX, ix, XXX, iy: XXX}\n     *           where idx is a global identifier; ix is an identifier\n     *           within each column, and iy is an identifier within\n     *           each row. \n     */\n    function prepData(data) {\n\n        // reinitialize\n        uniqueX = {}, // {cell x value: ix index}\n        uniqueY = {}, // {cell y value: iy index}\n        uniqueColor = [], // [cell color value]\n        uniqueXMeta = [], // [cell x metadata value]\n        uniqueYMeta = [], // [cell y metadata value]\n        uniqueCells = []; // [cell x,y values stored as array]\n        var warnings = [];\n        var sortedCells = {}; // {cell x values: {cell y value: cell data, ... }, ... }\n\n        var ix = 0, iy = 0; // use these indices to position cell in x & y direction\n        var combo, idx=0;\n        data.forEach(function(cell) {\n            var valX = getX(cell),\n                valY = getY(cell),\n                valColor = getCellValue(cell);            \n\n            // assemble list of unique values for each dimension\n            if (!(valX in uniqueX)) { \n                uniqueX[valX] = ix; \n                ix++;\n\n                sortedCells[valX] = {}\n\n                if (typeof xMeta === 'function') uniqueXMeta.push(xMeta(cell));\n            }\n\n            if (!(valY in uniqueY)) {\n                uniqueY[valY] = iy; \n                iy++;\n\n                sortedCells[valX][valY] = {}\n\n                if (typeof yMeta === 'function') uniqueYMeta.push(yMeta(cell));\n            }\n            if (uniqueColor.indexOf(valColor) == -1) uniqueColor.push(valColor)\n\n\n            // for each data point, we generate an object of data\n            // needed to properly position each cell\n            cell._cellPos = {\n                idx: idx,\n                ix: uniqueX[valX],\n                iy: uniqueY[valY],\n            }\n            idx++;\n\n\n            // keep track of row & column combinations we've already seen\n            // this prevents the same cells from being generated when\n            // the user hasn't provided proper data (one value for each\n            // row & column).\n            // if properly formatted data is not provided, only the first\n            // row & column value is used (the rest are ignored)\n            combo = [valX, valY];\n            if (!isArrayInArray(uniqueCells, combo)) {\n                uniqueCells.push(combo)\n                sortedCells[valX][valY] = cell;\n            } else if (warnings.indexOf(valX + valY) == -1) {\n                warnings.push(valX + valY);\n                console.warn(\"The row/column position \" + valX + \"/\" + valY + \" has multiple values; ensure each cell has only a single value.\");\n            }\n\n        });\n\n        uniqueColor = uniqueColor.sort()\n\n        // check in sortedCells that each x has all the y's\n        // if not, generate an empty placeholder\n        // this will also sort all cells from left to right\n        // and top to bottom\n        var reformatData = [];\n        Object.keys(uniqueY).forEach(function(j) {\n            Object.keys(uniqueX).forEach(function(i) {\n                var cellVal = sortedCells[i][j];\n    \n                if (cellVal) {\n                    reformatData.push(cellVal);\n                } else {\n                    var cellPos = {\n                        idx: idx,\n                        ix: uniqueX[i],\n                        iy: uniqueY[j],\n                    }\n                    idx++;\n                    reformatData.push({_cellPos: cellPos}); // empty cell placeholder\n                }\n            })\n        })\n\n\n        // normalize data is needed\n        return normalize ? normalizeData(reformatData) : reformatData;\n\n    }\n\n    // https://stackoverflow.com/a/41661388/1153897\n    function isArrayInArray(arr, item){\n      var item_as_string = JSON.stringify(item);\n\n      var contains = arr.some(function(ele){\n        return JSON.stringify(ele) === item_as_string;\n      });\n      return contains;\n    }\n\n    function removeAllHoverClasses() {\n        // remove all hover classes\n        d3.selectAll('.cell-hover').classed('cell-hover', false);\n        d3.selectAll('.no-hover').classed('no-hover', false);\n        d3.selectAll('.row-hover').classed('row-hover', false);\n        d3.selectAll('.column-hover').classed('column-hover', false);\n    }\n\n    // return the formatted cell value if it is\n    // a number, otherwise return missingDataLabel\n    var cellValueLabel = function(d) {\n        var val = !normalize ? cellValueFormat(getCellValue(d)) : cellValueFormat(getNorm(d));\n        return (cellsAreNumeric() && !isNaN(val) || typeof val !== 'undefined') ? val : missingDataLabel;\n    }\n\n    // https://stackoverflow.com/a/16794116/1153897\n    // note this returns the obj keys\n    function sortObjByVals(obj) {\n        return Object.keys(obj).sort(function(a,b){return obj[a]-obj[b]})\n    }\n\n    // https://stackoverflow.com/a/28191966/1153897\n    function getKeyByValue(object, value) {\n        //return Object.keys(object).find(key => object[key] === value);\n        return Object.keys(object).filter(function(key) {return object[key] === value})[0];\n    }\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var prepedData, cellHeight, cellWidth;\n    var uniqueX = {}, uniqueY = {}, uniqueColor = [];\n    var uniqueXMeta = [], uniqueYMeta = [], uniqueCells = []\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n    var RdYlBu = [\"#a50026\",\"#d73027\",\"#f46d43\",\"#fdae61\",\"#fee090\",\"#ffffbf\",\"#e0f3f8\",\"#abd9e9\",\"#74add1\",\"#4575b4\",\"#313695\"];\n\n    var getCellPos = function(d) { return d._cellPos; };\n    var getIX = function(d) { return getCellPos(d).ix; } // get the given cell's x index position\n    var getIY = function(d) { return getCellPos(d).iy; } // get the given cell's y index position\n    var getNorm = function(d) { return getCellPos(d).norm; }\n    var getIdx = function(d) { return getCellPos(d).idx; }\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n\n            prepedData = prepData(data);\n\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            // available width/height set the cell dimenions unless\n            // the aspect ratio is defined - in that case the cell\n            // height is adjusted and availableHeight updated\n            cellWidth = availableWidth / Object.keys(uniqueX).length;\n            cellHeight = cellAspectRatio ? cellWidth / cellAspectRatio : availableHeight / Object.keys(uniqueY).length;\n            if (cellAspectRatio) availableHeight = cellHeight * Object.keys(uniqueY).length - margin.top - margin.bottom;\n\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n  \n            // Setup Scales\n            xScale.domain(xDomain || sortObjByVals(uniqueX))\n                  .rangeBands(xRange || [0, availableWidth-cellBorderWidth/2]);\n            yScale.domain(yDomain || sortObjByVals(uniqueY))\n                  .rangeBands(yRange || [0, availableHeight-cellBorderWidth/2]);\n            colorScale = cellsAreNumeric() ? d3.scale.quantize() : d3.scale.ordinal();\n            colorScale.domain(colorDomain || getColorDomain())\n                  .range(colorRange || RdYlBu);\n\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-heatMapWrap').data([prepedData]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-heatMapWrap');\n            wrapEnter\n                .append('g')\n                .attr('class','cellWrap')\n\n            wrap.watchTransition(renderWatch, 'nv-wrap: heatMapWrap')\n                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var gridWrap = wrapEnter\n                .append('g')\n                .attr('class','cellGrid')\n                .style('opacity',1e-6)\n\n            var gridLinesV = wrap.select('.cellGrid').selectAll('.gridLines.verticalGrid')\n                .data(Object.values(uniqueX).concat([Object.values(uniqueX).length]))\n                \n            gridLinesV.enter()\n                .append('line')\n                .attr('class','gridLines verticalGrid')\n\n            gridLinesV.exit()\n                .remove()\n\n            var gridLinesH = wrap.select('.cellGrid').selectAll('.gridLines.horizontalGrid')\n                .data(Object.values(uniqueY).concat([Object.values(uniqueY).length]))\n                \n            gridLinesH.enter()\n                .append('line')\n                .attr('class','gridLines horizontalGrid')\n\n            gridLinesH.exit()\n                .remove()\n\n            var cellWrap = wrap.select('.cellWrap')\n                .selectAll(\".nv-cell\")\n                .data(function(d) { return d; }, function(e) { return getIdx(e); })\n\n            var xMetaWrap = wrapEnter\n                .append('g')\n                .attr('class','xMetaWrap')\n                .attr(\"transform\", function() { return \"translate(0,\" + (-xMetaHeight()-cellBorderWidth-metaOffset) + \")\" })\n\n            var xMetas = wrap.select('.xMetaWrap').selectAll('.x-meta')\n                .data(uniqueXMeta)\n\n            var xMetaEnter = xMetas\n                .enter()\n                .append('rect')\n                .attr('class','x-meta meta')\n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", xMetaHeight())\n                .attr(\"transform\", \"translate(0,0)\")\n                .attr(\"fill\", function(d) { return xMetaColorScale(d); })\n\n            var yMetaWrap = wrapEnter\n                .append('g')\n                .attr('class','yMetaWrap')\n                .attr(\"transform\", function(d,i) { return \"translate(\" + (-yMetaWidth()-cellBorderWidth-metaOffset) + \",0)\" })\n\n            var yMetas = wrap.select('.yMetaWrap').selectAll('.y-meta')\n                .data(uniqueYMeta)\n\n            var yMetaEnter = yMetas\n                .enter()\n                .append('rect')\n                .attr('class','y-meta meta')\n                .attr(\"width\", yMetaWidth())\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr(\"transform\", function(d,i) { return \"translate(0,0)\" })\n                .attr(\"fill\", function(d,i) { return yMetaColorScale(d); })\n\n            xMetas.exit().remove()\n            yMetas.exit().remove()\n          \n            // CELLS    \n            var cellsEnter = cellWrap\n                .enter()\n                .append('g')\n                .style('opacity', 1e-6)\n                .attr(\"transform\", function(d) { return \"translate(0,\" + getIY(d) * cellHeight + \")\" }) // enter all g's here for a sweep-right transition\n                .attr('data-row', function(d) { return getIY(d) })\n                .attr('data-column', function(d) { return getIX(d) });\n\n            cellsEnter\n                .append(\"rect\") \n\n            cellsEnter\n                .append('text')\n                .attr('text-anchor', 'middle')\n                .attr(\"dy\", 4)\n                .attr(\"class\",\"cell-text\")\n\n            \n            // transition cell (rect) size\n            cellWrap.selectAll('rect')\n                .watchTransition(renderWatch, 'heatMap: rect')\n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr('rx', cellRadius)\n                .attr('ry', cellRadius)\n                .style('stroke', function(d) { return cellColor(d) })\n\n            // transition cell (g) position, opacity and fill\n            cellWrap\n                .attr(\"class\",function(d) { return isNaN(getCellValue(d)) ? 'nv-cell cell-missing' : 'nv-cell'}) \n                .watchTransition(renderWatch, 'heatMap: cells')\n                .style({\n                    'opacity': 1,\n                    'fill': function(d) { return cellColor(d) },\n                })\n                .attr(\"transform\", function(d) { return \"translate(\" + getIX(d) * cellWidth + \",\" + getIY(d) * cellHeight + \")\" })\n                .attr(\"class\",function(d) { return isNaN(getCellValue(d)) ? 'nv-cell cell-missing' : 'nv-cell'}) \n\n            cellWrap.exit().remove();\n\n            // transition text position and fill\n            cellWrap.selectAll('text')\n                .watchTransition(renderWatch, 'heatMap: cells text')\n                .text(function(d) { return cellValueLabel(d); })\n                .attr(\"x\", function(d) { return (cellWidth-cellBorderWidth) / 2; })\n                .attr(\"y\", function(d) { return (cellHeight-cellBorderWidth) / 2; })\n                .style(\"fill\", function(d) { return cellTextColor(cellColor(d)) })\n                .style('opacity', function() { return showCellValues ? 1 : 0 })\n\n            // transition grid\n            wrap.selectAll('.verticalGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines') \n                .attr('y1',0)\n                .attr('y2',availableHeight-cellBorderWidth)\n                .attr('x1',function(d) { return d*cellWidth-cellBorderWidth/2; })\n                .attr('x2',function(d) { return d*cellWidth-cellBorderWidth/2; })\n\n            var numHLines = Object.keys(uniqueY).length;\n            wrap.selectAll('.horizontalGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines') \n                .attr('x1',function(d) { return (d == 0 || d == numHLines) ? -cellBorderWidth : 0 })\n                .attr('x2',function(d) { return (d == 0 || d == numHLines) ? availableWidth : availableWidth-cellBorderWidth})\n                .attr('y1',function(d) { return d*cellHeight-cellBorderWidth/2; })\n                .attr('y2',function(d) { return d*cellHeight-cellBorderWidth/2; })\n\n            wrap.select('.cellGrid')\n                .watchTransition(renderWatch, 'heatMap: gridLines')\n                .style({\n                    'stroke-width': cellBorderWidth,\n                    'opacity': function() { return showGrid ? 1 : 1e-6 },\n                })\n\n            var xMetaRect = wrap.selectAll('.x-meta')\n            var yMetaRect = wrap.selectAll('.y-meta')\n            var allMetaRect = wrap.selectAll('.meta')\n\n            // transition meta rect size\n            xMetas\n                .watchTransition(renderWatch, 'heatMap: xMetaRect') \n                .attr(\"width\", cellWidth-cellBorderWidth)\n                .attr(\"height\", xMetaHeight())\n                .attr(\"transform\", function(d,i) { return \"translate(\" + (i * cellWidth) + \",0)\" })\n\n            yMetas\n                .watchTransition(renderWatch, 'heatMap: yMetaRect') \n                .attr(\"width\", yMetaWidth())\n                .attr(\"height\", cellHeight-cellBorderWidth)\n                .attr(\"transform\", function(d,i) { return \"translate(0,\" + (i * cellHeight) + \")\" })\n\n\n            // transition position of meta wrap g & opacity\n            wrap.select('.xMetaWrap')\n                .watchTransition(renderWatch, 'heatMap: xMetaWrap') \n                .attr(\"transform\", function(d,i) { return \"translate(0,\" + (-xMetaHeight()-cellBorderWidth-metaOffset) + \")\" })\n                .style(\"opacity\", function() { return xMeta !== false ? 1 : 0 })\n            wrap.select('.yMetaWrap')\n                .watchTransition(renderWatch, 'heatMap: yMetaWrap') \n                .attr(\"transform\", function(d,i) { return \"translate(\" + (-yMetaWidth()-cellBorderWidth-metaOffset) + \",0)\" })\n                .style(\"opacity\", function() { return yMeta !== false ? 1 : 0 })\n\n            // TOOLTIPS\n            cellWrap\n                .on('mouseover', function(d,i) {\n\n                    var idx = getIdx(d);\n                    var ix = getIX(d);\n                    var iy = getIY(d);\n\n                    // set the proper classes for all cells\n                    // hover row gets class .row-hover\n                    // hover column gets class .column-hover\n                    // hover cell gets class .cell-hover\n                    // all remaining cells get class .no-hover\n                    d3.selectAll('.nv-cell').each(function(e) {\n                        if (idx == getIdx(e)) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                        if (ix == getIX(e)) {\n                            d3.select(this).classed('no-hover', false);\n                            d3.select(this).classed('column-hover', true);\n                        }\n                        if (iy == getIY(e)) {\n                            d3.select(this).classed('no-hover', false);\n                            d3.select(this).classed('row-hover', true);\n                        }\n                    })\n    \n                    // set hover classes for column metadata\n                    d3.selectAll('.x-meta').each(function(e, j) {\n                        if (j == ix) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                    });\n\n                    // set hover class for row metadata\n                    d3.selectAll('.y-meta').each(function(e, j) {\n                        if (j == iy) {\n                            d3.select(this).classed('cell-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('cell-hover', false);\n                        }\n                    });\n                    \n                    dispatch.elementMouseover({\n                        value: getKeyByValue(uniqueX, ix) + ' & ' + getKeyByValue(uniqueY, iy), \n                        series: {\n                                value: cellValueLabel(d), \n                                color: d3.select(this).select('rect').style(\"fill\")\n                                },\n                        e: d3.event,\n                    });\n\n                })\n                .on('mouseout', function(d,i) {\n\n                    // allow tooltip to remain even when mouse is over the\n                    // space between the cell;\n                    // this prevents cells from \"flashing\" when transitioning\n                    // between cells\n                    var bBox = d3.select(this).select('rect').node().getBBox();\n                    var coordinates = d3.mouse(d3.select('.nv-heatMap').node());\n                    var x = coordinates[0];\n                    var y = coordinates[1];\n\n                    // we only trigger mouseout when mouse moves outside of\n                    // .nv-heatMap\n                    if (x + cellBorderWidth >= availableWidth || y + cellBorderWidth >= availableHeight || x < 0 || y < 0) {\n                        // remove all hover classes\n                        removeAllHoverClasses();\n\n                        dispatch.elementMouseout({e: d3.event});\n                    }\n                })\n                .on('mousemove', function(d,i) {\n\n                    dispatch.elementMousemove({e: d3.event});\n                })\n\n            allMetaRect\n                .on('mouseover', function(d,i) {\n\n                    // true if hovering over a row metadata rect\n                    var isColMeta = d3.select(this).attr('class').indexOf('x-meta') != -1 ? true : false;\n\n                    // apply proper .row-hover & .column-hover\n                    // classes to cells\n                    d3.selectAll('.nv-cell').each(function(e) {\n\n                        if (isColMeta && i == getIX(e)) {\n                            d3.select(this).classed('column-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else if (!isColMeta && i-uniqueXMeta.length == getIY(e)) {\n                            // since allMetaRect selects all the meta rects, the index for the y's will\n                            // be offset by the number of x rects. TODO - write seperate tooltip sections\n                            // for x meta rect & y meta rect\n                            d3.select(this).classed('row-hover', true);\n                            d3.select(this).classed('no-hover', false);\n                        } else {\n                            d3.select(this).classed('no-hover', true);\n                            d3.select(this).classed('column-hover', false);\n                            d3.select(this).classed('row-hover', false);\n                        }\n                        d3.select(this).classed('cell-hover', false);\n                    })\n\n                    // apply proper .row-hover & .column-hover\n                    // classes to meta rects\n                    d3.selectAll('.meta').classed('no-hover', true);\n                    d3.select(this).classed('cell-hover', true);\n                    d3.select(this).classed('no-hover', false);\n\n                    dispatch.elementMouseover({\n                        value: isColMeta ? 'Column meta' : 'Row meta',\n                        series: { value: d, color: d3.select(this).style('fill'), }\n                    });\n                })\n                .on('mouseout', function(d,i) {\n\n                    // true if hovering over a row metadata rect\n                    var isColMeta = d3.select(this).attr('class').indexOf('x-meta') != -1 ? true : false;\n\n                    // allow tooltip to remain even when mouse is over the\n                    // space between the cell;\n                    // this prevents cells from \"flashing\" when transitioning\n                    // between cells\n                    var bBox = d3.select(this).node().getBBox();\n                    var coordinates = d3.mouse(d3.select(isColMeta ? '.xMetaWrap' : '.yMetaWrap').node());\n                    var x = coordinates[0];\n                    var y = coordinates[1];\n\n                    if ( y < 0 || x < 0 || \n                        (isColMeta && x + cellBorderWidth >= availableWidth) ||\n                        (!isColMeta && y + cellBorderWidth >= availableHeight)\n                    ) {\n                        // remove all hover classes\n                        removeAllHoverClasses();\n\n                        dispatch.elementMouseout({e: d3.event});\n                    }\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({e: d3.event});\n                })\n\n        });\n\n\n        renderWatch.renderEnd('heatMap immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        showCellValues: {get: function(){return showCellValues;}, set: function(_){showCellValues=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}}, // data attribute for horizontal axis\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}}, // data attribute for vertical axis\n        cellValue:       {get: function(){return getCellValue;}, set: function(_){getCellValue=_;}}, // data attribute that sets cell value and color\n        missingDataColor:  {get: function(){return missingDataColor;}, set: function(_){missingDataColor=_;}},\n        missingDataLabel:  {get: function(){return missingDataLabel;}, set: function(_){missingDataLabel=_;}},\n        xScale:  {get: function(){return xScale;}, set: function(_){xScale=_;}},\n        yScale:  {get: function(){return yScale;}, set: function(_){yScale=_;}},\n        colorScale:  {get: function(){return colorScale;}, set: function(_){colorScale=_;}}, // scale to map cell values to colors\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        colorRange:  {get: function(){return colorRange;}, set: function(_){colorRange=_;}},\n        colorDomain:  {get: function(){return colorDomain;}, set: function(_){colorDomain=_;}},\n        xMeta:  {get: function(){return xMeta;}, set: function(_){xMeta=_;}},\n        yMeta:  {get: function(){return yMeta;}, set: function(_){yMeta=_;}},\n        xMetaColorScale:  {get: function(){return color;}, set: function(_){color = nv.utils.getColor(_);}},\n        yMetaColorScale:  {get: function(){return color;}, set: function(_){color = nv.utils.getColor(_);}},\n        cellAspectRatio:  {get: function(){return cellAspectRatio;}, set: function(_){cellAspectRatio=_;}}, // cell width / height\n        cellRadius:  {get: function(){return cellRadius;}, set: function(_){cellRadius=_;}}, // cell width / height\n        cellHeight:  {get: function(){return cellHeight;}}, // TODO - should not be exposed since we don't want user setting this\n        cellWidth:   {get: function(){return cellWidth;}}, // TODO - should not be exposed since we don't want user setting this\n        normalize:   {get: function(){return normalize;}, set: function(_){normalize=_;}},\n        cellBorderWidth:     {get: function(){return cellBorderWidth;}, set: function(_){cellBorderWidth=_;}},\n        highContrastText:    {get: function(){return highContrastText;}, set: function(_){highContrastText=_;}},\n        cellValueFormat:     {get: function(){return cellValueFormat;}, set: function(_){cellValueFormat=_;}},\n        id:                  {get: function(){return id;}, set: function(_){id=_;}},\n        metaOffset:          {get: function(){return metaOffset;}, set: function(_){metaOffset=_;}},\n        xMetaHeight:         {get: function(){return xMetaHeight;}, set: function(_){xMetaHeight=_;}},\n        yMetaWidth:          {get: function(){return yMetaWidth;}, set: function(_){yMetaWidth=_;}},\n        showGrid:          {get: function(){return showGrid;}, set: function(_){showGrid=_;}},\n\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/heatMapChart.js",
    "content": "/* Heatmap Chart Type\n\nA heatmap is a graphical representation of data where the individual values\ncontained in a matrix are represented as colors within cells. Furthermore,\nmetadata can be associated with each of the matrix rows or columns. By grouping\nthese rows/columns together by a given metadata value, data trends can be spotted.\n\nFormat for input data should be:\nvar data = [\n    {day: 'mo', hour: '1a', value: 16, timeperiod: 'early morning', weekperiod: 'week', category: 1},\n    {day: 'mo', hour: '2a', value: 20, timeperiod: 'early morning', weekperiod: 'week', category: 2},\n    {day: 'mo', hour: '3a', value: 0, timeperiod: 'early morning', weekperiod: 'week', category: 1},\n    ...\n]\nwhere the keys 'day' and 'hour' specify the row/column of the heatmap, 'value' specifies the  cell\nvalue and the keys 'timeperiod', 'weekperiod' and 'week' are extra metadata that can be associated\nwith rows/columns.\n\n\nOptions for chart:\n*/\nnv.models.heatMapChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var heatMap = nv.models.heatMap()\n        , legend = nv.models.legend()\n        , legendRowMeta = nv.models.legend()\n        , legendColumnMeta = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        ;\n\n\n    var margin = {top: 20, right: 10, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.getColor()\n        , showLegend = true\n        , staggerLabels = false\n        , showXAxis = true\n        , showYAxis = true\n        , alignYAxis = 'left'\n        , alignXAxis = 'top'\n        , rotateLabels = 0\n        , title = false\n        , x\n        , y\n        , noData = null\n        , dispatch = d3.dispatch('beforeUpdate','renderEnd')\n        , duration = 250\n        ;\n\n    xAxis\n        .orient(alignXAxis)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient(alignYAxis)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(true)\n        .keyFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    // https://bl.ocks.org/mbostock/4573883\n    // get max/min range for all the quantized cell values\n    // returns an array where each element is [start,stop]\n    // of color bin\n    function quantizeLegendValues() {\n\n        var e = heatMap.colorScale(), legendVals;\n\n        if (typeof e.domain()[0] === 'string') { // if color scale is ordinal\n\n            legendVals = e.domain();\n\n        } else { // if color scale is numeric\n\n            legendVals = e.range().map(function(color) {\n              var d = e.invertExtent(color);\n              if (d[0] === null) d[0] = e.domain()[0];\n              if (d[1] === null) d[1] = e.domain()[1];\n              return d;\n            })\n\n        }\n\n        return legendVals\n\n    }\n\n    // return true if row metadata specified by user\n    function hasRowMeta() {\n        return typeof heatMap.yMeta() === 'function'\n    }\n    // return true if col metadata specified by user\n    function hasColumnMeta() {\n        return typeof heatMap.xMeta() === 'function'\n    }\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(heatMap);\n        renderWatch.models(xAxis);\n        renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                dispatch.beforeUpdate();\n                container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = heatMap.xScale();\n            y = heatMap.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap').append('g');\n            var g = wrap.select('g');\n\n\n            gEnter.append('g').attr('class', 'nv-heatMap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n\n            heatMap\n                .width(availableWidth)\n                .height(availableHeight);\n\n\n            var heatMapWrap = g.select('.nv-heatMap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n\n            heatMapWrap.transition().call(heatMap);\n\n\n            if (heatMap.cellAspectRatio()) {\n                availableHeight = heatMap.cellHeight() * y.domain().length;\n                heatMap.height(availableHeight);\n            }\n\n\n            // Setup Axes\n            xAxis\n                .scale(x)\n                ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                .tickSize(-availableHeight, 0);\n\n            var axisX = g.select('.nv-x.nv-axis')\n\n            axisX.call(xAxis)\n                .watchTransition(renderWatch, 'heatMap: axisX')\n                .selectAll('.tick')\n                .style('opacity', function() { return showXAxis ? 1 : 0 } )\n\n            var xTicks = axisX.selectAll('g');\n\n            xTicks\n                .selectAll('.tick text')\n                .attr('transform', function(d,i,j) {\n                    var rot = rotateLabels != 0 ? rotateLabels : '0';\n                    var stagger = staggerLabels ? j % 2 == 0 ? '5' : '17' : '0';\n                    return 'translate(0, ' + stagger + ') rotate(' + rot + ' 0,0)';\n                })\n                .style('text-anchor', rotateLabels > 0 ? 'start' : rotateLabels < 0 ? 'end' : 'middle');\n\n            // position text in center of meta rects\n            var yPos = -5;\n            if (hasColumnMeta()) {\n                axisX.selectAll('text').style('text-anchor', 'middle')\n                yPos = -heatMap.xMetaHeight()()/2 - heatMap.metaOffset() + 3;\n            }\n\n            // adjust position of axis based on presence of metadata group\n            if (alignXAxis == 'bottom') {\n                axisX\n                    .watchTransition(renderWatch, 'heatMap: axisX')\n                    .attr(\"transform\", \"translate(0,\" + (availableHeight - yPos) + \")\");\n                if (heatMap.xMeta() !== false) { // if showing x metadata\n                    var pos = availableHeight+heatMap.metaOffset()+heatMap.cellBorderWidth()\n                    g.select('.xMetaWrap')\n                        .watchTransition(renderWatch, 'heatMap: xMetaWrap')\n                        .attr(\"transform\", function(d,i) { return \"translate(0,\" + pos + \")\" })\n                }\n            } else {\n                axisX\n                    .watchTransition(renderWatch, 'heatMap: axisX')\n                    .attr(\"transform\", \"translate(0,\" + yPos + \")\");\n            }\n\n\n            yAxis\n                .scale(y)\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n            var axisY = g.select('.nv-y.nv-axis')\n\n            axisY.call(yAxis)\n                .watchTransition(renderWatch, 'heatMap: axisY')\n                .selectAll('.tick')\n                .style('opacity', function() { return showYAxis ? 1 : 0 } )\n\n            // position text in center of meta rects\n            var xPos = -5;\n            if (hasRowMeta()) {\n                axisY.selectAll('text').style('text-anchor', 'middle')\n                xPos = -heatMap.yMetaWidth()()/2 - heatMap.metaOffset();\n            }\n\n            // adjust position of axis based on presence of metadata group\n            if (alignYAxis == 'right') {\n                axisY.attr(\"transform\", \"translate(\" + (availableWidth - xPos) + \",0)\");\n                if (heatMap.yMeta() !== false) { // if showing y meatdata\n                    var pos = availableWidth+heatMap.metaOffset()+heatMap.cellBorderWidth()\n                    g.select('.yMetaWrap')\n                        .watchTransition(renderWatch, 'heatMap: yMetaWrap')\n                        .attr(\"transform\", function(d,i) { return \"translate(\" + pos + \",0)\" })\n                }\n            } else {\n                axisY.attr(\"transform\", \"translate(\" + xPos + \",0)\");\n            }\n\n\n\n            // Legend\n            var legendWrap = g.select('.nv-legendWrap')\n\n            legend\n                .width(availableWidth)\n                .color(heatMap.colorScale().range())\n\n            var legendVal = quantizeLegendValues().map(function(d) {\n                if (Array.isArray(d)) { // if cell values are numeric\n                    return {key: d[0].toFixed(1) + \" - \" + d[1].toFixed(1)};\n                } else { // if cell values are ordinal\n                    return {key: d};\n                }\n            })\n            \n\n            legendWrap\n                .datum(legendVal)\n                .call(legend)\n                .attr('transform', 'translate(0,' + (alignXAxis == 'top' ? availableHeight : -30) + ')'); // TODO: more intelligent offset (-30) when top aligning legend\n\n            legendWrap\n                .watchTransition(renderWatch, 'heatMap: nv-legendWrap')\n                .style('opacity', function() { return showLegend ? 1 : 0 } )\n\n        });\n\n        // axis don't have a flag for disabling the zero line, so we do it manually\n        d3.selectAll('.nv-axis').selectAll('line')\n            .style('stroke-opacity', 0)\n        d3.select('.nv-y').select('path.domain').remove()\n\n        renderWatch.renderEnd('heatMap chart immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    heatMap.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip.data(evt).hidden(false);\n    });\n\n    heatMap.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    heatMap.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.heatMap = heatMap;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        noData:     {get: function(){return noData;}, set: function(_){noData=_;}},\n        showXAxis:     {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:     {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        staggerLabels: {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        rotateLabels:  {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            heatMap.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        alignYAxis: {get: function(){return alignYAxis;}, set: function(_){\n            alignYAxis = _;\n            yAxis.orient(_);\n        }},\n        alignXAxis: {get: function(){return alignXAxis;}, set: function(_){\n            alignXAxis = _;\n            xAxis.orient(_);\n        }},\n    });\n\n    nv.utils.inheritOptions(chart, heatMap);\n    nv.utils.initOptions(chart);\n\n    return chart;\n}\n"
  },
  {
    "path": "src/models/historicalBar.js",
    "content": "//TODO: consider deprecating and using multibar with single series for this\nnv.models.historicalBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceX = []\n        , forceY = [0]\n        , padData = false\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        , interactive = true\n        ;\n\n    var renderWatch = nv.utils.renderWatch(dispatch, 0);\n\n    function chart(selection) {\n        selection.each(function(data) {\n            renderWatch.reset();\n\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [0, availableWidth]);\n\n            y.domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) ))\n                .range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-historicalBar-' + id).data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBar-' + id);\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-bars');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var bars = wrap.select('.nv-bars').selectAll('.nv-bar')\n                .data(function(d) { return d }, function(d,i) {return getX(d,i)});\n            bars.exit().remove();\n\n            bars.enter().append('rect')\n                .attr('x', 0 )\n                .attr('y', function(d,i) {  return nv.utils.NaNtoZero(y(Math.max(0, getY(d,i)))) })\n                .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.abs(y(getY(d,i)) - y(0))) })\n                .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })\n                .on('mouseover', function(d,i) {\n                    if (!interactive) return;\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n\n                })\n                .on('mouseout', function(d,i) {\n                    if (!interactive) return;\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    if (!interactive) return;\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    if (!interactive) return;\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    if (!interactive) return;\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            bars\n                .attr('fill', function(d,i) { return color(d, i); })\n                .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })\n                .watchTransition(renderWatch, 'bars')\n                .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })\n                //TODO: better width calculations that don't assume always uniform data spacing;w\n                .attr('width', (availableWidth / data[0].values.length) * .9 );\n\n            bars.watchTransition(renderWatch, 'bars')\n                .attr('y', function(d,i) {\n                    var rval = getY(d,i) < 0 ?\n                        y(0) :\n                            y(0) - y(getY(d,i)) < 1 ?\n                        y(0) - 1 :\n                        y(getY(d,i));\n                    return nv.utils.NaNtoZero(rval);\n                })\n                .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) });\n\n        });\n\n        renderWatch.renderEnd('historicalBar immediate');\n        return chart;\n    }\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        container\n            .select(\".nv-bars .nv-bar-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container\n            .select(\".nv-bars .nv-bar.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        forceX:  {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData: {get: function(){return padData;}, set: function(_){padData=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/historicalBarChart.js",
    "content": "\nnv.models.historicalBarChart = function(bar_model) {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var bars = bar_model || nv.models.historicalBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        ;\n\n\n    var margin = {top: 30, right: 90, bottom: 50, left: 90}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = false\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , useInteractiveGuideline = false\n        , x\n        , y\n        , state = {}\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('tooltipHide', 'stateChange', 'changeState', 'renderEnd')\n        , transitionDuration = 250\n        ;\n\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient( (rightAlignYAxis) ? 'right' : 'left');\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, 0);\n\n    function chart(selection) {\n        selection.each(function(data) {\n            renderWatch.reset();\n            renderWatch.models(bars);\n            if (showXAxis) renderWatch.models(xAxis);\n            if (showYAxis) renderWatch.models(yAxis);\n\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().duration(transitionDuration).call(chart) };\n            chart.container = this;\n\n            //set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = bars.xScale();\n            y = bars.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-historicalBarChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBarChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n            }\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n            bars\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n            barsWrap.transition().call(bars);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .transition()\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .transition()\n                    .call(yAxis);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                bars.clearHighlights();\n\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        bars.highlightPoint(pointIndex,true);\n                        var point = series.values[pointIndex];\n                        if (point === undefined) return;\n                        if (singlePoint === undefined) singlePoint = point;\n                        if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: chart.y()(point, pointIndex),\n                            color: color(series,series.seriesIndex),\n                            data: series.values[pointIndex]\n                        });\n                    });\n\n                var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex));\n                interactiveLayer.tooltip\n                    .valueFormatter(function(d,i) {\n                        return yAxis.tickFormat()(d);\n                    })\n                    .data({\n                        value: xValue,\n                        index: pointIndex,\n                        series: allData\n                    })();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                dispatch.tooltipHide();\n                bars.clearHighlights();\n            });\n\n            legend.dispatch.on('legendClick', function(d,i) {\n                d.disabled = !d.disabled;\n\n                if (!data.filter(function(d) { return !d.disabled }).length) {\n                    data.map(function(d) {\n                        d.disabled = false;\n                        wrap.selectAll('.nv-series').classed('disabled', false);\n                        return d;\n                    });\n                }\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n\n                selection.transition().call(chart);\n            });\n\n            legend.dispatch.on('legendDblclick', function(d) {\n                //Double clicking should always enable current series, and disabled all others.\n                data.forEach(function(d) {\n                    d.disabled = true;\n                });\n                d.disabled = false;\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                chart.update();\n            });\n        });\n\n        renderWatch.renderEnd('historicalBarChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    bars.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    bars.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bars.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.bars = bars;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            bars.color(color);\n        }},\n        duration:    {get: function(){return transitionDuration;}, set: function(_){\n            transitionDuration=_;\n            renderWatch.reset(transitionDuration);\n            yAxis.duration(transitionDuration);\n            xAxis.duration(transitionDuration);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (_ === true) {\n                chart.interactive(false);\n            }\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, bars);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\n\n// ohlcChart is just a historical chart with ohlc bars and some tweaks\nnv.models.ohlcBarChart = function() {\n    var chart = nv.models.historicalBarChart(nv.models.ohlcBar());\n\n    // special default tooltip since we show multiple values per x\n    chart.useInteractiveGuideline(true);\n    chart.interactiveLayer.tooltip.contentGenerator(function(data) {\n        // we assume only one series exists for this chart\n        var d = data.series[0].data;\n        // match line colors as defined in nv.d3.css\n        var color = d.open < d.close ? \"2ca02c\" : \"d62728\";\n        return '' +\n            '<h3 style=\"color: #' + color + '\">' + data.value + '</h3>' +\n            '<table>' +\n            '<tr><td>open:</td><td>' + chart.yAxis.tickFormat()(d.open) + '</td></tr>' +\n            '<tr><td>close:</td><td>' + chart.yAxis.tickFormat()(d.close) + '</td></tr>' +\n            '<tr><td>high</td><td>' + chart.yAxis.tickFormat()(d.high) + '</td></tr>' +\n            '<tr><td>low:</td><td>' + chart.yAxis.tickFormat()(d.low) + '</td></tr>' +\n            '</table>';\n    });\n    return chart;\n};\n\n// candlestickChart is just a historical chart with candlestick bars and some tweaks\nnv.models.candlestickBarChart = function() {\n    var chart = nv.models.historicalBarChart(nv.models.candlestickBar());\n\n    // special default tooltip since we show multiple values per x\n    chart.useInteractiveGuideline(true);\n    chart.interactiveLayer.tooltip.contentGenerator(function(data) {\n        // we assume only one series exists for this chart\n        var d = data.series[0].data;\n        // match line colors as defined in nv.d3.css\n        var color = d.open < d.close ? \"2ca02c\" : \"d62728\";\n        return '' +\n            '<h3 style=\"color: #' + color + '\">' + data.value + '</h3>' +\n            '<table>' +\n            '<tr><td>open:</td><td>' + chart.yAxis.tickFormat()(d.open) + '</td></tr>' +\n            '<tr><td>close:</td><td>' + chart.yAxis.tickFormat()(d.close) + '</td></tr>' +\n            '<tr><td>high</td><td>' + chart.yAxis.tickFormat()(d.high) + '</td></tr>' +\n            '<tr><td>low:</td><td>' + chart.yAxis.tickFormat()(d.low) + '</td></tr>' +\n            '</table>';\n    });\n    return chart;\n};\n"
  },
  {
    "path": "src/models/legend.js",
    "content": "nv.models.legend = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , width = 400\n        , height = 20\n        , getKey = function(d) { return d.key }\n        , keyFormatter = function (d) { return d }\n        , color = nv.utils.getColor()\n        , maxKeyLength = 20 //default value for key lengths\n        , align = true\n        , padding = 32 //define how much space between legend items. - recommend 32 for furious version\n        , rightAlign = true\n        , updateState = true   //If true, legend will update data.disabled and trigger a 'stateChange' dispatch.\n        , enableDoubleClick = true   //If true, legend will enable double click handling\n        , radioButtonMode = false   //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time)\n        , expanded = false\n        , dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange')\n        , vers = 'classic' //Options are \"classic\" and \"furious\"\n        ;\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-legend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-legend').append('g');\n            var g = wrap.select('g');\n\n            if (rightAlign)\n                wrap.attr('transform', 'translate(' + (- margin.right) + ',' + margin.top + ')');\n            else\n                wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var series = g.selectAll('.nv-series')\n                .data(function(d) {\n                    if(vers != 'furious') return d;\n\n                    return d.filter(function(n) {\n                        return expanded ? true : !n.disengaged;\n                    });\n                });\n\n            var seriesEnter = series.enter().append('g').attr('class', 'nv-series');\n            var seriesShape;\n\n            var versPadding;\n            switch(vers) {\n                case 'furious' :\n                    versPadding = 23;\n                    break;\n                case 'classic' :\n                    versPadding = 20;\n            }\n\n            if(vers == 'classic') {\n                seriesEnter.append('circle')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('r', 5);\n\n                seriesShape = series.select('.nv-legend-symbol');\n            } else if (vers == 'furious') {\n                seriesEnter.append('rect')\n                    .style('stroke-width', 2)\n                    .attr('class','nv-legend-symbol')\n                    .attr('rx', 3)\n                    .attr('ry', 3);\n                seriesShape = series.select('.nv-legend-symbol');\n\n                seriesEnter.append('g')\n                    .attr('class', 'nv-check-box')\n                    .property('innerHTML','<path d=\"M0.5,5 L22.5,5 L22.5,26.5 L0.5,26.5 L0.5,5 Z\" class=\"nv-box\"></path><path d=\"M5.5,12.8618467 L11.9185089,19.2803556 L31,0.198864511\" class=\"nv-check\"></path>')\n                    .attr('transform', 'translate(-10,-8)scale(0.5)');\n\n                var seriesCheckbox = series.select('.nv-check-box');\n\n                seriesCheckbox.each(function(d,i) {\n                    d3.select(this).selectAll('path')\n                        .attr('stroke', setTextColor(d,i));\n                });\n            }\n\n            seriesEnter.append('text')\n                .attr('text-anchor', 'start')\n                .attr('class','nv-legend-text')\n                .attr('dy', '.32em')\n                .attr('dx', '8');\n\n            var seriesText = series.select('text.nv-legend-text');\n\n            series\n                .on('mouseover', function(d,i) {\n                    dispatch.legendMouseover(d,i);  //TODO: Make consistent with other event objects\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.legendMouseout(d,i);\n                })\n                .on('click', function(d,i) {\n                    dispatch.legendClick(d,i);\n                    // make sure we re-get data in case it was modified\n                    var data = series.data();\n                    if (updateState) {\n                        if(vers =='classic') {\n                            if (radioButtonMode) {\n                                //Radio button mode: set every series to disabled,\n                                //  and enable the clicked series.\n                                data.forEach(function(series) { series.disabled = true});\n                                d.disabled = false;\n                            }\n                            else {\n                                d.disabled = !d.disabled;\n                                if (data.every(function(series) { return series.disabled})) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) { series.disabled = false});\n                                }\n                            }\n                        } else if(vers == 'furious') {\n                            if(expanded) {\n                                d.disengaged = !d.disengaged;\n                                d.userDisabled = d.userDisabled == undefined ? !!d.disabled : d.userDisabled;\n                                d.disabled = d.disengaged || d.userDisabled;\n                            } else if (!expanded) {\n                                d.disabled = !d.disabled;\n                                d.userDisabled = d.disabled;\n                                var engaged = data.filter(function(d) { return !d.disengaged; });\n                                if (engaged.every(function(series) { return series.userDisabled })) {\n                                    //the default behavior of NVD3 legends is, if every single series\n                                    // is disabled, turn all series' back on.\n                                    data.forEach(function(series) {\n                                        series.disabled = series.userDisabled = false;\n                                    });\n                                }\n                            }\n                        }\n                        dispatch.stateChange({\n                            disabled: data.map(function(d) { return !!d.disabled }),\n                            disengaged: data.map(function(d) { return !!d.disengaged })\n                        });\n\n                    }\n                })\n                .on('dblclick', function(d,i) {\n                    if (enableDoubleClick) {\n                        if (vers == 'furious' && expanded) return;\n                        dispatch.legendDblclick(d, i);\n                        if (updateState) {\n                            // make sure we re-get data in case it was modified\n                            var data = series.data();\n                            //the default behavior of NVD3 legends, when double clicking one,\n                            // is to set all other series' to false, and make the double clicked series enabled.\n                            data.forEach(function (series) {\n                                series.disabled = true;\n                                if (vers == 'furious') series.userDisabled = series.disabled;\n                            });\n                            d.disabled = false;\n                            if (vers == 'furious') d.userDisabled = d.disabled;\n                            dispatch.stateChange({\n                                disabled: data.map(function (d) {\n                                    return !!d.disabled\n                                })\n                            });\n                        }\n                    }\n                });\n\n            series.classed('nv-disabled', function(d) { return d.userDisabled });\n            series.exit().remove();\n\n            seriesText\n                .attr('fill', setTextColor)\n                .text(function (d) { return keyFormatter(getKey(d)) });\n\n            //TODO: implement fixed-width and max-width options (max-width is especially useful with the align option)\n            // NEW ALIGNING CODE, TODO: clean up\n            var legendWidth = 0;\n            if (align) {\n\n                var seriesWidths = [];\n                series.each(function(d,i) {\n                    var legendText;\n                    if (keyFormatter(getKey(d)) && keyFormatter(getKey(d)).length > maxKeyLength) {\n                        var trimmedKey = keyFormatter(getKey(d)).substring(0, maxKeyLength);\n                        legendText = d3.select(this).select('text').text(trimmedKey + \"...\");\n                        d3.select(this).append(\"svg:title\").text(keyFormatter(getKey(d)));\n                    } else {\n                        legendText = d3.select(this).select('text');\n                    }\n                    var nodeTextLength;\n                    try {\n                        nodeTextLength = legendText.node().getComputedTextLength();\n                        // If the legendText is display:none'd (nodeTextLength == 0), simulate an error so we approximate, instead\n                        if(nodeTextLength <= 0) throw Error();\n                    }\n                    catch(e) {\n                        nodeTextLength = nv.utils.calcApproxTextWidth(legendText);\n                    }\n\n                    seriesWidths.push(nodeTextLength + padding);\n                });\n\n                var seriesPerRow = 0;\n                var columnWidths = [];\n                legendWidth = 0;\n\n                while ( legendWidth < availableWidth && seriesPerRow < seriesWidths.length) {\n                    columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];\n                    legendWidth += seriesWidths[seriesPerRow++];\n                }\n                if (seriesPerRow === 0) seriesPerRow = 1; //minimum of one series per row\n\n                while ( legendWidth > availableWidth && seriesPerRow > 1 ) {\n                    columnWidths = [];\n                    seriesPerRow--;\n\n                    for (var k = 0; k < seriesWidths.length; k++) {\n                        if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )\n                            columnWidths[k % seriesPerRow] = seriesWidths[k];\n                    }\n\n                    legendWidth = columnWidths.reduce(function(prev, cur, index, array) {\n                        return prev + cur;\n                    });\n                }\n\n                var xPositions = [];\n                for (var i = 0, curX = 0; i < seriesPerRow; i++) {\n                    xPositions[i] = curX;\n                    curX += columnWidths[i];\n                }\n\n                series\n                    .attr('transform', function(d, i) {\n                        return 'translate(' + xPositions[i % seriesPerRow] + ',' + (5 + Math.floor(i / seriesPerRow) * versPadding) + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                if (rightAlign) {\n                    g.attr('transform', 'translate(' + (width - margin.right - legendWidth) + ',' + margin.top + ')');\n                }\n                else {\n                    g.attr('transform', 'translate(0' + ',' + margin.top + ')');\n                }\n\n                height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length / seriesPerRow) * versPadding);\n\n            } else {\n\n                var ypos = 5,\n                    newxpos = 5,\n                    maxwidth = 0,\n                    xpos;\n                series\n                    .attr('transform', function(d, i) {\n                        var length = d3.select(this).select('text').node().getComputedTextLength() + padding;\n                        xpos = newxpos;\n\n                        if (width < margin.left + margin.right + xpos + length) {\n                            newxpos = xpos = 5;\n                            ypos += versPadding;\n                        }\n\n                        newxpos += length;\n                        if (newxpos > maxwidth) maxwidth = newxpos;\n\n                        if(legendWidth < xpos + maxwidth) {\n                            legendWidth = xpos + maxwidth;\n                        }\n                        return 'translate(' + xpos + ',' + ypos + ')';\n                    });\n\n                //position legend as far right as possible within the total width\n                g.attr('transform', 'translate(' + (width - margin.right - maxwidth) + ',' + margin.top + ')');\n\n                height = margin.top + margin.bottom + ypos + 15;\n            }\n\n            if(vers == 'furious') {\n                // Size rectangles after text is placed\n                seriesShape\n                    .attr('width', function(d,i) {\n                        return seriesText[0][i].getComputedTextLength() + 27;\n                    })\n                    .attr('height', 18)\n                    .attr('y', -9)\n                    .attr('x', -15);\n\n                // The background for the expanded legend (UI)\n                gEnter.insert('rect',':first-child')\n                    .attr('class', 'nv-legend-bg')\n                    .attr('fill', '#eee')\n                    // .attr('stroke', '#444')\n                    .attr('opacity',0);\n\n                var seriesBG = g.select('.nv-legend-bg');\n\n                seriesBG\n                .transition().duration(300)\n                    .attr('x', -versPadding )\n                    .attr('width', legendWidth + versPadding - 12)\n                    .attr('height', height + 10)\n                    .attr('y', -margin.top - 10)\n                    .attr('opacity', expanded ? 1 : 0);\n\n\n            }\n\n            seriesShape\n                .style('fill', setBGColor)\n                .style('fill-opacity', setBGOpacity)\n                .style('stroke', setBGColor);\n        });\n\n        function setTextColor(d,i) {\n            if(vers != 'furious') return '#000';\n            if(expanded) {\n                return d.disengaged ? '#000' : '#fff';\n            } else if (!expanded) {\n                if(!d.color) d.color = color(d,i);\n                return !!d.disabled ? d.color : '#fff';\n            }\n        }\n\n        function setBGColor(d,i) {\n            if(expanded && vers == 'furious') {\n                return d.disengaged ? '#eee' : d.color || color(d,i);\n            } else {\n                return d.color || color(d,i);\n            }\n        }\n\n\n        function setBGOpacity(d,i) {\n            if(expanded && vers == 'furious') {\n                return 1;\n            } else {\n                return !!d.disabled ? 0 : 1;\n            }\n        }\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:          {get: function(){return width;}, set: function(_){width=_;}},\n        height:         {get: function(){return height;}, set: function(_){height=_;}},\n        key:            {get: function(){return getKey;}, set: function(_){getKey=_;}},\n        keyFormatter:   {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        align:          {get: function(){return align;}, set: function(_){align=_;}},\n        maxKeyLength:   {get: function(){return maxKeyLength;}, set: function(_){maxKeyLength=_;}},\n        rightAlign:     {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}},\n        padding:        {get: function(){return padding;}, set: function(_){padding=_;}},\n        updateState:    {get: function(){return updateState;}, set: function(_){updateState=_;}},\n        enableDoubleClick: {get: function(){return enableDoubleClick;}, set: function(_){enableDoubleClick=_;}},\n        radioButtonMode:{get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}},\n        expanded:       {get: function(){return expanded;}, set: function(_){expanded=_;}},\n        vers:           {get: function(){return vers;}, set: function(_){vers=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/line.js",
    "content": "\nnv.models.line = function() {\n    \"use strict\";\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var  scatter = nv.models.scatter()\n        ;\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , container = null\n        , strokeWidth = 1.5\n        , color = nv.utils.defaultColor() // a function that returns a color\n        , getX = function(d) { return d.x } // accessor to get the x value from a data point\n        , getY = function(d) { return d.y } // accessor to get the y value from a data point\n        , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined\n        , isArea = function(d) { return d.area } // decides if a line is an area or just a line\n        , clipEdge = false // if true, masks lines within x and y scale\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , interpolate = \"linear\" // controls the line interpolation\n        , duration = 250\n        , dispatch = d3.dispatch('elementClick', 'elementMouseover', 'elementMouseout', 'renderEnd')\n        ;\n\n    scatter\n        .pointSize(16) // default size\n        .pointDomain([16,256]) //set to speed up calculation, needs to be unset if there is a custom size accessor\n    ;\n\n    //============================================================\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0 //used to store previous scales\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        ;\n\n    //============================================================\n\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-line').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-line');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            scatter\n                .width(availableWidth)\n                .height(availableHeight);\n\n            var scatterWrap = wrap.select('.nv-scatterWrap');\n            scatterWrap.call(scatter);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + scatter.id())\n                .append('rect');\n\n            wrap.select('#nv-edge-clip-' + scatter.id() + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', (availableHeight > 0) ? availableHeight : 0);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : '');\n            scatterWrap\n                .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + scatter.id() + ')' : '');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('stroke-width', function(d) { return d.strokeWidth || strokeWidth })\n                .style('fill-opacity', 1e-6);\n\n            groups.exit().remove();\n\n            groups\n                .attr('class', function(d,i) {\n                    return (d.classed || '') + ' nv-group nv-series-' + i;\n                })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i)});\n            groups.watchTransition(renderWatch, 'line: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', function(d) { return d.fillOpacity || .5});\n\n            var areaPaths = groups.selectAll('path.nv-area')\n                .data(function(d) { return isArea(d) ? [d] : [] }); // this is done differently than lines because I need to check if series is an area\n            areaPaths.enter().append('path')\n                .attr('class', 'nv-area')\n                .attr('d', function(d) {\n                    return d3.svg.area()\n                        .interpolate(interpolate)\n                        .defined(defined)\n                        .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) })\n                        .y0(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })\n                        .y1(function(d,i) { return y0( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })\n                        //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this\n                        .apply(this, [d.values])\n                });\n            groups.exit().selectAll('path.nv-area')\n                .remove();\n\n            areaPaths.watchTransition(renderWatch, 'line: areaPaths')\n                .attr('d', function(d) {\n                    return d3.svg.area()\n                        .interpolate(interpolate)\n                        .defined(defined)\n                        .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })\n                        .y0(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })\n                        .y1(function(d,i) { return y( y.domain()[0] <= 0 ? y.domain()[1] >= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })\n                        //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain.. may need to tweak this\n                        .apply(this, [d.values])\n                });\n\n            var linePaths = groups.selectAll('path.nv-line')\n                .data(function(d) { return [d.values] });\n\n            linePaths.enter().append('path')\n                .attr('class', 'nv-line')\n                .attr('d',\n                    d3.svg.line()\n                    .interpolate(interpolate)\n                    .defined(defined)\n                    .x(function(d,i) { return nv.utils.NaNtoZero(x0(getX(d,i))) })\n                    .y(function(d,i) { return nv.utils.NaNtoZero(y0(getY(d,i))) })\n            );\n\n            linePaths.watchTransition(renderWatch, 'line: linePaths')\n                .attr('d',\n                    d3.svg.line()\n                    .interpolate(interpolate)\n                    .defined(defined)\n                    .x(function(d,i) { return nv.utils.NaNtoZero(x(getX(d,i))) })\n                    .y(function(d,i) { return nv.utils.NaNtoZero(y(getY(d,i))) })\n            );\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n        });\n        renderWatch.renderEnd('line immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    // Pass through events\n    scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); });\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        defined: {get: function(){return defined;}, set: function(_){defined=_;}},\n        interpolate:      {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            scatter.duration(duration);\n        }},\n        isArea: {get: function(){return isArea;}, set: function(_){\n            isArea = d3.functor(_);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            scatter.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            scatter.y(_);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            scatter.color(color);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/lineChart.js",
    "content": "nv.models.lineChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        , focus = nv.models.focus(nv.models.line())\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , color = nv.utils.defaultColor()\n        , width = null\n        , height = null\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , useInteractiveGuideline = false\n        , x\n        , y\n        , focusEnable = false\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , duration = 250\n        ;\n\n    // set options on sub-objects for this chart\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient(rightAlignYAxis ? 'right' : 'left');\n\n    lines.clipEdge(true).duration(0);\n\n    tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    interactiveLayer.tooltip.valueFormatter(function(d, i) {\n        return yAxis.tickFormat()(d, i);\n    }).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled; })\n            };\n        };\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        };\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(lines);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n            chart.update = function() {\n                if( duration === 0 ) {\n                    container.call( chart );\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled; });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length; }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            /* Update `main' graph on brush update. */\n            focus.dispatch.on(\"onBrush\", function(extent) {\n                onBrush(extent);\n            });\n\n            // Setup Scales\n            x = lines.xScale();\n            y = lines.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-lineChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-lineChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-background').append('rect');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y nv-axis');\n            focusEnter.append('g').attr('class', 'nv-linesWrap');\n            focusEnter.append('g').attr('class', 'nv-interactive');\n\n            var contextEnter = gEnter.append('g').attr('class', 'nv-focusWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (legendPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(0,' + (availableHeight + xAxis.height())  +')');\n                } else if (legendPosition === 'top') {\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                    }\n\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + (-margin.top) +')');\n                }\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            g.select('.nv-focus .nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            lines\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var linesWrap = g.select('.nv-linesWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n\n            // Setup Main (Focus) Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks(nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n            }\n\n            //============================================================\n            // Update Axes\n            //============================================================\n            function updateXAxis() {\n              if(showXAxis) {\n                g.select('.nv-focus .nv-x.nv-axis')\n                  .transition()\n                  .duration(duration)\n                  .call(xAxis)\n                ;\n              }\n            }\n\n            function updateYAxis() {\n              if(showYAxis) {\n                g.select('.nv-focus .nv-y.nv-axis')\n                  .transition()\n                  .duration(duration)\n                  .call(yAxis)\n                ;\n              }\n            }\n\n            g.select('.nv-focus .nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + availableHeight + ')');\n\n            //============================================================\n            // Update Focus\n            //============================================================\n            if (!focusEnable && focus.brush.extent() === null) {\n                linesWrap.transition().call(lines);\n                updateXAxis();\n                updateYAxis();\n            } else {\n                focus.width(availableWidth);\n                g.select('.nv-focusWrap')\n                    .style('display', focusEnable ? 'initial' : 'none')\n                    .attr('transform', 'translate(0,' + ( availableHeight + margin.bottom + focus.margin().top) + ')')\n                    .call(focus);\n                var extent = focus.brush.empty() ? focus.xDomain() : focus.brush.extent();\n                if (extent !== null) {\n                    onBrush(extent);\n                }\n            }\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                lines.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [];\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled && !series.disableTooltip;\n                    })\n                    .forEach(function(series,i) {\n                        var extent = focus.brush.extent() !== null ? (focus.brush.empty() ? focus.xScale().domain() : focus.brush.extent()) : x.domain();\n                        var currentValues = series.values.filter(function(d,i) {\n                            // Checks if the x point is between the extents, handling case where extent[0] is greater than extent[1]\n                            // (e.g. x domain is manually set to reverse the x-axis)\n                            if(extent[0] <= extent[1]) {\n                                return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                            } else {\n                                return lines.x()(d,i) >= extent[1] && lines.x()(d,i) <= extent[0];\n                            }\n                        });\n\n                        if (currentValues.length > 0) {\n                            pointIndex = nv.interactiveBisect(currentValues, e.pointXValue, lines.x());\n                            var point = currentValues[pointIndex];\n                            var pointYValue = chart.y()(point, pointIndex);\n                            if (pointYValue !== null) {\n                                lines.highlightPoint(i, series.values.indexOf(point), true);\n                            }\n                            if (point === undefined) return;\n                            if (singlePoint === undefined) singlePoint = point;\n                            if (pointXLocation === undefined) pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                            allData.push({\n                                key: series.key,\n                                value: pointYValue,\n                                color: color(series,series.seriesIndex),\n                                data: point\n                            });\n                        }\n                    });\n                //Highlight the tooltip entry based on which point the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);\n                    var threshold = 0.03 * domainExtent;\n                    var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value;}),yValue,threshold);\n                    if (indexToHighlight !== null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                var defaultValueFormatter = function(d,i) {\n                    return d == null ? \"N/A\" : yAxis.tickFormat()(d);\n                };\n\n                if (typeof pointIndex !== 'undefined') {\n                    interactiveLayer.tooltip\n                        .valueFormatter(interactiveLayer.tooltip.valueFormatter() || defaultValueFormatter)\n                        .data({\n                            value: chart.x()( singlePoint,pointIndex ),\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                }\n            });\n\n            interactiveLayer.dispatch.on('elementClick', function(e) {\n                var pointXLocation, allData = [];\n\n                data.filter(function(series, i) {\n                    series.seriesIndex = i;\n                    return !series.disabled;\n                }).forEach(function(series) {\n                    var pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                    var point = series.values[pointIndex];\n                    if (typeof point === 'undefined') return;\n                    if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n                    var yPos = chart.yScale()(chart.y()(point,pointIndex));\n                    allData.push({\n                        point: point,\n                        pointIndex: pointIndex,\n                        pos: [pointXLocation, yPos],\n                        seriesIndex: series.seriesIndex,\n                        series: series\n                    });\n                });\n\n                lines.dispatch.elementClick(allData);\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                lines.clearHighlights();\n            });\n\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight / 3;\n                return 'M' + (0.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (0.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n\n            function onBrush(extent) {\n                // Update Main (Focus)\n                var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')\n                    .datum(\n                    data.filter(function(d) { return !d.disabled; })\n                        .map(function(d,i) {\n                            return {\n                                key: d.key,\n                                area: d.area,\n                                classed: d.classed,\n                                values: d.values.filter(function(d,i) {\n                                    return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                                }),\n                                disableTooltip: d.disableTooltip\n                            };\n                        })\n                );\n                focusLinesWrap.transition().duration(duration).call(lines);\n\n                // Update Main (Focus) Axes\n                updateXAxis();\n                updateYAxis();\n            }\n        });\n\n        renderWatch.renderEnd('lineChart immediate');\n        return chart;\n    }\n\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        if(!evt.series.disableTooltip){\n            tooltip.data(evt).hidden(false);\n        }\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.lines = lines;\n    chart.legend = legend;\n    chart.focus = focus;\n    chart.xAxis = xAxis;\n    chart.x2Axis = focus.xAxis\n    chart.yAxis = yAxis;\n    chart.y2Axis = focus.yAxis\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n    chart.state = state;\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        // Focus options, mostly passed onto focus model.\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:     {get: function(){return focus.height();}, set: function(_){focus.height(_);}},\n        focusShowAxisX:    {get: function(){return focus.showXAxis();}, set: function(_){focus.showXAxis(_);}},\n        focusShowAxisY:    {get: function(){return focus.showYAxis();}, set: function(_){focus.showYAxis(_);}},\n        brushExtent: {get: function(){return focus.brushExtent();}, set: function(_){focus.brushExtent(_);}},\n\n        // options that require extra logic in the setter\n        focusMargin: {get: function(){return focus.margin}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            focus.margin.right  = _.right  !== undefined ? _.right  : focus.margin.right;\n            focus.margin.bottom = _.bottom !== undefined ? _.bottom : focus.margin.bottom;\n            focus.margin.left   = _.left   !== undefined ? _.left   : focus.margin.left;\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            lines.duration(duration);\n            focus.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            lines.color(color);\n            focus.color(color);\n        }},\n        interpolate: {get: function(){return lines.interpolate();}, set: function(_){\n            lines.interpolate(_);\n            focus.interpolate(_);\n        }},\n        xTickFormat: {get: function(){return xAxis.tickFormat();}, set: function(_){\n            xAxis.tickFormat(_);\n            focus.xTickFormat(_);\n        }},\n        yTickFormat: {get: function(){return yAxis.tickFormat();}, set: function(_){\n            yAxis.tickFormat(_);\n            focus.yTickFormat(_);\n        }},\n        x: {get: function(){return lines.x();}, set: function(_){\n            lines.x(_);\n            focus.x(_);\n        }},\n        y: {get: function(){return lines.y();}, set: function(_){\n            lines.y(_);\n            focus.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (useInteractiveGuideline) {\n                lines.interactive(false);\n                lines.useVoronoi(false);\n            }\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.lineWithFocusChart = function() {\n  return nv.models.lineChart()\n    .margin({ bottom: 30 })\n    .focusEnable( true );\n};\n"
  },
  {
    "path": "src/models/linePlusBarChart.js",
    "content": "nv.models.linePlusBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var lines = nv.models.line()\n        , lines2 = nv.models.line()\n        , bars = nv.models.historicalBar()\n        , bars2 = nv.models.historicalBar()\n        , xAxis = nv.models.axis()\n        , x2Axis = nv.models.axis()\n        , y1Axis = nv.models.axis()\n        , y2Axis = nv.models.axis()\n        , y3Axis = nv.models.axis()\n        , y4Axis = nv.models.axis()\n        , legend = nv.models.legend()\n        , brush = d3.svg.brush()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 30, bottom: 30, left: 60}\n        , marginTop = null\n        , margin2 = {top: 0, right: 30, bottom: 20, left: 60}\n        , width = null\n        , height = null\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , color = nv.utils.defaultColor()\n        , showLegend = true\n        , focusEnable = true\n        , focusShowAxisY = false\n        , focusShowAxisX = true\n        , focusHeight = 50\n        , extent\n        , brushExtent = null\n        , x\n        , x2\n        , y1\n        , y2\n        , y3\n        , y4\n        , noData = null\n        , dispatch = d3.dispatch('brush', 'stateChange', 'changeState')\n        , transitionDuration = 0\n        , state = nv.utils.state()\n        , defaultState = null\n        , legendLeftAxisHint = ' (left axis)'\n        , legendRightAxisHint = ' (right axis)'\n        , switchYAxisOrder = false\n        ;\n\n    lines.clipEdge(true);\n    lines2.interactive(false);\n    // We don't want any points emitted for the focus chart's scatter graph.\n    lines2.pointActive(function(d) { return false });\n    xAxis.orient('bottom').tickPadding(5);\n    y1Axis.orient('left');\n    y2Axis.orient('right');\n    x2Axis.orient('bottom').tickPadding(5);\n    y3Axis.orient('left');\n    y4Axis.orient('right');\n\n    tooltip.headerEnabled(true).headerFormatter(function(d, i) {\n        return xAxis.tickFormat()(d, i);\n    });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var getBarsAxis = function() {\n        return switchYAxisOrder\n            ? { main: y2Axis, focus: y4Axis }\n            : { main: y1Axis, focus: y3Axis }\n    }\n\n    var getLinesAxis = function() {\n        return switchYAxisOrder\n            ? { main: y1Axis, focus: y3Axis }\n            : { main: y2Axis, focus: y4Axis }\n    }\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var allDisabled = function(data) {\n      return data.every(function(series) {\n        return series.disabled;\n      });\n    }\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight1 = nv.utils.availableHeight(height, container, margin)\n                    - (focusEnable ? focusHeight : 0),\n                availableHeight2 = focusHeight - margin2.top - margin2.bottom;\n\n            chart.update = function() { container.transition().duration(transitionDuration).call(chart); };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            var dataBars = data.filter(function(d) { return !d.disabled && d.bar });\n            var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240\n\n            if (dataBars.length && !switchYAxisOrder) {\n                x = bars.xScale();\n            } else {\n                x = lines.xScale();\n            }\n\n            x2 = x2Axis.scale();\n\n            // select the scales and series based on the position of the yAxis\n            y1 = switchYAxisOrder ? lines.yScale() : bars.yScale();\n            y2 = switchYAxisOrder ? bars.yScale() : lines.yScale();\n            y3 = switchYAxisOrder ? lines2.yScale() : bars2.yScale();\n            y4 = switchYAxisOrder ? bars2.yScale() : lines2.yScale();\n\n            var series1 = data\n                .filter(function(d) { return !d.disabled && (switchYAxisOrder ? !d.bar : d.bar) })\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i) }\n                    })\n                });\n\n            var series2 = data\n                .filter(function(d) { return !d.disabled && (switchYAxisOrder ? d.bar : !d.bar) })\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i) }\n                    })\n                });\n\n            x.range([0, availableWidth]);\n\n            x2  .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x } ))\n                .range([0, availableWidth]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-linePlusBar').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            // this is the main chart\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            focusEnter.append('g').attr('class', 'nv-barsWrap');\n            focusEnter.append('g').attr('class', 'nv-linesWrap');\n\n            // context chart is where you can focus in\n            var contextEnter = gEnter.append('g').attr('class', 'nv-context');\n            contextEnter.append('g').attr('class', 'nv-x nv-axis');\n            contextEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            contextEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            contextEnter.append('g').attr('class', 'nv-barsWrap');\n            contextEnter.append('g').attr('class', 'nv-linesWrap');\n            contextEnter.append('g').attr('class', 'nv-brushBackground');\n            contextEnter.append('g').attr('class', 'nv-x nv-brush');\n\n            //============================================================\n            // Legend\n            //------------------------------------------------------------\n\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;\n                var legendXPosition = legend.align() ? legendWidth : 0;\n\n                legend.width(legendWidth);\n\n                g.select('.nv-legendWrap')\n                    .datum(data.map(function(series) {\n                        series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;\n                        if(switchYAxisOrder) {\n                            series.key = series.originalKey + (series.bar ? legendRightAxisHint : legendLeftAxisHint);\n                        } else {\n                            series.key = series.originalKey + (series.bar ? legendLeftAxisHint : legendRightAxisHint);\n                        }\n                        return series;\n                    }))\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    // FIXME: shouldn't this be \"- (focusEnabled ? focusHeight : 0)\"?\n                    availableHeight1 = nv.utils.availableHeight(height, container, margin) - focusHeight;\n                }\n\n                g.select('.nv-legendWrap')\n                    .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            //============================================================\n            // Context chart (focus chart) components\n            //------------------------------------------------------------\n\n            // hide or show the focus context chart\n            g.select('.nv-context').style('display', focusEnable ? 'initial' : 'none');\n\n            bars2\n                .width(availableWidth)\n                .height(availableHeight2)\n                .color(data.map(function (d, i) {\n                    return d.color || color(d, i);\n                }).filter(function (d, i) {\n                    return !data[i].disabled && data[i].bar\n                }));\n            lines2\n                .width(availableWidth)\n                .height(availableHeight2)\n                .color(data.map(function (d, i) {\n                    return d.color || color(d, i);\n                }).filter(function (d, i) {\n                    return !data[i].disabled && !data[i].bar\n                }));\n\n            var bars2Wrap = g.select('.nv-context .nv-barsWrap')\n                .datum(dataBars.length ? dataBars : [\n                    {values: []}\n                ]);\n            var lines2Wrap = g.select('.nv-context .nv-linesWrap')\n                .datum(allDisabled(dataLines) ?\n                       [{values: []}] :\n                       dataLines.filter(function(dataLine) {\n                         return !dataLine.disabled;\n                       }));\n\n            g.select('.nv-context')\n                .attr('transform', 'translate(0,' + ( availableHeight1 + margin.bottom + margin2.top) + ')');\n\n            bars2Wrap.transition().call(bars2);\n            lines2Wrap.transition().call(lines2);\n\n            // context (focus chart) axis controls\n            if (focusShowAxisX) {\n                x2Axis\n                    ._ticks( nv.utils.calcTicksX(availableWidth / 100, data))\n                    .tickSize(-availableHeight2, 0);\n                g.select('.nv-context .nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y3.range()[0] + ')');\n                g.select('.nv-context .nv-x.nv-axis').transition()\n                    .call(x2Axis);\n            }\n\n            if (focusShowAxisY) {\n                y3Axis\n                    .scale(y3)\n                    ._ticks( availableHeight2 / 36 )\n                    .tickSize( -availableWidth, 0);\n                y4Axis\n                    .scale(y4)\n                    ._ticks( availableHeight2 / 36 )\n                    .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if y1 has none\n\n                g.select('.nv-context .nv-y3.nv-axis')\n                    .style('opacity', dataBars.length ? 1 : 0)\n                    .attr('transform', 'translate(0,' + x2.range()[0] + ')');\n                g.select('.nv-context .nv-y2.nv-axis')\n                    .style('opacity', dataLines.length ? 1 : 0)\n                    .attr('transform', 'translate(' + x2.range()[1] + ',0)');\n\n                g.select('.nv-context .nv-y1.nv-axis').transition()\n                    .call(y3Axis);\n                g.select('.nv-context .nv-y2.nv-axis').transition()\n                    .call(y4Axis);\n            }\n\n            // Setup Brush\n            brush.x(x2).on('brush', onBrush);\n\n            if (brushExtent) brush.extent(brushExtent);\n\n            var brushBG = g.select('.nv-brushBackground').selectAll('g')\n                .data([brushExtent || brush.extent()]);\n\n            var brushBGenter = brushBG.enter()\n                .append('g');\n\n            brushBGenter.append('rect')\n                .attr('class', 'left')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight2);\n\n            brushBGenter.append('rect')\n                .attr('class', 'right')\n                .attr('x', 0)\n                .attr('y', 0)\n                .attr('height', availableHeight2);\n\n            var gBrush = g.select('.nv-x.nv-brush')\n                .call(brush);\n            gBrush.selectAll('rect')\n                //.attr('y', -5)\n                .attr('height', availableHeight2);\n            gBrush.selectAll('.resize').append('path').attr('d', resizePath);\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            // Taken from crossfilter (http://square.github.com/crossfilter/)\n            function resizePath(d) {\n                var e = +(d == 'e'),\n                    x = e ? 1 : -1,\n                    y = availableHeight2 / 3;\n                return 'M' + (.5 * x) + ',' + y\n                    + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)\n                    + 'V' + (2 * y - 6)\n                    + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y)\n                    + 'Z'\n                    + 'M' + (2.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8)\n                    + 'M' + (4.5 * x) + ',' + (y + 8)\n                    + 'V' + (2 * y - 8);\n            }\n\n\n            function updateBrushBG() {\n                if (!brush.empty()) brush.extent(brushExtent);\n                brushBG\n                    .data([brush.empty() ? x2.domain() : brushExtent])\n                    .each(function(d,i) {\n                        var leftWidth = x2(d[0]) - x2.range()[0],\n                            rightWidth = x2.range()[1] - x2(d[1]);\n                        d3.select(this).select('.left')\n                            .attr('width',  leftWidth < 0 ? 0 : leftWidth);\n\n                        d3.select(this).select('.right')\n                            .attr('x', x2(d[1]))\n                            .attr('width', rightWidth < 0 ? 0 : rightWidth);\n                    });\n            }\n\n            function onBrush() {\n                brushExtent = brush.empty() ? null : brush.extent();\n                extent = brush.empty() ? x2.domain() : brush.extent();\n                dispatch.brush({extent: extent, brush: brush});\n                updateBrushBG();\n\n                // Prepare Main (Focus) Bars and Lines\n                bars\n                    .width(availableWidth)\n                    .height(availableHeight1)\n                    .color(data.map(function(d,i) {\n                        return d.color || color(d, i);\n                    }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));\n\n                lines\n                    .width(availableWidth)\n                    .height(availableHeight1)\n                    .color(data.map(function(d,i) {\n                        return d.color || color(d, i);\n                    }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));\n\n                var focusBarsWrap = g.select('.nv-focus .nv-barsWrap')\n                    .datum(!dataBars.length ? [{values:[]}] :\n                        dataBars\n                            .map(function(d,i) {\n                                return {\n                                    key: d.key,\n                                    values: d.values.filter(function(d,i) {\n                                        return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <= extent[1];\n                                    })\n                                }\n                            })\n                );\n\n                var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')\n                    .datum(allDisabled(dataLines) ? [{values:[]}] :\n                           dataLines\n                           .filter(function(dataLine) { return !dataLine.disabled; })\n                           .map(function(d,i) {\n                                return {\n                                    area: d.area,\n                                    fillOpacity: d.fillOpacity,\n                                    strokeWidth: d.strokeWidth,\n                                    key: d.key,\n                                    values: d.values.filter(function(d,i) {\n                                        return lines.x()(d,i) >= extent[0] && lines.x()(d,i) <= extent[1];\n                                    })\n                                }\n                            })\n                );\n\n                // Update Main (Focus) X Axis\n                if (dataBars.length && !switchYAxisOrder) {\n                    x = bars.xScale();\n                } else {\n                    x = lines.xScale();\n                }\n\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight1, 0);\n\n                xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]);\n\n                g.select('.nv-x.nv-axis').transition().duration(transitionDuration)\n                    .call(xAxis);\n\n                // Update Main (Focus) Bars and Lines\n                focusBarsWrap.transition().duration(transitionDuration).call(bars);\n                focusLinesWrap.transition().duration(transitionDuration).call(lines);\n\n                // Setup and Update Main (Focus) Y Axes\n                g.select('.nv-focus .nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y1.range()[0] + ')');\n\n                y1Axis\n                    .scale(y1)\n                    ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) )\n                    .tickSize(-availableWidth, 0);\n                y2Axis\n                    .scale(y2)\n                    ._ticks( nv.utils.calcTicksY(availableHeight1/36, data) );\n\n                // Show the y2 rules only if y1 has none\n                if(!switchYAxisOrder) {\n                    y2Axis.tickSize(dataBars.length ? 0 : -availableWidth, 0);\n                } else {\n                    y2Axis.tickSize(dataLines.length ? 0 : -availableWidth, 0);\n                }\n\n                // Calculate opacity of the axis\n                var barsOpacity = dataBars.length ? 1 : 0;\n                var linesOpacity = dataLines.length && !allDisabled(dataLines) ? 1 : 0;\n\n                var y1Opacity = switchYAxisOrder ? linesOpacity : barsOpacity;\n                var y2Opacity = switchYAxisOrder ? barsOpacity : linesOpacity;\n\n                g.select('.nv-focus .nv-y1.nv-axis')\n                    .style('opacity', y1Opacity);\n                g.select('.nv-focus .nv-y2.nv-axis')\n                    .style('opacity', y2Opacity)\n                    .attr('transform', 'translate(' + x.range()[1] + ',0)');\n\n                g.select('.nv-focus .nv-y1.nv-axis').transition().duration(transitionDuration)\n                    .call(y1Axis);\n                g.select('.nv-focus .nv-y2.nv-axis').transition().duration(transitionDuration)\n                    .call(y2Axis);\n            }\n\n            onBrush();\n\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    lines.dispatch.on('elementMouseover.tooltip', function(evt) {\n        tooltip\n            .duration(100)\n            .valueFormatter(function(d, i) {\n                return getLinesAxis().main.tickFormat()(d, i);\n            })\n            .data(evt)\n            .hidden(false);\n    });\n\n    lines.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n\n    bars.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.value = chart.x()(evt.data);\n        evt['series'] = {\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip\n            .duration(0)\n            .valueFormatter(function(d, i) {\n                return getBarsAxis().main.tickFormat()(d, i);\n            })\n            .data(evt)\n            .hidden(false);\n    });\n\n    bars.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    bars.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.legend = legend;\n    chart.lines = lines;\n    chart.lines2 = lines2;\n    chart.bars = bars;\n    chart.bars2 = bars2;\n    chart.xAxis = xAxis;\n    chart.x2Axis = x2Axis;\n    chart.y1Axis = y1Axis;\n    chart.y2Axis = y2Axis;\n    chart.y3Axis = y3Axis;\n    chart.y4Axis = y4Axis;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        brushExtent:    {get: function(){return brushExtent;}, set: function(_){brushExtent=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:    {get: function(){return focusHeight;}, set: function(_){focusHeight=_;}},\n        focusShowAxisX:    {get: function(){return focusShowAxisX;}, set: function(_){focusShowAxisX=_;}},\n        focusShowAxisY:    {get: function(){return focusShowAxisY;}, set: function(_){focusShowAxisY=_;}},\n        legendLeftAxisHint:    {get: function(){return legendLeftAxisHint;}, set: function(_){legendLeftAxisHint=_;}},\n        legendRightAxisHint:    {get: function(){return legendRightAxisHint;}, set: function(_){legendRightAxisHint=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        focusMargin: {get: function(){return margin2;}, set: function(_){\n            margin2.top    = _.top    !== undefined ? _.top    : margin2.top;\n            margin2.right  = _.right  !== undefined ? _.right  : margin2.right;\n            margin2.bottom = _.bottom !== undefined ? _.bottom : margin2.bottom;\n            margin2.left   = _.left   !== undefined ? _.left   : margin2.left;\n        }},\n        duration: {get: function(){return transitionDuration;}, set: function(_){\n            transitionDuration = _;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            lines.x(_);\n            lines2.x(_);\n            bars.x(_);\n            bars2.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            lines.y(_);\n            lines2.y(_);\n            bars.y(_);\n            bars2.y(_);\n        }},\n        switchYAxisOrder:    {get: function(){return switchYAxisOrder;}, set: function(_){\n            // Switch the tick format for the yAxis\n            if(switchYAxisOrder !== _) {\n                var y1 = y1Axis;\n                y1Axis = y2Axis;\n                y2Axis = y1;\n\n                var y3 = y3Axis;\n                y3Axis = y4Axis;\n                y4Axis = y3;\n            }\n            switchYAxisOrder=_;\n\n            y1Axis.orient('left');\n            y2Axis.orient('right');\n            y3Axis.orient('left');\n            y4Axis.orient('right');\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, lines);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/multiBar.js",
    "content": "\nnv.models.multiBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , clipEdge = true\n        , stacked = false\n        , stackOffset = 'zero' // options include 'silhouette', 'wiggle', 'expand', 'zero', or a custom function\n        , color = nv.utils.defaultColor()\n        , hideable = false\n        , barColor = null // adding the ability to set the color for each rather than the whole group\n        , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled\n        , duration = 500\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , groupSpacing = 0.1\n        , fillOpacity = 0.75\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0 //used to store previous scales\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        ;\n\n    var last_datalength = 0;\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n            var nonStackableCount = 0;\n            // This function defines the requirements for render complete\n            var endFn = function(d, i) {\n                if (d.series === data.length - 1 && i === data[0].values.length - 1)\n                    return true;\n                return false;\n            };\n\n            if(hideable && data.length) hideable = [{\n                values: data[0].values.map(function(d) {\n                        return {\n                            x: d.x,\n                            y: 0,\n                            series: d.series,\n                            size: 0.01\n                        };}\n                )}];\n\n            if (stacked) {\n                var parsed = d3.layout.stack()\n                    .offset(stackOffset)\n                    .values(function(d){ return d.values })\n                    .y(getY)\n                (!data.length && hideable ? hideable : data);\n\n                parsed.forEach(function(series, i){\n                    // if series is non-stackable, use un-parsed data\n                    if (series.nonStackable) {\n                        data[i].nonStackableSeries = nonStackableCount++;\n                        parsed[i] = data[i];\n                    } else {\n                        // don't stack this seires on top of the nonStackable seriees\n                        if (i > 0 && parsed[i - 1].nonStackable){\n                            parsed[i].values.map(function(d,j){\n                                d.y0 -= parsed[i - 1].values[j].y;\n                                d.y1 = d.y0 + d.y;\n                            });\n                        }\n                    }\n                });\n                data = parsed;\n            }\n            //add series index and key to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                    point.key = series.key;\n                });\n            });\n\n            // HACK for negative value stacking\n            if (stacked && data.length > 0) {\n                data[0].values.map(function(d,i) {\n                    var posBase = 0, negBase = 0;\n                    data.map(function(d, idx) {\n                        if (!data[idx].nonStackable) {\n                            var f = d.values[i]\n                            f.size = Math.abs(f.y);\n                            if (f.y<0)  {\n                                f.y1 = negBase;\n                                negBase = negBase - f.size;\n                            } else\n                            {\n                                f.y1 = f.size + posBase;\n                                posBase = posBase + f.size;\n                            }\n                        }\n\n                    });\n                });\n            }\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d, idx) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1, idx:idx }\n                    })\n                });\n\n            x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableWidth], groupSpacing);\n\n            y.domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) {\n                var domain = d.y;\n                // increase the domain range if this series is stackable\n                if (stacked && !data[d.idx].nonStackable) {\n                    if (d.y > 0){\n                        domain = d.y1\n                    } else {\n                        domain = d.y1 + d.y\n                    }\n                }\n                return domain;\n            }).concat(forceY)))\n            .range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multibar').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect');\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d,i) { return i });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n\n            var exitTransition = renderWatch\n                .transition(groups.exit().selectAll('rect.nv-bar'), 'multibarExit', Math.min(100, duration))\n                .attr('y', function(d, i, j) {\n                    var yVal = y0(0) || 0;\n                    if (stacked) {\n                        if (data[d.series] && !data[d.series].nonStackable) {\n                            yVal = y0(d.y0);\n                        }\n                    }\n                    return yVal;\n                })\n                .attr('height', 0)\n                .remove();\n            if (exitTransition.delay)\n                exitTransition.delay(function(d,i) {\n                    var delay = i * (duration / (last_datalength + 1)) - i;\n                    return delay;\n                });\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i) });\n            groups\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', fillOpacity);\n\n            var bars = groups.selectAll('rect.nv-bar')\n                .data(function(d) { return (hideable && !data.length) ? hideable.values : d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('rect')\n                    .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n                    .attr('x', function(d,i,j) {\n                        return stacked && !data[j].nonStackable ? 0 : (j * x.rangeBand() / data.length )\n                    })\n                    .attr('y', function(d,i,j) { return y0(stacked && !data[j].nonStackable ? d.y0 : 0) || 0 })\n                    .attr('height', 0)\n                    .attr('width', function(d,i,j) { return x.rangeBand() / (stacked && !data[j].nonStackable ? 1 : data.length) })\n                    .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })\n                ;\n            bars\n                .style('fill', function(d,i,j){ return color(d, j, i);  })\n                .style('stroke', function(d,i,j){ return color(d, j, i); })\n                .on('mouseover', function(d,i,j) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i,j) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i,j) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i,j) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i,j) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        series: data[j],\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',0)'; })\n\n            if (barColor) {\n                if (!disabled) disabled = data.map(function() { return true });\n                bars\n                    .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); })\n                    .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); });\n            }\n\n            var barSelection =\n                bars.watchTransition(renderWatch, 'multibar', Math.min(250, duration))\n                    .delay(function(d,i) {\n                        return i * duration / data[0].values.length;\n                    });\n            if (stacked){\n                barSelection\n                    .attr('y', function(d,i,j) {\n                        var yVal = 0;\n                        // if stackable, stack it on top of the previous series\n                        if (!data[j].nonStackable) {\n                            yVal = y(d.y1);\n                        } else {\n                            if (getY(d,i) < 0){\n                                yVal = y(0);\n                            } else {\n                                if (y(0) - y(getY(d,i)) < -1){\n                                    yVal = y(0) - 1;\n                                } else {\n                                    yVal = y(getY(d, i)) || 0;\n                                }\n                            }\n                        }\n                        return yVal;\n                    })\n                    .attr('height', function(d,i,j) {\n                        if (!data[j].nonStackable) {\n                            return Math.max(Math.abs(y(d.y+d.y0) - y(d.y0)), 0);\n                        } else {\n                            return Math.max(Math.abs(y(getY(d,i)) - y(0)), 0) || 0;\n                        }\n                    })\n                    .attr('x', function(d,i,j) {\n                        var width = 0;\n                        if (data[j].nonStackable) {\n                            width = d.series * x.rangeBand() / data.length;\n                            if (data.length !== nonStackableCount){\n                                width = data[j].nonStackableSeries * x.rangeBand()/(nonStackableCount*2);\n                            }\n                        }\n                        return width;\n                    })\n                    .attr('width', function(d,i,j){\n                        if (!data[j].nonStackable) {\n                            return x.rangeBand();\n                        } else {\n                            // if all series are nonStacable, take the full width\n                            var width = (x.rangeBand() / nonStackableCount);\n                            // otherwise, nonStackable graph will be only taking the half-width\n                            // of the x rangeBand\n                            if (data.length !== nonStackableCount) {\n                                width = x.rangeBand()/(nonStackableCount*2);\n                            }\n                            return width;\n                        }\n                    });\n            }\n            else {\n                barSelection\n                    .attr('x', function(d,i) {\n                        return d.series * x.rangeBand() / data.length;\n                    })\n                    .attr('width', x.rangeBand() / data.length)\n                    .attr('y', function(d,i) {\n                        return getY(d,i) < 0 ?\n                            y(0) :\n                                y(0) - y(getY(d,i)) < 1 ?\n                            y(0) - 1 :\n                            y(getY(d,i)) || 0;\n                    })\n                    .attr('height', function(d,i) {\n                        return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0;\n                    });\n            }\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n            // keep track of the last data value length for transition calculations\n            if (data[0] && data[0].values) {\n                last_datalength = data[0].values.length;\n            }\n\n        });\n\n        renderWatch.renderEnd('multibar immediate');\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}},\n        stackOffset: {get: function(){return stackOffset;}, set: function(_){stackOffset=_;}},\n        clipEdge:    {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        disabled:    {get: function(){return disabled;}, set: function(_){disabled=_;}},\n        id:          {get: function(){return id;}, set: function(_){id=_;}},\n        hideable:    {get: function(){return hideable;}, set: function(_){hideable=_;}},\n        groupSpacing:{get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}},\n        fillOpacity: {get: function(){return fillOpacity;}, set: function(_){fillOpacity=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        barColor:  {get: function(){return barColor;}, set: function(_){\n            barColor = _ ? nv.utils.getColor(_) : null;\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/multiBarChart.js",
    "content": "nv.models.multiBarChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var multibar = nv.models.multiBar()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , interactiveLayer = nv.interactiveGuideline()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , controlLabels = {}\n        , showLegend = true\n        , legendPosition = null\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , reduceXTicks = true // if false a tick will show for every data point\n        , staggerLabels = false\n        , wrapLabels = false\n        , rotateLabels = 0\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , controlWidth = function() { return showControls ? 180 : 0 }\n        , duration = 250\n        , useInteractiveGuideline = false\n        ;\n\n    state.stacked = false // DEPRECATED Maintained for backward compatibility\n\n    multibar.stacked(false);\n    xAxis\n        .orient('bottom')\n        .tickPadding(7)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .valueFormatter(function(d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .valueFormatter(function (d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function (d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    var stacked = false;\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                stacked: stacked\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.stacked !== undefined)\n                stacked = state.stacked;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(multibar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition()\n                        .duration(duration)\n                        .call(chart);\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = multibar.xScale();\n            y = multibar.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multiBarWithLegend').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarWithLegend').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                if (legendPosition === 'bottom') {\n                    legend.width(availableWidth - margin.right);\n\n                     g.select('.nv-legendWrap')\n                         .datum(data)\n                         .call(legend);\n\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(0,' + (availableHeight + xAxis.height())  +')');\n                } else {\n                    legend.width(availableWidth - controlWidth());\n\n                    g.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');\n                }\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },\n                    { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }\n                ];\n\n                controls.width(controlWidth()).color(['#444', '#444', '#444']);\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .attr('transform', 'translate(0,' + (-margin.top) +')')\n                    .call(controls);\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Main Chart Component(s)\n            multibar\n                .disabled(data.map(function(series) { return series.disabled }))\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.call(multibar);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize(-availableHeight, 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')');\n                g.select('.nv-x.nv-axis')\n                    .call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis > g').selectAll('g');\n\n                xTicks\n                    .selectAll('line, text')\n                    .style('opacity', 1)\n\n                if (staggerLabels) {\n                    var getTranslate = function(x,y) {\n                        return \"translate(\" + x + \",\" + y + \")\";\n                    };\n\n                    var staggerUp = 5, staggerDown = 17;  //pixels to stagger by\n                    // Issue #140\n                    xTicks\n                        .selectAll(\"text\")\n                        .attr('transform', function(d,i,j) {\n                            return  getTranslate(0, (j % 2 == 0 ? staggerUp : staggerDown));\n                        });\n\n                    var totalInBetweenTicks = d3.selectAll(\".nv-x.nv-axis .nv-wrap g g text\")[0].length;\n                    g.selectAll(\".nv-x.nv-axis .nv-axisMaxMin text\")\n                        .attr(\"transform\", function(d,i) {\n                            return getTranslate(0, (i === 0 || totalInBetweenTicks % 2 !== 0) ? staggerDown : staggerUp);\n                        });\n                }\n\n                if (wrapLabels) {\n                    g.selectAll('.tick text')\n                        .call(nv.utils.wrapTicks, chart.xAxis.rangeBand())\n                }\n\n                if (reduceXTicks)\n                    xTicks\n                        .filter(function(d,i) {\n                            return i % Math.ceil(data[0].values.length / (availableWidth / 100)) !== 0;\n                        })\n                        .selectAll('text, line')\n                        .style('opacity', 0);\n\n                if(rotateLabels)\n                    xTicks\n                        .selectAll('.tick text')\n                        .attr('transform', 'rotate(' + rotateLabels + ' 0,0)')\n                        .style('text-anchor', rotateLabels > 0 ? 'start' : 'end');\n\n                g.select('.nv-x.nv-axis').selectAll('g.nv-axisMaxMin text')\n                    .style('opacity', 1);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                switch (d.key) {\n                    case 'Grouped':\n                    case controlLabels.grouped:\n                        multibar.stacked(false);\n                        break;\n                    case 'Stacked':\n                    case controlLabels.stacked:\n                        multibar.stacked(true);\n                        break;\n                }\n\n                state.stacked = multibar.stacked();\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                if (typeof e.stacked !== 'undefined') {\n                    multibar.stacked(e.stacked);\n                    state.stacked = e.stacked;\n                    stacked = e.stacked;\n                }\n                chart.update();\n            });\n\n            if (useInteractiveGuideline) {\n                interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                    if (e.pointXValue == undefined) return;\n\n                    var singlePoint, pointIndex, pointXLocation, xValue, allData = [];\n                    data\n                        .filter(function(series, i) {\n                            series.seriesIndex = i;\n                            return !series.disabled;\n                        })\n                        .forEach(function(series,i) {\n                            pointIndex = x.domain().indexOf(e.pointXValue)\n\n                            var point = series.values[pointIndex];\n                            if (point === undefined) return;\n\n                            xValue = point.x;\n                            if (singlePoint === undefined) singlePoint = point;\n                            if (pointXLocation === undefined) pointXLocation = e.mouseX\n                            allData.push({\n                                key: series.key,\n                                value: chart.y()(point, pointIndex),\n                                color: color(series,series.seriesIndex),\n                                data: series.values[pointIndex]\n                            });\n                        });\n\n                    interactiveLayer.tooltip\n                        .data({\n                            value: xValue,\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                });\n\n                interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                    interactiveLayer.tooltip.hidden(true);\n                });\n            }\n            else {\n                multibar.dispatch.on('elementMouseover.tooltip', function(evt) {\n                    evt.value = chart.x()(evt.data);\n                    evt['series'] = {\n                        key: evt.data.key,\n                        value: chart.y()(evt.data),\n                        color: evt.color\n                    };\n                    tooltip.data(evt).hidden(false);\n                });\n\n                multibar.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n\n                multibar.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n            }\n        });\n\n        renderWatch.renderEnd('multibarchart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.multibar = multibar;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.state = state;\n    chart.tooltip = tooltip;\n    chart.interactiveLayer = interactiveLayer;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        reduceXTicks:    {get: function(){return reduceXTicks;}, set: function(_){reduceXTicks=_;}},\n        rotateLabels:    {get: function(){return rotateLabels;}, set: function(_){rotateLabels=_;}},\n        staggerLabels:    {get: function(){return staggerLabels;}, set: function(_){staggerLabels=_;}},\n        wrapLabels:   {get: function(){return wrapLabels;}, set: function(_){wrapLabels=!!_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            multibar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n        }},\n        barColor:  {get: function(){return multibar.barColor;}, set: function(_){\n            multibar.barColor(_);\n            legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();})\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, multibar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/multiBarHorizontal.js",
    "content": "\nnv.models.multiBarHorizontal = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.ordinal()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getYerr = function(d) { return d.yErr }\n        , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar graphs... user can always do chart.forceY([]) to remove\n        , color = nv.utils.defaultColor()\n        , barColor = null // adding the ability to set the color for each rather than the whole group\n        , disabled // used in conjunction with barColor to communicate from multiBarHorizontalChart what series are disabled\n        , stacked = false\n        , showValues = false\n        , showBarLabels = false\n        , valuePadding = 60\n        , groupSpacing = 0.1\n        , fillOpacity = 0.75\n        , valueFormat = d3.format(',.2f')\n        , delay = 1200\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , duration = 250\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0; //used to store previous scales\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            if (stacked)\n                data = d3.layout.stack()\n                    .offset('zero')\n                    .values(function(d){ return d.values })\n                    .y(getY)\n                (data);\n\n            //add series index and key to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                    point.key = series.key;\n                });\n            });\n\n            // HACK for negative value stacking\n            if (stacked)\n                data[0].values.map(function(d,i) {\n                    var posBase = 0, negBase = 0;\n                    data.map(function(d) {\n                        var f = d.values[i]\n                        f.size = Math.abs(f.y);\n                        if (f.y<0)  {\n                            f.y1 = negBase - f.size;\n                            negBase = negBase - f.size;\n                        } else\n                        {\n                            f.y1 = posBase;\n                            posBase = posBase + f.size;\n                        }\n                    });\n                });\n\n            // Setup Scales\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and yDomain, no need to calculate\n                data.map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 }\n                    })\n                });\n\n            x.domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))\n                .rangeBands(xRange || [0, availableHeight], groupSpacing);\n\n            y.domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return stacked ? (d.y > 0 ? d.y1 + d.y : d.y1 ) : d.y }).concat(forceY)))\n\n            if (showValues && !stacked)\n                y.range(yRange || [(y.domain()[0] < 0 ? valuePadding : 0), availableWidth - (y.domain()[1] > 0 ? valuePadding : 0) ]);\n            else\n                y.range(yRange || [0, availableWidth]);\n\n            x0 = x0 || x;\n            y0 = y0 || d3.scale.linear().domain(y.domain()).range([y(0),y(0)]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-multibarHorizontal').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multibarHorizontal');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-groups');\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d,i) { return i });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit().watchTransition(renderWatch, 'multibarhorizontal: exit groups')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6)\n                .remove();\n            groups\n                .attr('class', function(d,i) { return 'nv-group nv-series-' + i })\n                .classed('hover', function(d) { return d.hover })\n                .style('fill', function(d,i){ return color(d, i) })\n                .style('stroke', function(d,i){ return color(d, i) });\n            groups.watchTransition(renderWatch, 'multibarhorizontal: groups')\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', fillOpacity);\n\n            var bars = groups.selectAll('g.nv-bar')\n                .data(function(d) { return d.values });\n            bars.exit().remove();\n\n            var barsEnter = bars.enter().append('g')\n                .attr('transform', function(d,i,j) {\n                    return 'translate(' + y0(stacked ? d.y0 : 0) + ',' + (stacked ? 0 : (j * x.rangeBand() / data.length ) + x(getX(d,i))) + ')'\n                });\n\n            barsEnter.append('rect')\n                .attr('width', 0)\n                .attr('height', x.rangeBand() / (stacked ? 1 : data.length) )\n\n            bars\n                .on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here\n                    d3.select(this).classed('hover', true);\n                    dispatch.elementMouseover({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    dispatch.elementMouseout({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('mousemove', function(d,i) {\n                    dispatch.elementMousemove({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                })\n                .on('click', function(d,i) {\n                    var element = this;\n                    dispatch.elementClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\"),\n                        event: d3.event,\n                        element: element\n                    });\n                    d3.event.stopPropagation();\n                })\n                .on('dblclick', function(d,i) {\n                    dispatch.elementDblClick({\n                        data: d,\n                        index: i,\n                        color: d3.select(this).style(\"fill\")\n                    });\n                    d3.event.stopPropagation();\n                });\n\n            if (getYerr(data[0],0)) {\n                barsEnter.append('polyline');\n\n                bars.select('polyline')\n                    .attr('fill', 'none')\n                    .attr('points', function(d,i) {\n                        var xerr = getYerr(d,i)\n                            , mid = 0.8 * x.rangeBand() / ((stacked ? 1 : data.length) * 2);\n                        xerr = xerr.length ? xerr : [-Math.abs(xerr), Math.abs(xerr)];\n                        xerr = xerr.map(function(e) { return y(e + ((getY(d,i) < 0) ? 0 : getY(d,i))) - y(0); });\n                        var a = [[xerr[0],-mid], [xerr[0],mid], [xerr[0],0], [xerr[1],0], [xerr[1],-mid], [xerr[1],mid]];\n                        return a.map(function (path) { return path.join(',') }).join(' ');\n                    })\n                    .attr('transform', function(d,i) {\n                        var mid = x.rangeBand() / ((stacked ? 1 : data.length) * 2);\n                        return 'translate(0, ' + mid + ')';\n                    });\n            }\n\n            barsEnter.append('text');\n\n            if (showValues && !stacked) {\n                bars.select('text')\n                    .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'end' : 'start' })\n                    .attr('y', x.rangeBand() / (data.length * 2))\n                    .attr('dy', '.32em')\n                    .text(function(d,i) {\n                        var t = valueFormat(getY(d,i))\n                            , yerr = getYerr(d,i);\n                        if (yerr === undefined)\n                            return t;\n                        if (!yerr.length)\n                            return t + '±' + valueFormat(Math.abs(yerr));\n                        return t + '+' + valueFormat(Math.abs(yerr[1])) + '-' + valueFormat(Math.abs(yerr[0]));\n                    });\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .select('text')\n                    .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 : y(getY(d,i)) - y(0) + 4 })\n            } else {\n                bars.selectAll('text').text('');\n            }\n\n            if (showBarLabels && !stacked) {\n                barsEnter.append('text').classed('nv-bar-label',true);\n                bars.select('text.nv-bar-label')\n                    .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ? 'start' : 'end' })\n                    .attr('y', x.rangeBand() / (data.length * 2))\n                    .attr('dy', '.32em')\n                    .text(function(d,i) { return getX(d,i) });\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .select('text.nv-bar-label')\n                    .attr('x', function(d,i) { return getY(d,i) < 0 ? y(0) - y(getY(d,i)) + 4 : -4 });\n            }\n            else {\n                bars.selectAll('text.nv-bar-label').text('');\n            }\n\n            bars\n                .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive'})\n\n            if (barColor) {\n                if (!disabled) disabled = data.map(function() { return true });\n                bars\n                    .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); })\n                    .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(  disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i]  })[j]   ).toString(); });\n            }\n\n            if (stacked)\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .attr('transform', function(d,i) {\n                        return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) + ')'\n                    })\n                    .select('rect')\n                    .attr('width', function(d,i) {\n                        return Math.abs(y(getY(d,i) + d.y0) - y(d.y0)) || 0\n                    })\n                    .attr('height', x.rangeBand() );\n            else\n                bars.watchTransition(renderWatch, 'multibarhorizontal: bars')\n                    .attr('transform', function(d,i) {\n                        //TODO: stacked must be all positive or all negative, not both?\n                        return 'translate(' +\n                            (getY(d,i) < 0 ? y(getY(d,i)) : y(0))\n                            + ',' +\n                            (d.series * x.rangeBand() / data.length\n                                +\n                                x(getX(d,i)) )\n                            + ')'\n                    })\n                    .select('rect')\n                    .attr('height', x.rangeBand() / data.length )\n                    .attr('width', function(d,i) {\n                        return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0\n                    });\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('multibarHorizontal immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:   {get: function(){return width;}, set: function(_){width=_;}},\n        height:  {get: function(){return height;}, set: function(_){height=_;}},\n        x:       {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:       {get: function(){return getY;}, set: function(_){getY=_;}},\n        yErr:       {get: function(){return getYerr;}, set: function(_){getYerr=_;}},\n        xScale:  {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:  {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:  {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:  {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceY:  {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        stacked: {get: function(){return stacked;}, set: function(_){stacked=_;}},\n        showValues: {get: function(){return showValues;}, set: function(_){showValues=_;}},\n        // this shows the group name, seems pointless?\n        //showBarLabels:    {get: function(){return showBarLabels;}, set: function(_){showBarLabels=_;}},\n        disabled:     {get: function(){return disabled;}, set: function(_){disabled=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n        valueFormat:  {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        valuePadding: {get: function(){return valuePadding;}, set: function(_){valuePadding=_;}},\n        groupSpacing: {get: function(){return groupSpacing;}, set: function(_){groupSpacing=_;}},\n        fillOpacity:  {get: function(){return fillOpacity;}, set: function(_){fillOpacity=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        barColor:  {get: function(){return barColor;}, set: function(_){\n            barColor = _ ? nv.utils.getColor(_) : null;\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/multiBarHorizontalChart.js",
    "content": "\nnv.models.multiBarHorizontalChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var multibar = nv.models.multiBarHorizontal()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend().height(30)\n        , controls = nv.models.legend().height(30)\n        , tooltip = nv.models.tooltip()\n        ;\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , controlsPosition = 'top'        \n        , controlLabels = {}\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , stacked = false\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        , controlWidth = function() { return showControls ? 180 : 0 }\n        , duration = 250\n        ;\n\n    state.stacked = false; // DEPRECATED Maintained for backward compatibility\n\n    multibar.stacked(stacked);\n\n    xAxis\n        .orient('left')\n        .tickPadding(5)\n        .showMaxMin(false)\n        .tickFormat(function(d) { return d })\n    ;\n    yAxis\n        .orient('bottom')\n        .tickFormat(d3.format(',.1f'))\n    ;\n\n    tooltip\n        .duration(0)\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        })\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        });\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                stacked: stacked\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.stacked !== undefined)\n                stacked = state.stacked;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(multibar);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().duration(duration).call(chart) };\n            chart.container = this;\n\n            stacked = multibar.stacked();\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = multibar.xScale();\n            y = multibar.yScale().clamp(true);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-multiBarHorizontalChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-multiBarHorizontalChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis')\n                .append('g').attr('class', 'nv-zeroLine')\n                .append('line');\n            gEnter.append('g').attr('class', 'nv-barsWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                legend.width(availableWidth - controlWidth());\n\n                g.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n                if (legendPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                     g.select('.nv-legendWrap')\n                         .attr('transform', 'translate(' + controlWidth() + ',' + (availableHeight + xAxis.height())  +')');\n                } else if (legendPosition === 'top') {\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');\n                }                    \n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    { key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },\n                    { key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }\n                ];\n\n                controls.width(controlWidth()).color(['#444', '#444', '#444']);\n\n                if (controlsPosition === 'bottom') {\n                     margin.bottom = xAxis.height() + legend.height();\n                     availableHeight = nv.utils.availableHeight(height, container, margin);\n                    g.select('.nv-controlsWrap')\n                        .datum(controlsData)\n                        .attr('transform', 'translate(0,' + (availableHeight + xAxis.height()) +')')\n                        .call(controls);  \n\n                } else if (controlsPosition === 'top') {\n                    g.select('.nv-controlsWrap')\n                        .datum(controlsData)\n                        .attr('transform', 'translate(0,' + (-margin.top) +')')\n                        .call(controls);                        \n                }\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            multibar\n                .disabled(data.map(function(series) { return series.disabled }))\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n\n            var barsWrap = g.select('.nv-barsWrap')\n                .datum(data.filter(function(d) { return !d.disabled }));\n\n            barsWrap.transition().call(multibar);\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/24, data) )\n                    .tickSize(-availableWidth, 0);\n\n                g.select('.nv-x.nv-axis').call(xAxis);\n\n                var xTicks = g.select('.nv-x.nv-axis').selectAll('g');\n\n                xTicks\n                    .selectAll('line, text');\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .attr('transform', 'translate(0,' + availableHeight + ')');\n                g.select('.nv-y.nv-axis').call(yAxis);\n            }\n\n            // Zero line\n            g.select(\".nv-zeroLine line\")\n                .attr(\"x1\", y(0))\n                .attr(\"x2\", y(0))\n                .attr(\"y1\", 0)\n                .attr(\"y2\", -availableHeight)\n            ;\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                switch (d.key) {\n                    case 'Grouped':\n                    case controlLabels.grouped:\n                        multibar.stacked(false);\n                        break;\n                    case 'Stacked':\n                    case controlLabels.stacked:\n                        multibar.stacked(true);\n                        break;\n                }\n\n                state.stacked = multibar.stacked();\n                dispatch.stateChange(state);\n                stacked = multibar.stacked();\n\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.stacked !== 'undefined') {\n                    multibar.stacked(e.stacked);\n                    state.stacked = e.stacked;\n                    stacked = e.stacked;\n                }\n\n                chart.update();\n            });\n        });\n        renderWatch.renderEnd('multibar horizontal chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    multibar.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.value = chart.x()(evt.data);\n        evt['series'] = {\n            key: evt.data.key,\n            value: chart.y()(evt.data),\n            color: evt.color\n        };\n        tooltip.data(evt).hidden(false);\n    });\n\n    multibar.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    multibar.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.multibar = multibar;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.state = state;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        controlsPosition: {get: function(){return controlsPosition;}, set: function(_){controlsPosition=_;}},\n        showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            multibar.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n        }},\n        barColor:  {get: function(){return multibar.barColor;}, set: function(_){\n            multibar.barColor(_);\n            legend.color(function(d,i) {return d3.rgb('#ccc').darker(i * 1.5).toString();})\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, multibar);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/multiChart.js",
    "content": "nv.models.multiChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 30, right: 20, bottom: 50, left: 60},\n        marginTop = null,\n        color = nv.utils.defaultColor(),\n        width = null,\n        height = null,\n        showLegend = true,\n        noData = null,\n        yDomain1,\n        yDomain2,\n        getX = function(d) { return d.x },\n        getY = function(d) { return d.y},\n        interpolate = 'linear',\n        useVoronoi = true,\n        interactiveLayer = nv.interactiveGuideline(),\n        useInteractiveGuideline = false,\n        legendRightAxisHint = ' (right axis)',\n        duration = 250\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x = d3.scale.linear(),\n        yScale1 = d3.scale.linear(),\n        yScale2 = d3.scale.linear(),\n\n        lines1 = nv.models.line().yScale(yScale1).duration(duration),\n        lines2 = nv.models.line().yScale(yScale2).duration(duration),\n\n        scatters1 = nv.models.scatter().yScale(yScale1).duration(duration),\n        scatters2 = nv.models.scatter().yScale(yScale2).duration(duration),\n\n        bars1 = nv.models.multiBar().stacked(false).yScale(yScale1).duration(duration),\n        bars2 = nv.models.multiBar().stacked(false).yScale(yScale2).duration(duration),\n\n        stack1 = nv.models.stackedArea().yScale(yScale1).duration(duration),\n        stack2 = nv.models.stackedArea().yScale(yScale2).duration(duration),\n\n        xAxis = nv.models.axis().scale(x).orient('bottom').tickPadding(5).duration(duration),\n        yAxis1 = nv.models.axis().scale(yScale1).orient('left').duration(duration),\n        yAxis2 = nv.models.axis().scale(yScale2).orient('right').duration(duration),\n\n        legend = nv.models.legend().height(30),\n        tooltip = nv.models.tooltip(),\n        dispatch = d3.dispatch();\n\n    var charts = [lines1, lines2, scatters1, scatters2, bars1, bars2, stack1, stack2];\n\n    function chart(selection) {\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            chart.update = function() { container.transition().call(chart); };\n            chart.container = this;\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            var dataLines1 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 1});\n            var dataLines2 = data.filter(function(d) {return d.type == 'line' && d.yAxis == 2});\n            var dataScatters1 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 1});\n            var dataScatters2 = data.filter(function(d) {return d.type == 'scatter' && d.yAxis == 2});\n            var dataBars1 =  data.filter(function(d) {return d.type == 'bar'  && d.yAxis == 1});\n            var dataBars2 =  data.filter(function(d) {return d.type == 'bar'  && d.yAxis == 2});\n            var dataStack1 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 1});\n            var dataStack2 = data.filter(function(d) {return d.type == 'area' && d.yAxis == 2});\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var series1 = data.filter(function(d) {return !d.disabled && d.yAxis == 1})\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d), y: getY(d) }\n                    })\n                });\n\n            var series2 = data.filter(function(d) {return !d.disabled && d.yAxis == 2})\n                .map(function(d) {\n                    return d.values.map(function(d,i) {\n                        return { x: getX(d), y: getY(d) }\n                    })\n                });\n\n            x   .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x }))\n                .range([0, availableWidth]);\n\n            var wrap = container.selectAll('g.wrap.multiChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3 multiChart').append('g');\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y1 nv-axis');\n            gEnter.append('g').attr('class', 'nv-y2 nv-axis');\n            gEnter.append('g').attr('class', 'stack1Wrap');\n            gEnter.append('g').attr('class', 'stack2Wrap');\n            gEnter.append('g').attr('class', 'bars1Wrap');\n            gEnter.append('g').attr('class', 'bars2Wrap');\n            gEnter.append('g').attr('class', 'scatters1Wrap');\n            gEnter.append('g').attr('class', 'scatters2Wrap');\n            gEnter.append('g').attr('class', 'lines1Wrap');\n            gEnter.append('g').attr('class', 'lines2Wrap');\n            gEnter.append('g').attr('class', 'legendWrap');\n            gEnter.append('g').attr('class', 'nv-interactive');\n\n            var g = wrap.select('g');\n\n            var color_array = data.map(function(d,i) {\n                return data[i].color || color(d, i);\n            });\n\n            // Legend\n            if (!showLegend) {\n                g.select('.legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;\n                var legendXPosition = legend.align() ? legendWidth : 0;\n\n                legend.width(legendWidth);\n                legend.color(color_array);\n\n                g.select('.legendWrap')\n                    .datum(data.map(function(series) {\n                        series.originalKey = series.originalKey === undefined ? series.key : series.originalKey;\n                        series.key = series.originalKey + (series.yAxis == 1 ? '' : legendRightAxisHint);\n                        return series;\n                    }))\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                g.select('.legendWrap')\n                    .attr('transform', 'translate(' + legendXPosition + ',' + (-margin.top) +')');\n            }\n\n            lines1\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'line'}));\n            lines2\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'line'}));\n            scatters1\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'scatter'}));\n            scatters2\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'scatter'}));\n            bars1\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'bar'}));\n            bars2\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'bar'}));\n            stack1\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'area'}));\n            stack2\n                .width(availableWidth)\n                .height(availableHeight)\n                .interpolate(interpolate)\n                .color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'area'}));\n\n            g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            var lines1Wrap = g.select('.lines1Wrap')\n                .datum(dataLines1.filter(function(d){return !d.disabled}));\n            var scatters1Wrap = g.select('.scatters1Wrap')\n                .datum(dataScatters1.filter(function(d){return !d.disabled}));\n            var bars1Wrap = g.select('.bars1Wrap')\n                .datum(dataBars1.filter(function(d){return !d.disabled}));\n            var stack1Wrap = g.select('.stack1Wrap')\n                .datum(dataStack1.filter(function(d){return !d.disabled}));\n            var lines2Wrap = g.select('.lines2Wrap')\n                .datum(dataLines2.filter(function(d){return !d.disabled}));\n            var scatters2Wrap = g.select('.scatters2Wrap')\n                .datum(dataScatters2.filter(function(d){return !d.disabled}));\n            var bars2Wrap = g.select('.bars2Wrap')\n                .datum(dataBars2.filter(function(d){return !d.disabled}));\n            var stack2Wrap = g.select('.stack2Wrap')\n                .datum(dataStack2.filter(function(d){return !d.disabled}));\n\n            var extraValue1BarStacked = [];\n            if (bars1.stacked() && dataBars1.length) {\n                var extraValue1BarStacked = dataBars1.filter(function(d){return !d.disabled}).map(function(a){return a.values});\n\n                if (extraValue1BarStacked.length > 0)\n                    extraValue1BarStacked = extraValue1BarStacked.reduce(function(a,b){\n                        return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})\n                    });\n            }\n            if (dataBars1.length) {\n                extraValue1BarStacked.push({x:0, y:0});\n            }\n\n            var extraValue2BarStacked = [];\n            if (bars2.stacked() && dataBars2.length) {\n                var extraValue2BarStacked = dataBars2.filter(function(d){return !d.disabled}).map(function(a){return a.values});\n\n                if (extraValue2BarStacked.length > 0)\n                    extraValue2BarStacked = extraValue2BarStacked.reduce(function(a,b){\n                        return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})\n                    });\n            }\n\n            if (dataBars2.length) {\n              extraValue2BarStacked.push({x:0, y:0});\n            }\n\n            function getStackedAreaYs(series) {\n                return d3.transpose(series).map(function(x) {\n                    return x.map(function(g) {\n                        return g.y;\n                        });\n                    }).map(function(x) {return d3.sum(x);})\n            }\n            \n            yScale1 .domain(yDomain1 || d3.extent(d3.merge(series1).concat(extraValue1BarStacked), function(d) { return d.y } ))\n                .range([0, availableHeight]);\n\n            yScale2 .domain(yDomain2 || d3.extent(d3.merge(series2).concat(extraValue2BarStacked), function(d) { return d.y } ))\n                .range([0, availableHeight]);\n\n            lines1.yDomain(yScale1.domain());\n            scatters1.yDomain(yScale1.domain());\n            if(bars1.stacked()) {\n                var yStackScale1 = yScale1.domain([0, d3.max(getStackedAreaYs(series1))]).range([0, availableHeight]);\n                bars1.yDomain(yStackScale1.domain())\n            } else {\n                bars1.yDomain(yScale1.domain());\n            }\n            stack1.yDomain(yScale1.domain());\n\n            lines2.yDomain(yScale2.domain());\n            scatters2.yDomain(yScale2.domain());\n            if(bars2.stacked()) {\n                var yStackScale2 = yScale2.domain([0, d3.max(getStackedAreaYs(series2))]).range([0, availableHeight]);\n                bars2.yDomain(yStackScale2.domain())\n            } else {\n                bars2.yDomain(yScale2.domain());\n            }\n            stack2.yDomain(yScale2.domain());\n\n            if(dataStack1.length){d3.transition(stack1Wrap).call(stack1);}\n            if(dataStack2.length){d3.transition(stack2Wrap).call(stack2);}\n\n            if(dataBars1.length){d3.transition(bars1Wrap).call(bars1);}\n            if(dataBars2.length){d3.transition(bars2Wrap).call(bars2);}\n\n            if(dataLines1.length){d3.transition(lines1Wrap).call(lines1);}\n            if(dataLines2.length){d3.transition(lines2Wrap).call(lines2);}\n\n            if(dataScatters1.length){d3.transition(scatters1Wrap).call(scatters1);}\n            if(dataScatters2.length){d3.transition(scatters2Wrap).call(scatters2);}\n\n            xAxis\n                ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                .tickSize(-availableHeight, 0);\n\n            g.select('.nv-x.nv-axis')\n                .attr('transform', 'translate(0,' + availableHeight + ')');\n            d3.transition(g.select('.nv-x.nv-axis'))\n                .call(xAxis);\n\n            yAxis1\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n\n            d3.transition(g.select('.nv-y1.nv-axis'))\n                .call(yAxis1);\n\n            yAxis2\n                ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                .tickSize( -availableWidth, 0);\n\n            d3.transition(g.select('.nv-y2.nv-axis'))\n                .call(yAxis2);\n\n            g.select('.nv-y1.nv-axis')\n                .classed('nv-disabled', series1.length ? false : true)\n                .attr('transform', 'translate(' + x.range()[0] + ',0)');\n\n            g.select('.nv-y2.nv-axis')\n                .classed('nv-disabled', series2.length ? false : true)\n                .attr('transform', 'translate(' + x.range()[1] + ',0)');\n\n            legend.dispatch.on('stateChange', function(newState) {\n                chart.update();\n            });\n\n            if(useInteractiveGuideline){\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left:margin.left, top:margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            //============================================================\n            // Event Handling/Dispatching\n            //------------------------------------------------------------\n\n            function mouseover_line(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.value = evt.point.x;\n                evt.series = {\n                    value: evt.point.y,\n                    color: evt.point.color,\n                    key: evt.series.key\n                };\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_scatter(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.value = evt.point.x;\n                evt.series = {\n                    value: evt.point.y,\n                    color: evt.point.color,\n                    key: evt.series.key\n                };\n                tooltip\n                    .duration(100)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_stack(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n                evt.point['x'] = stack1.x()(evt.point);\n                evt.point['y'] = stack1.y()(evt.point);\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n            function mouseover_bar(evt) {\n                var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;\n\n                evt.value = bars1.x()(evt.data);\n                evt['series'] = {\n                    value: bars1.y()(evt.data),\n                    color: evt.color,\n                    key: evt.data.key\n                };\n                tooltip\n                    .duration(0)\n                    .headerFormatter(function(d, i) {\n                    \treturn xAxis.tickFormat()(d, i);\n                    })\n                    .valueFormatter(function(d, i) {\n                        return yaxis.tickFormat()(d, i);\n                    })\n                    .data(evt)\n                    .hidden(false);\n            }\n\n\n\n            function clearHighlights() {\n              for(var i=0, il=charts.length; i < il; i++){\n                var chart = charts[i];\n                try {\n                  chart.clearHighlights();\n                } catch(e){}\n              }\n            }\n\n            function highlightPoint(series, pointIndex, b, pointYValue) {\n\n              var chartMap = {\n                'line': {\n                  'yAxis1': {\n                    chart: lines1,\n                    data: dataLines1\n                  },\n                  'yAxis2': {\n                    chart: lines2,\n                    data: dataLines2\n                  }\n                },\n                'scatter': {\n                  'yAxis1': {\n                    chart: scatters1,\n                    data: dataScatters1\n                  },\n                  'yAxis2': {\n                    chart: scatters2,\n                    data: dataScatters2\n                  }\n                },\n                'bar': {\n                  'yAxis1': {\n                    chart: bars1,\n                    data: dataBars1\n                  },\n                  'yAxis2': {\n                    chart: bars2,\n                    data: dataBars2\n                  }\n                },\n                'area': {\n                  'yAxis1': {\n                    chart: stack1,\n                    data: dataStack1\n                  },\n                  'yAxis2': {\n                    chart: stack2,\n                    data: dataStack2\n                  }\n                }\n              };\n\n              var relevantChart = chartMap[series.type]['yAxis' + series.yAxis].chart;\n              var relevantDatasets = chartMap[series.type]['yAxis' + series.yAxis].data;\n              var seriesIndex = relevantDatasets.reduce(function (seriesIndex, dataSet, i) {\n                return dataSet.key === series.key ? i : seriesIndex;\n              }, 0);\n\n              try {\n                relevantChart.highlightPoint(seriesIndex, pointIndex, b, pointYValue);\n              } catch(e){}\n            }\n\n            if(useInteractiveGuideline){\n                interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                    clearHighlights();\n                    var singlePoint, pointIndex, pointXLocation, allData = [];\n                    data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series, i) {\n                        var extent = x.domain();\n                        var currentValues = series.values.filter(function(d,i) {\n                            return chart.x()(d,i) >= extent[0] && chart.x()(d,i) <= extent[1];\n                        });\n\n                        pointIndex = nv.interactiveBisect(currentValues, e.pointXValue, chart.x());\n                        var point = currentValues[pointIndex];\n                        var pointYValue = chart.y()(point, pointIndex);\n                        if (pointYValue !== null && !isNaN(pointYValue) && !series.noHighlightSeries) {\n                          highlightPoint(series, pointIndex, true);\n                        }\n                        if (point === undefined) return;\n                        if (singlePoint === undefined) singlePoint = point;\n                        if (pointXLocation === undefined) pointXLocation = x(chart.x()(point,pointIndex));\n                        allData.push({\n                            key: series.key,\n                            value: pointYValue,\n                            color: color(series,series.seriesIndex),\n                            data: point,\n                            yAxis: series.yAxis == 2 ? yAxis2 : yAxis1\n                        });\n                    });\n\n                    var defaultValueFormatter = function(d,i) {\n                        var yAxis = allData[i].yAxis;\n                        return d == null ? \"N/A\" : yAxis.tickFormat()(d);\n                    };\n                    interactiveLayer.tooltip\n                        .headerFormatter(function(d, i) {\n                            return xAxis.tickFormat()(d, i);\n                        })\n                        .valueFormatter(interactiveLayer.tooltip.valueFormatter() || defaultValueFormatter)\n                        .data({\n                            value: chart.x()( singlePoint,pointIndex ),\n                            index: pointIndex,\n                            series: allData\n                        })();\n\n                    interactiveLayer.renderGuideLine(pointXLocation);\n                });\n\n                interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                    clearHighlights();\n                });\n            } else {\n                lines1.dispatch.on('elementMouseover.tooltip', mouseover_line);\n                lines2.dispatch.on('elementMouseover.tooltip', mouseover_line);\n                lines1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                lines2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                scatters1.dispatch.on('elementMouseover.tooltip', mouseover_scatter);\n                scatters2.dispatch.on('elementMouseover.tooltip', mouseover_scatter);\n                scatters1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                scatters2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                stack1.dispatch.on('elementMouseover.tooltip', mouseover_stack);\n                stack2.dispatch.on('elementMouseover.tooltip', mouseover_stack);\n                stack1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n                stack2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true)\n                });\n\n                bars1.dispatch.on('elementMouseover.tooltip', mouseover_bar);\n                bars2.dispatch.on('elementMouseover.tooltip', mouseover_bar);\n\n                bars1.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n                bars2.dispatch.on('elementMouseout.tooltip', function(evt) {\n                    tooltip.hidden(true);\n                });\n                bars1.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n                bars2.dispatch.on('elementMousemove.tooltip', function(evt) {\n                    tooltip();\n                });\n            }\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Global getters and setters\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.legend = legend;\n    chart.lines1 = lines1;\n    chart.lines2 = lines2;\n    chart.scatters1 = scatters1;\n    chart.scatters2 = scatters2;\n    chart.bars1 = bars1;\n    chart.bars2 = bars2;\n    chart.stack1 = stack1;\n    chart.stack2 = stack2;\n    chart.xAxis = xAxis;\n    chart.yAxis1 = yAxis1;\n    chart.yAxis2 = yAxis2;\n    chart.tooltip = tooltip;\n    chart.interactiveLayer = interactiveLayer;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        xScale: {get: function(){return x;}, set: function(_){ x = _; xAxis.scale(x); }},\n        yDomain1:      {get: function(){return yDomain1;}, set: function(_){yDomain1=_;}},\n        yDomain2:    {get: function(){return yDomain2;}, set: function(_){yDomain2=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        interpolate:    {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n        legendRightAxisHint:    {get: function(){return legendRightAxisHint;}, set: function(_){legendRightAxisHint=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        x: {get: function(){return getX;}, set: function(_){\n            getX = _;\n            lines1.x(_);\n            lines2.x(_);\n            scatters1.x(_);\n            scatters2.x(_);\n            bars1.x(_);\n            bars2.x(_);\n            stack1.x(_);\n            stack2.x(_);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY = _;\n            lines1.y(_);\n            lines2.y(_);\n            scatters1.y(_);\n            scatters2.y(_);\n            stack1.y(_);\n            stack2.y(_);\n            bars1.y(_);\n            bars2.y(_);\n        }},\n        useVoronoi: {get: function(){return useVoronoi;}, set: function(_){\n            useVoronoi=_;\n            lines1.useVoronoi(_);\n            lines2.useVoronoi(_);\n            stack1.useVoronoi(_);\n            stack2.useVoronoi(_);\n        }},\n\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = _;\n            if (useInteractiveGuideline) {\n                lines1.interactive(false);\n                lines1.useVoronoi(false);\n                lines2.interactive(false);\n                lines2.useVoronoi(false);\n                stack1.interactive(false);\n                stack1.useVoronoi(false);\n                stack2.interactive(false);\n                stack2.useVoronoi(false);\n                scatters1.interactive(false);\n                scatters2.interactive(false);\n            }\n        }},\n\n        duration: {get: function(){return duration;}, set: function(_) {\n            duration = _;\n            [lines1, lines2, stack1, stack2, scatters1, scatters2, xAxis, yAxis1, yAxis2].forEach(function(model){\n              model.duration(duration);\n            });\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/ohlcBar.js",
    "content": "\nnv.models.ohlcBar = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = null\n        , height = null\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , getOpen = function(d) { return d.open }\n        , getClose = function(d) { return d.close }\n        , getHigh = function(d) { return d.high }\n        , getLow = function(d) { return d.low }\n        , forceX = []\n        , forceY = []\n        , padData     = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , clipEdge = true\n        , color = nv.utils.defaultColor()\n        , interactive = false\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd', 'chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            // ohlc bar width.\n            var w = (availableWidth / data[0].values.length) * .9;\n\n            // Setup Scales\n            x.domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));\n\n            if (padData)\n                x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [5 + w/2, availableWidth - w/2 - 5]);\n\n            y.domain(yDomain || [\n                    d3.min(data[0].values.map(getLow).concat(forceY)),\n                    d3.max(data[0].values.map(getHigh).concat(forceY))\n                ]\n            ).range(yRange || [availableHeight, 0]);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            // Setup containers and skeleton of chart\n            var wrap = d3.select(this).selectAll('g.nv-wrap.nv-ohlcBar').data([data[0].values]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-ohlcBar');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-ticks');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            container\n                .on('click', function(d,i) {\n                    dispatch.chartClick({\n                        data: d,\n                        index: i,\n                        pos: d3.event,\n                        id: id\n                    });\n                });\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-chart-clip-path-' + id)\n                .append('rect');\n\n            wrap.select('#nv-chart-clip-path-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g   .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');\n\n            var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')\n                .data(function(d) { return d });\n            ticks.exit().remove();\n\n            ticks.enter().append('path')\n                .attr('class', function(d,i,j) { return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i })\n                .attr('d', function(d,i) {\n                    return 'm0,0l0,'\n                        + (y(getOpen(d,i))\n                            - y(getHigh(d,i)))\n                        + 'l'\n                        + (-w/2)\n                        + ',0l'\n                        + (w/2)\n                        + ',0l0,'\n                        + (y(getLow(d,i)) - y(getOpen(d,i)))\n                        + 'l0,'\n                        + (y(getClose(d,i))\n                            - y(getLow(d,i)))\n                        + 'l'\n                        + (w/2)\n                        + ',0l'\n                        + (-w/2)\n                        + ',0z';\n                })\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })\n                .attr('fill', function(d,i) { return color[0]; })\n                .attr('stroke', function(d,i) { return color[0]; })\n                .attr('x', 0 )\n                .attr('y', function(d,i) {  return y(Math.max(0, getY(d,i))) })\n                .attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0)) });\n\n            // the bar colors are controlled by CSS currently\n            ticks.attr('class', function(d,i,j) {\n                return (getOpen(d,i) > getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + ' nv-tick-' + j + '-' + i;\n            });\n\n            d3.transition(ticks)\n                .attr('transform', function(d,i) { return 'translate(' + x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })\n                .attr('d', function(d,i) {\n                    var w = (availableWidth / data[0].values.length) * .9;\n                    return 'm0,0l0,'\n                        + (y(getOpen(d,i))\n                            - y(getHigh(d,i)))\n                        + 'l'\n                        + (-w/2)\n                        + ',0l'\n                        + (w/2)\n                        + ',0l0,'\n                        + (y(getLow(d,i))\n                            - y(getOpen(d,i)))\n                        + 'l0,'\n                        + (y(getClose(d,i))\n                            - y(getLow(d,i)))\n                        + 'l'\n                        + (w/2)\n                        + ',0l'\n                        + (-w/2)\n                        + ',0z';\n                });\n        });\n\n        return chart;\n    }\n\n\n    //Create methods to allow outside functions to highlight a specific bar.\n    chart.highlightPoint = function(pointIndex, isHoverOver) {\n        chart.clearHighlights();\n        container.select(\".nv-ohlcBar .nv-tick-0-\" + pointIndex)\n            .classed(\"hover\", isHoverOver)\n        ;\n    };\n\n    chart.clearHighlights = function() {\n        container.select(\".nv-ohlcBar .nv-tick.hover\")\n            .classed(\"hover\", false)\n        ;\n    };\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:    {get: function(){return width;}, set: function(_){width=_;}},\n        height:   {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:   {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:   {get: function(){return y;}, set: function(_){y=_;}},\n        xDomain:  {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:  {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:   {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:   {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        forceX:   {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:   {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        padData:  {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        id:       {get: function(){return id;}, set: function(_){id=_;}},\n        interactive: {get: function(){return interactive;}, set: function(_){interactive=_;}},\n\n        x:     {get: function(){return getX;}, set: function(_){getX=_;}},\n        y:     {get: function(){return getY;}, set: function(_){getY=_;}},\n        open:  {get: function(){return getOpen();}, set: function(_){getOpen=_;}},\n        close: {get: function(){return getClose();}, set: function(_){getClose=_;}},\n        high:  {get: function(){return getHigh;}, set: function(_){getHigh=_;}},\n        low:   {get: function(){return getLow;}, set: function(_){getLow=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/parallelCoordinates.js",
    "content": "// Code adapted from Jason Davies' \"Parallel Coordinates\"\n// http://bl.ocks.org/jasondavies/1341281\nnv.models.parallelCoordinates = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 30, right: 0, bottom: 10, left: 0}\n        , width = null\n        , height = null\n        , availableWidth = null\n        , availableHeight = null\n        , x = d3.scale.ordinal()\n        , y = {}\n        , undefinedValuesLabel = \"undefined values\"\n        , dimensionData = []\n        , enabledDimensions = []\n        , dimensionNames = []\n        , displayBrush = true\n        , color = nv.utils.defaultColor()\n        , filters = []\n        , active = []\n        , dragging = []\n        , axisWithUndefinedValues = []\n        , lineTension = 1\n        , foreground\n        , background\n        , dimensions\n        , line = d3.svg.line()\n        , axis = d3.svg.axis()\n        , dispatch = d3.dispatch('brushstart', 'brush', 'brushEnd', 'dimensionsOrder', \"stateChange\", 'elementClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd', 'activeChanged')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var container = d3.select(this);\n            availableWidth = nv.utils.availableWidth(width, container, margin);\n            availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n           //Convert old data to new format (name, values)\n            if (data[0].values === undefined) {\n                var newData = [];\n                data.forEach(function (d) {\n                        var val = {};\n                        var key = Object.keys(d);\n                        key.forEach(function (k) { if (k !== \"name\") val[k] = d[k] });\n                        newData.push({ key: d.name, values: val });\n                });\n                data = newData;\n            }\n\n            var dataValues = data.map(function (d) {return d.values});\n            if (active.length === 0) {\n                active = data;\n            }; //set all active before first brush call\n            \n            dimensionNames = dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; }).map(function (d) { return d.key });\n            enabledDimensions = dimensionData.filter(function (d) { return !d.disabled; });\n            \n            // Setup Scales\n            x.rangePoints([0, availableWidth], 1).domain(enabledDimensions.map(function (d) { return d.key; }));\n\n            //Set as true if all values on an axis are missing.\n            // Extract the list of dimensions and create a scale for each.\n            var oldDomainMaxValue = {};\n            var displayMissingValuesline = false;\n            var currentTicks = [];\n            \n            dimensionNames.forEach(function(d) {\n                var extent = d3.extent(dataValues, function (p) { return +p[d]; });\n                var min = extent[0];\n                var max = extent[1];\n                var onlyUndefinedValues = false;\n                //If there is no values to display on an axis, set the extent to 0\n                if (isNaN(min) || isNaN(max)) {\n                    onlyUndefinedValues = true;\n                    min = 0;\n                    max = 0;\n                }\n                //Scale axis if there is only one value\n                if (min === max) {\n                    min = min - 1;\n                    max = max + 1;\n                }\n                var f = filters.filter(function (k) { return k.dimension == d; });\n                if (f.length !== 0) {\n                    //If there is only NaN values, keep the existing domain.\n                    if (onlyUndefinedValues) {\n                        min = y[d].domain()[0];\n                        max = y[d].domain()[1];\n                    }\n                        //If the brush extent is > max (< min), keep the extent value.\n                    else if (!f[0].hasOnlyNaN && displayBrush) {\n                        min = min > f[0].extent[0] ? f[0].extent[0] : min;\n                        max = max < f[0].extent[1] ? f[0].extent[1] : max;\n                    }\n                        //If there is NaN values brushed be sure the brush extent is on the domain.\n                    else if (f[0].hasNaN) {\n                        max = max < f[0].extent[1] ? f[0].extent[1] : max;\n                        oldDomainMaxValue[d] = y[d].domain()[1];\n                        displayMissingValuesline = true;\n                    }\n                }\n                //Use 90% of (availableHeight - 12) for the axis range, 12 reprensenting the space necessary to display \"undefined values\" text.\n                //The remaining 10% are used to display the missingValue line.\n                y[d] = d3.scale.linear()\n                    .domain([min, max])\n                    .range([(availableHeight - 12) * 0.9, 0]);\n\n                axisWithUndefinedValues = [];\n                y[d].brush = d3.svg.brush().y(y[d]).on('brushstart', brushstart).on('brush', brush).on('brushend', brushend);\n            });\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-parallelCoordinates').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-parallelCoordinates');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates background');\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates foreground');\n            gEnter.append('g').attr('class', 'nv-parallelCoordinates missingValuesline');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            line.interpolate('cardinal').tension(lineTension);\n            axis.orient('left');\n            var axisDrag = d3.behavior.drag()\n                        .on('dragstart', dragStart)\n                        .on('drag', dragMove)\n                        .on('dragend', dragEnd);\n\n            //Add missing value line at the bottom of the chart\n            var missingValuesline, missingValueslineText;\n            var step = x.range()[1] - x.range()[0];\n            step = isNaN(step) ? x.range()[0] : step;\n            if (!isNaN(step)) {\n                var lineData = [0 + step / 2, availableHeight - 12, availableWidth - step / 2, availableHeight - 12];\n                missingValuesline = wrap.select('.missingValuesline').selectAll('line').data([lineData]);\n                missingValuesline.enter().append('line');\n                missingValuesline.exit().remove();\n                missingValuesline.attr(\"x1\", function(d) { return d[0]; })\n                        .attr(\"y1\", function(d) { return d[1]; })\n                        .attr(\"x2\", function(d) { return d[2]; })\n                        .attr(\"y2\", function(d) { return d[3]; });\n    \n                //Add the text \"undefined values\" under the missing value line\n                missingValueslineText = wrap.select('.missingValuesline').selectAll('text').data([undefinedValuesLabel]);\n                missingValueslineText.append('text').data([undefinedValuesLabel]);\n                missingValueslineText.enter().append('text');\n                missingValueslineText.exit().remove();\n                missingValueslineText.attr(\"y\", availableHeight)\n                        //To have the text right align with the missingValues line, substract 92 representing the text size.\n                        .attr(\"x\", availableWidth - 92 - step / 2)\n                        .text(function(d) { return d; });\n            }\n            // Add grey background lines for context.\n            background = wrap.select('.background').selectAll('path').data(data);\n            background.enter().append('path');\n            background.exit().remove();\n            background.attr('d', path);\n\n            // Add blue foreground lines for focus.\n            foreground = wrap.select('.foreground').selectAll('path').data(data);\n            foreground.enter().append('path')\n            foreground.exit().remove();\n            foreground.attr('d', path)\n                .style(\"stroke-width\", function (d, i) {\n                if (isNaN(d.strokeWidth)) { d.strokeWidth = 1;} return d.strokeWidth;})\n                .attr('stroke', function (d, i) { return d.color || color(d, i); });\n            foreground.on(\"mouseover\", function (d, i) {\n                d3.select(this).classed('hover', true).style(\"stroke-width\", d.strokeWidth + 2 + \"px\").style(\"stroke-opacity\", 1);\n                dispatch.elementMouseover({\n                    label: d.name,\n                    color: d.color || color(d, i),\n                    values: d.values,\n                    dimensions: enabledDimensions\n                });\n\n            });\n            foreground.on(\"mouseout\", function (d, i) {\n                d3.select(this).classed('hover', false).style(\"stroke-width\", d.strokeWidth + \"px\").style(\"stroke-opacity\", 0.7);\n                dispatch.elementMouseout({\n                    label: d.name,\n                    index: i\n                });\n            });\n            foreground.on('mousemove', function (d, i) {\n                dispatch.elementMousemove();\n            });\n            foreground.on('click', function (d) {\n                dispatch.elementClick({\n                    id: d.id\n                });\n            });\n            // Add a group element for each dimension.\n            dimensions = g.selectAll('.dimension').data(enabledDimensions);\n            var dimensionsEnter = dimensions.enter().append('g').attr('class', 'nv-parallelCoordinates dimension');\n\n            dimensions.attr('transform', function(d) { return 'translate(' + x(d.key) + ',0)'; });\n            dimensionsEnter.append('g').attr('class', 'nv-axis');\n\n            // Add an axis and title.\n            dimensionsEnter.append('text')\n                .attr('class', 'nv-label')\n                .style(\"cursor\", \"move\")\n                .attr('dy', '-1em')\n                .attr('text-anchor', 'middle')\n                .on(\"mouseover\", function(d, i) {\n                    dispatch.elementMouseover({\n                        label: d.tooltip || d.key,\n                        color: d.color \n                    });\n                })\n                .on(\"mouseout\", function(d, i) {\n                    dispatch.elementMouseout({\n                        label: d.tooltip\n                    });\n                })\n                .on('mousemove', function (d, i) {\n                    dispatch.elementMousemove();\n                })\n                .call(axisDrag);\n\n            dimensionsEnter.append('g').attr('class', 'nv-brushBackground');\n            dimensions.exit().remove();\n            dimensions.select('.nv-label').text(function (d) { return d.key });\n\n            // Add and store a brush for each axis.\n            restoreBrush(displayBrush);\n\n            var actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); }),\n                    extents = actives.map(function (p) { return y[p].brush.extent(); });\n            var formerActive = active.slice(0);\n\n            //Restore active values\n            active = [];\n            foreground.style(\"display\", function (d) {\n                var isActive = actives.every(function (p, i) {\n                    if ((isNaN(d.values[p]) || isNaN(parseFloat(d.values[p]))) && extents[i][0] == y[p].brush.y().domain()[0]) {\n                        return true;\n                    }\n                    return (extents[i][0] <= d.values[p] && d.values[p] <= extents[i][1]) && !isNaN(parseFloat(d.values[p]));\n                });\n                if (isActive)\n                    active.push(d);\n                return !isActive ? \"none\" : null;\n\n            });\n\n            if (filters.length > 0 || !nv.utils.arrayEquals(active, formerActive)) {\n               dispatch.activeChanged(active);\n            }\n\n            // Returns the path for a given data point.\n            function path(d) {\n                return line(enabledDimensions.map(function (p) {\n                    //If value if missing, put the value on the missing value line\n                    if (isNaN(d.values[p.key]) || isNaN(parseFloat(d.values[p.key])) || displayMissingValuesline) {\n                        var domain = y[p.key].domain();\n                        var range = y[p.key].range();\n                        var min = domain[0] - (domain[1] - domain[0]) / 9;\n\n                        //If it's not already the case, allow brush to select undefined values\n                        if (axisWithUndefinedValues.indexOf(p.key) < 0) {\n\n                            var newscale = d3.scale.linear().domain([min, domain[1]]).range([availableHeight - 12, range[1]]);\n                            y[p.key].brush.y(newscale);\n                            axisWithUndefinedValues.push(p.key);\n                        }\n                        if (isNaN(d.values[p.key]) || isNaN(parseFloat(d.values[p.key]))) {\n                            return [x(p.key), y[p.key](min)];\n                        }\n                    }\n\n                    //If parallelCoordinate contain missing values show the missing values line otherwise, hide it.\n                    if (missingValuesline !== undefined) {\n                        if (axisWithUndefinedValues.length > 0 || displayMissingValuesline) {\n                            missingValuesline.style(\"display\", \"inline\");\n                            missingValueslineText.style(\"display\", \"inline\");\n                        } else {\n                            missingValuesline.style(\"display\", \"none\");\n                            missingValueslineText.style(\"display\", \"none\");\n                        }\n                    }\n                    return [x(p.key), y[p.key](d.values[p.key])];\n                }));\n            }\n\n            function restoreBrush(visible) {\n                filters.forEach(function (f) {\n                    //If filter brushed NaN values, keep the brush on the bottom of the axis.\n                    var brushDomain = y[f.dimension].brush.y().domain();\n                    if (f.hasOnlyNaN) {\n                        f.extent[1] = (y[f.dimension].domain()[1] - brushDomain[0]) * (f.extent[1] - f.extent[0]) / (oldDomainMaxValue[f.dimension] - f.extent[0]) + brushDomain[0];\n                    }\n                    if (f.hasNaN) {\n                        f.extent[0] = brushDomain[0];\n                    }\n                    if (visible)\n                        y[f.dimension].brush.extent(f.extent);\n                });\n                \n                dimensions.select('.nv-brushBackground')\n                    .each(function (d) {\n                        d3.select(this).call(y[d.key].brush);\n\n                    })\n                    .selectAll('rect')\n                    .attr('x', -8)\n                    .attr('width', 16);\n                \n                updateTicks();\n            }\n            \n            // Handles a brush event, toggling the display of foreground lines.\n            function brushstart() {\n                //If brush aren't visible, show it before brushing again.\n                if (displayBrush === false) {\n                    displayBrush = true;\n                    restoreBrush(true);\n                }\n            }\n            \n            // Handles a brush event, toggling the display of foreground lines.\n            function brush() {\n                actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); });\n                extents = actives.map(function(p) { return y[p].brush.extent(); });\n\n                filters = []; //erase current filters\n                actives.forEach(function(d,i) {\n                    filters[i] = {\n                        dimension: d,\n                        extent: extents[i],\n                        hasNaN: false,\n                        hasOnlyNaN: false\n                    }\n                });\n\n                active = []; //erase current active list\n                foreground.style('display', function(d) {\n                    var isActive = actives.every(function(p, i) {\n                        if ((isNaN(d.values[p]) || isNaN(parseFloat(d.values[p]))) && extents[i][0] == y[p].brush.y().domain()[0]) return true;\n                        return (extents[i][0] <= d.values[p] && d.values[p] <= extents[i][1]) && !isNaN(parseFloat(d.values[p]));\n                    });\n                    if (isActive) active.push(d);\n                    return isActive ? null : 'none';\n                });\n                \n                updateTicks();\n                \n                dispatch.brush({\n                    filters: filters,\n                    active: active\n                });\n            }\n            function brushend() {\n                var hasActiveBrush = actives.length > 0 ? true : false;\n                filters.forEach(function (f) {\n                    if (f.extent[0] === y[f.dimension].brush.y().domain()[0] && axisWithUndefinedValues.indexOf(f.dimension) >= 0)\n                        f.hasNaN = true;\n                    if (f.extent[1] < y[f.dimension].domain()[0])\n                        f.hasOnlyNaN = true;\n                });\n                dispatch.brushEnd(active, hasActiveBrush);\n            }           \n            function updateTicks() {\n                dimensions.select('.nv-axis')\n                    .each(function (d, i) {\n                        var f = filters.filter(function (k) { return k.dimension == d.key; });\n                        currentTicks[d.key] = y[d.key].domain();\n                        \n                        //If brush are available, display brush extent\n                        if (f.length != 0 && displayBrush)\n                        {\n                            currentTicks[d.key] = [];\n                            if (f[0].extent[1] > y[d.key].domain()[0]) \n                                currentTicks[d.key] = [f[0].extent[1]];\n                            if (f[0].extent[0] >= y[d.key].domain()[0])\n                                currentTicks[d.key].push(f[0].extent[0]);    \n                        }\n                            \n                        d3.select(this).call(axis.scale(y[d.key]).tickFormat(d.format).tickValues(currentTicks[d.key]));\n                });\n            }\n            function dragStart(d) {\n                dragging[d.key] = this.parentNode.__origin__ = x(d.key);\n                background.attr(\"visibility\", \"hidden\");\n            }\n            function dragMove(d) {\n                dragging[d.key] = Math.min(availableWidth, Math.max(0, this.parentNode.__origin__ += d3.event.x));\n                foreground.attr(\"d\", path);\n                enabledDimensions.sort(function (a, b) { return dimensionPosition(a.key) - dimensionPosition(b.key); });\n                enabledDimensions.forEach(function (d, i) { return d.currentPosition = i; });\n                x.domain(enabledDimensions.map(function (d) { return d.key; }));\n                dimensions.attr(\"transform\", function(d) { return \"translate(\" + dimensionPosition(d.key) + \")\"; });\n            }\n            function dragEnd(d, i) {\n                delete this.parentNode.__origin__;\n                delete dragging[d.key];\n                d3.select(this.parentNode).attr(\"transform\", \"translate(\" + x(d.key) + \")\");\n                foreground\n                  .attr(\"d\", path);\n                background\n                  .attr(\"d\", path)\n                  .attr(\"visibility\", null);\n\n                dispatch.dimensionsOrder(enabledDimensions);\n            }\n            function dimensionPosition(d) {\n                var v = dragging[d];\n                return v == null ? x(d) : v;\n            }\n        });\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:         {get: function(){return width;},           set: function(_){width= _;}},\n        height:        {get: function(){return height;},          set: function(_){height= _;}},\n        dimensionData: { get: function () { return dimensionData; }, set: function (_) { dimensionData = _; } },\n        displayBrush: { get: function () { return displayBrush; }, set: function (_) { displayBrush = _; } },\n        filters: { get: function () { return filters; }, set: function (_) { filters = _; } },\n        active: { get: function () { return active; }, set: function (_) { active = _; } },\n        lineTension:   {get: function(){return lineTension;},     set: function(_){lineTension = _;}},\n        undefinedValuesLabel : {get: function(){return undefinedValuesLabel;}, set: function(_){undefinedValuesLabel=_;}},\n        \n        // deprecated options\n        dimensions: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensions', 'use dimensionData instead');\n            if (dimensionData.length === 0) {\n                _.forEach(function (k) { dimensionData.push({ key: k }) })\n            } else {\n                _.forEach(function (k, i) { dimensionData[i].key= k })\n            }\n        }},\n        dimensionNames: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensionNames', 'use dimensionData instead');\n            dimensionNames = [];\n            if (dimensionData.length === 0) {\n                _.forEach(function (k) { dimensionData.push({ key: k }) })\n            } else {\n                _.forEach(function (k, i) { dimensionData[i].key = k })\n            }\n \n        }},\n        dimensionFormats: {get: function () { return dimensionData.map(function (d) { return d.format }); }, set: function (_) {\n            // deprecated after 1.8.1\n            nv.deprecated('dimensionFormats', 'use dimensionData instead');\n            if (dimensionData.length === 0) {\n                _.forEach(function (f) { dimensionData.push({ format: f }) })\n            } else {\n                _.forEach(function (f, i) { dimensionData[i].format = f })\n            }\n\n        }},\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    =  _.top    !== undefined ? _.top    : margin.top;\n            margin.right  =  _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom =  _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   =  _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/parallelCoordinatesChart.js",
    "content": "nv.models.parallelCoordinatesChart = function () {\n        \"use strict\";\n        //============================================================\n        // Public Variables with Default Settings\n        //------------------------------------------------------------\n\n        var parallelCoordinates = nv.models.parallelCoordinates()\n        var legend = nv.models.legend()\n        var tooltip = nv.models.tooltip();\n        var dimensionTooltip = nv.models.tooltip();\n\n        var margin = { top: 0, right: 0, bottom: 0, left: 0 }\n        , marginTop = null\n        , width = null\n        , height = null\n        , showLegend = true\n        , color = nv.utils.defaultColor()\n        , state = nv.utils.state()\n        , dimensionData = []\n        , displayBrush = true\n        , defaultState = null\n        , noData = null\n        , nanValue = \"undefined\"\n        , dispatch = d3.dispatch('dimensionsOrder', 'brushEnd', 'stateChange', 'changeState', 'renderEnd')\n        , controlWidth = function () { return showControls ? 180 : 0 }\n        ;\n\n\t    //============================================================\n\n\t\t//============================================================\n        // Private Variables\n        //------------------------------------------------------------\n\n        var renderWatch = nv.utils.renderWatch(dispatch);\n\n        var stateGetter = function(data) {\n            return function() {\n                return {\n                    active: data.map(function(d) { return !d.disabled })\n                };\n            }\n        };\n\n        var stateSetter = function(data) {\n            return function(state) {\n                if(state.active !== undefined) {\n                    data.forEach(function(series, i) {\n                        series.disabled = !state.active[i];\n                    });\n                }\n            }\n        };\n\n        tooltip.contentGenerator(function(data) {\n            var str = '<table><thead><tr><td class=\"legend-color-guide\"><div style=\"background-color:' + data.color + '\"></div></td><td><strong>' + data.key + '</strong></td></tr></thead>';\n            if(data.series.length !== 0)\n            {\n                str = str + '<tbody><tr><td height =\"10px\"></td></tr>';\n                data.series.forEach(function(d){\n                    str = str + '<tr><td class=\"legend-color-guide\"><div style=\"background-color:' + d.color + '\"></div></td><td class=\"key\">' + d.key + '</td><td class=\"value\">' + d.value + '</td></tr>';\n                });\n                str = str + '</tbody>';\n            }\n            str = str + '</table>';\n            return str;\n        });\n\n        //============================================================\n        // Chart function\n        //------------------------------------------------------------\n\n        function chart(selection) {\n            renderWatch.reset();\n            renderWatch.models(parallelCoordinates);\n\n            selection.each(function(data) {\n                var container = d3.select(this);\n                nv.utils.initSVG(container);\n\n                var that = this;\n\n                var availableWidth = nv.utils.availableWidth(width, container, margin),\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n\n                chart.update = function() { container.call(chart); };\n                chart.container = this;\n\n                state.setter(stateSetter(dimensionData), chart.update)\n                    .getter(stateGetter(dimensionData))\n                    .update();\n\n                //set state.disabled\n                state.disabled = dimensionData.map(function (d) { return !!d.disabled });\n\n                //Keep dimensions position in memory\n                dimensionData = dimensionData.map(function (d) {d.disabled = !!d.disabled; return d});\n                dimensionData.forEach(function (d, i) {\n                    d.originalPosition = isNaN(d.originalPosition) ? i : d.originalPosition;\n                    d.currentPosition = isNaN(d.currentPosition) ? i : d.currentPosition;\n                });\n\n               if (!defaultState) {\n                    var key;\n                    defaultState = {};\n                    for(key in state) {\n                        if(state[key] instanceof Array)\n                            defaultState[key] = state[key].slice(0);\n                        else\n                            defaultState[key] = state[key];\n                    }\n                }\n\n                // Display No Data message if there's nothing to show.\n                if(!data || !data.length) {\n                    nv.utils.noData(chart, container);\n                    return chart;\n                } else {\n                    container.selectAll('.nv-noData').remove();\n                }\n\n                //------------------------------------------------------------\n                // Setup containers and skeleton of chart\n\n                var wrap = container.selectAll('g.nv-wrap.nv-parallelCoordinatesChart').data([data]);\n                var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-parallelCoordinatesChart').append('g');\n\n                var g = wrap.select('g');\n\n                gEnter.append('g').attr('class', 'nv-parallelCoordinatesWrap');\n                gEnter.append('g').attr('class', 'nv-legendWrap');\n\n                g.select(\"rect\")\n                    .attr(\"width\", availableWidth)\n                    .attr(\"height\", (availableHeight > 0) ? availableHeight : 0);\n\n                // Legend\n                if (!showLegend) {\n                    g.select('.nv-legendWrap').selectAll('*').remove();\n                } else {\n                    legend.width(availableWidth)\n                        .color(function (d) { return \"rgb(188,190,192)\"; });\n\n                    g.select('.nv-legendWrap')\n                        .datum(dimensionData.sort(function (a, b) { return a.originalPosition - b.originalPosition; }))\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n                    wrap.select('.nv-legendWrap')\n                       .attr('transform', 'translate( 0 ,' + (-margin.top) + ')');\n                }\n                wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n                // Main Chart Component(s)\n                parallelCoordinates\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .dimensionData(dimensionData)\n                    .displayBrush(displayBrush);\n\n\t\t        var parallelCoordinatesWrap = g.select('.nv-parallelCoordinatesWrap ')\n                  .datum(data);\n\n\t\t        parallelCoordinatesWrap.transition().call(parallelCoordinates);\n\n\t\t\t\t//============================================================\n                // Event Handling/Dispatching (in chart's scope)\n                //------------------------------------------------------------\n                //Display reset brush button\n\t\t        parallelCoordinates.dispatch.on('brushEnd', function (active, hasActiveBrush) {\n\t\t            if (hasActiveBrush) {\n\t\t                displayBrush = true;\n\t\t                dispatch.brushEnd(active);\n\t\t            } else {\n\n\t\t                displayBrush = false;\n\t\t            }\n\t\t        });\n\n\t\t        legend.dispatch.on('stateChange', function(newState) {\n\t\t            for(var key in newState) {\n\t\t                state[key] = newState[key];\n\t\t            }\n\t\t            dispatch.stateChange(state);\n\t\t            chart.update();\n\t\t        });\n\n                //Update dimensions order and display reset sorting button\n\t\t        parallelCoordinates.dispatch.on('dimensionsOrder', function (e) {\n\t\t            dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; });\n\t\t            var isSorted = false;\n\t\t            dimensionData.forEach(function (d, i) {\n\t\t                d.currentPosition = i;\n\t\t                if (d.currentPosition !== d.originalPosition)\n\t\t                    isSorted = true;\n\t\t            });\n\t\t            dispatch.dimensionsOrder(dimensionData, isSorted);\n\t\t        });\n\n\t\t\t\t// Update chart from a state object passed to event handler\n                dispatch.on('changeState', function (e) {\n\n                    if (typeof e.disabled !== 'undefined') {\n                        dimensionData.forEach(function (series, i) {\n                            series.disabled = e.disabled[i];\n                        });\n                        state.disabled = e.disabled;\n                    }\n                    chart.update();\n                });\n            });\n\n            renderWatch.renderEnd('parraleleCoordinateChart immediate');\n            return chart;\n        }\n\n\t\t//============================================================\n        // Event Handling/Dispatching (out of chart's scope)\n        //------------------------------------------------------------\n\n        parallelCoordinates.dispatch.on('elementMouseover.tooltip', function (evt) {\n            var tp = {\n                key: evt.label,\n                color: evt.color,\n                series: []\n             }\n            if(evt.values){\n                Object.keys(evt.values).forEach(function (d) {\n                    var dim = evt.dimensions.filter(function (dd) {return dd.key === d;})[0];\n                    if(dim){\n                        var v;\n                        if (isNaN(evt.values[d]) || isNaN(parseFloat(evt.values[d]))) {\n                            v = nanValue;\n                        } else {\n                            v = dim.format(evt.values[d]);\n                        }\n                        tp.series.push({ idx: dim.currentPosition, key: d, value: v, color: dim.color });\n                    }\n                });\n                tp.series.sort(function(a,b) {return a.idx - b.idx});\n             }\n            tooltip.data(tp).hidden(false);\n        });\n\n        parallelCoordinates.dispatch.on('elementMouseout.tooltip', function(evt) {\n            tooltip.hidden(true)\n        });\n\n        parallelCoordinates.dispatch.on('elementMousemove.tooltip', function () {\n            tooltip();\n        });\n\t\t //============================================================\n        // Expose Public Variables\n        //------------------------------------------------------------\n\n\t\t// expose chart's sub-components\n        chart.dispatch = dispatch;\n        chart.parallelCoordinates = parallelCoordinates;\n        chart.legend = legend;\n        chart.tooltip = tooltip;\n        chart.options = nv.utils.optionsFunc.bind(chart);\n\n        chart._options = Object.create({}, {\n            // simple options, just get/set the necessary values\n            width: { get: function () { return width; }, set: function (_) { width = _; } },\n            height: { get: function () { return height; }, set: function (_) { height = _; } },\n            showLegend: { get: function () { return showLegend; }, set: function (_) { showLegend = _; } },\n            defaultState: { get: function () { return defaultState; }, set: function (_) { defaultState = _; } },\n            dimensionData: { get: function () { return dimensionData; }, set: function (_) { dimensionData = _; } },\n            displayBrush: { get: function () { return displayBrush; }, set: function (_) { displayBrush = _; } },\n            noData: { get: function () { return noData; }, set: function (_) { noData = _; } },\n            nanValue: { get: function () { return nanValue; }, set: function (_) { nanValue = _; } },\n\n            // options that require extra logic in the setter\n            margin: {\n                get: function () { return margin; },\n                set: function (_) {\n                    if (_.top !== undefined) {\n                        margin.top = _.top;\n                        marginTop = _.top;\n                    }\n                    margin.right = _.right !== undefined ? _.right : margin.right;\n                    margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n                    margin.left = _.left !== undefined ? _.left : margin.left;\n                }\n            },\n            color: {get: function(){return color;}, set: function(_){\n                    color = nv.utils.getColor(_);\n                    legend.color(color);\n                    parallelCoordinates.color(color);\n                }}\n        });\n\n        nv.utils.inheritOptions(chart, parallelCoordinates);\n        nv.utils.initOptions(chart);\n\n        return chart;\n    };\n"
  },
  {
    "path": "src/models/pie.js",
    "content": "nv.models.pie = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 500\n        , height = 500\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , color = nv.utils.defaultColor()\n        , valueFormat = d3.format(',.2f')\n        , showLabels = true\n        , labelsOutside = false\n        , labelType = \"key\"\n        , labelThreshold = .02 //if slice percentage is under this, don't show label\n        , hideOverlapLabels = false //Hide labels that don't fit in slice\n        , donut = false\n        , title = false\n        , growOnHover = true\n        , titleOffset = 0\n        , labelSunbeamLayout = false\n        , startAngle = false\n        , padAngle = false\n        , endAngle = false\n        , cornerRadius = 0\n        , donutRatio = 0.5\n        , duration = 250\n        , arcsRadius = []\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd')\n        ;\n\n    var arcs = [];\n    var arcsOver = [];\n\n    //============================================================\n    // chart function\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right\n                , availableHeight = height - margin.top - margin.bottom\n                , radius = Math.min(availableWidth, availableHeight) / 2\n                , arcsRadiusOuter = []\n                , arcsRadiusInner = []\n                ;\n\n            container = d3.select(this)\n            if (arcsRadius.length === 0) {\n                var outer = radius - radius / 10;\n                var inner = donutRatio * radius;\n                for (var i = 0; i < data[0].length; i++) {\n                    arcsRadiusOuter.push(outer);\n                    arcsRadiusInner.push(inner);\n                }\n            } else {\n                if(growOnHover){\n                    arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer / 10) * radius; });\n                    arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner / 10) * radius; });\n                    donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner / 10); }));\n                } else {\n                    arcsRadiusOuter = arcsRadius.map(function (d) { return d.outer * radius; });\n                    arcsRadiusInner = arcsRadius.map(function (d) { return d.inner * radius; });\n                    donutRatio = d3.min(arcsRadius.map(function (d) { return d.inner; }));\n                }\n            }\n            nv.utils.initSVG(container);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('.nv-wrap.nv-pie').data(data);\n            var wrapEnter = wrap.enter().append('g').attr('class','nvd3 nv-wrap nv-pie nv-chart-' + id);\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n            var g_pie = gEnter.append('g').attr('class', 'nv-pie');\n            gEnter.append('g').attr('class', 'nv-pieLabels');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n            g.select('.nv-pie').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');\n            g.select('.nv-pieLabels').attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');\n\n            //\n            container.on('click', function(d,i) {\n                dispatch.chartClick({\n                    data: d,\n                    index: i,\n                    pos: d3.event,\n                    id: id\n                });\n            });\n\n            arcs = [];\n            arcsOver = [];\n            for (var i = 0; i < data[0].length; i++) {\n\n                var arc = d3.svg.arc().outerRadius(arcsRadiusOuter[i]);\n                var arcOver = d3.svg.arc().outerRadius(arcsRadiusOuter[i] + 5);\n\n                if (startAngle !== false) {\n                    arc.startAngle(startAngle);\n                    arcOver.startAngle(startAngle);\n                }\n                if (endAngle !== false) {\n                    arc.endAngle(endAngle);\n                    arcOver.endAngle(endAngle);\n                }\n                if (donut) {\n                    arc.innerRadius(arcsRadiusInner[i]);\n                    arcOver.innerRadius(arcsRadiusInner[i]);\n                }\n\n                if (arc.cornerRadius && cornerRadius) {\n                    arc.cornerRadius(cornerRadius);\n                    arcOver.cornerRadius(cornerRadius);\n                }\n\n                arcs.push(arc);\n                arcsOver.push(arcOver);\n            }\n\n            // Setup the Pie chart and choose the data element\n            var pie = d3.layout.pie()\n                .sort(null)\n                .value(function(d) { return d.disabled ? 0 : getY(d) });\n\n            // padAngle added in d3 3.5\n            if (pie.padAngle && padAngle) {\n                pie.padAngle(padAngle);\n            }\n\n            // if title is specified and donut, put it in the middle\n            if (donut && title) {\n                g_pie.append(\"text\").attr('class', 'nv-pie-title');\n\n                wrap.select('.nv-pie-title')\n                    .style(\"text-anchor\", \"middle\")\n                    .text(function (d) {\n                        return title;\n                    })\n                    .style(\"font-size\", (Math.min(availableWidth, availableHeight)) * donutRatio * 2 / (title.length + 2) + \"px\")\n                    .attr(\"dy\", \"0.35em\") // trick to vertically center text\n                    .attr('transform', function(d, i) {\n                        return 'translate(0, '+ titleOffset + ')';\n                    });\n            }\n\n            var slices = wrap.select('.nv-pie').selectAll('.nv-slice').data(pie);\n            var pieLabels = wrap.select('.nv-pieLabels').selectAll('.nv-label').data(pie);\n\n            slices.exit().remove();\n            pieLabels.exit().remove();\n\n            var ae = slices.enter().append('g');\n            ae.attr('class', 'nv-slice');\n            ae.on('mouseover', function(d, i) {\n                d3.select(this).classed('hover', true);\n                if (growOnHover) {\n                    d3.select(this).select(\"path\").transition()\n                        .duration(70)\n                        .attr(\"d\", arcsOver[i]);\n                }\n                dispatch.elementMouseover({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\"),\n                    percent: (d.endAngle - d.startAngle) / (2 * Math.PI)\n                });\n            });\n            ae.on('mouseout', function(d, i) {\n                d3.select(this).classed('hover', false);\n                if (growOnHover) {\n                    d3.select(this).select(\"path\").transition()\n                        .duration(50)\n                        .attr(\"d\", arcs[i]);\n                }\n                dispatch.elementMouseout({data: d.data, index: i});\n            });\n            ae.on('mousemove', function(d, i) {\n                dispatch.elementMousemove({data: d.data, index: i});\n            });\n            ae.on('click', function(d, i) {\n                var element = this;\n                dispatch.elementClick({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\"),\n                    event: d3.event,\n                    element: element\n                });\n            });\n            ae.on('dblclick', function(d, i) {\n                dispatch.elementDblClick({\n                    data: d.data,\n                    index: i,\n                    color: d3.select(this).style(\"fill\")\n                });\n            });\n\n            slices.attr('fill', function(d,i) { return color(d.data, i); });\n            slices.attr('stroke', function(d,i) { return color(d.data, i); });\n\n            var paths = ae.append('path').each(function(d) {\n                this._current = d;\n            });\n\n            slices.select('path')\n                .transition()\n                .duration(duration)\n                .attr('d', function (d, i) { return arcs[i](d); })\n                .attrTween('d', arcTween);\n\n            if (showLabels) {\n                // This does the normal label\n                var labelsArc = [];\n                for (var i = 0; i < data[0].length; i++) {\n                    labelsArc.push(arcs[i]);\n\n                    if (labelsOutside) {\n                        if (donut) {\n                            labelsArc[i] = d3.svg.arc().outerRadius(arcs[i].outerRadius());\n                            if (startAngle !== false) labelsArc[i].startAngle(startAngle);\n                            if (endAngle !== false) labelsArc[i].endAngle(endAngle);\n                        }\n                    } else if (!donut) {\n                            labelsArc[i].innerRadius(0);\n                    }\n                }\n\n                pieLabels.enter().append(\"g\").classed(\"nv-label\",true).each(function(d,i) {\n                    var group = d3.select(this);\n\n                    group.attr('transform', function (d, i) {\n                        if (labelSunbeamLayout) {\n                            d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate\n                            d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate\n                            var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);\n                            if ((d.startAngle + d.endAngle) / 2 < Math.PI) {\n                                rotateAngle -= 90;\n                            } else {\n                                rotateAngle += 90;\n                            }\n                            return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')';\n                        } else {\n                            d.outerRadius = radius + 10; // Set Outer Coordinate\n                            d.innerRadius = radius + 15; // Set Inner Coordinate\n                            return 'translate(' + labelsArc[i].centroid(d) + ')'\n                        }\n                    });\n\n                    group.append('rect')\n                        .style('stroke', '#fff')\n                        .style('fill', '#fff')\n                        .attr(\"rx\", 3)\n                        .attr(\"ry\", 3);\n\n                    group.append('text')\n                        .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned\n                        .style('fill', '#000')\n                });\n\n                var labelLocationHash = {};\n                var avgHeight = 14;\n                var avgWidth = 140;\n                var createHashKey = function(coordinates) {\n                    return Math.floor(coordinates[0]/avgWidth) * avgWidth + ',' + Math.floor(coordinates[1]/avgHeight) * avgHeight;\n                };\n                var getSlicePercentage = function(d) {\n                    return (d.endAngle - d.startAngle) / (2 * Math.PI);\n                };\n\n                pieLabels.watchTransition(renderWatch, 'pie labels').attr('transform', function (d, i) {\n                    if (labelSunbeamLayout) {\n                        d.outerRadius = arcsRadiusOuter[i] + 10; // Set Outer Coordinate\n                        d.innerRadius = arcsRadiusOuter[i] + 15; // Set Inner Coordinate\n                        var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);\n                        if ((d.startAngle + d.endAngle) / 2 < Math.PI) {\n                            rotateAngle -= 90;\n                        } else {\n                            rotateAngle += 90;\n                        }\n                        return 'translate(' + labelsArc[i].centroid(d) + ') rotate(' + rotateAngle + ')';\n                    } else {\n                        d.outerRadius = radius + 10; // Set Outer Coordinate\n                        d.innerRadius = radius + 15; // Set Inner Coordinate\n\n                        /*\n                        Overlapping pie labels are not good. What this attempts to do is, prevent overlapping.\n                        Each label location is hashed, and if a hash collision occurs, we assume an overlap.\n                        Adjust the label's y-position to remove the overlap.\n                        */\n                        var center = labelsArc[i].centroid(d);\n                        var percent = getSlicePercentage(d);\n                        if (d.value && percent >= labelThreshold) {\n                            var hashKey = createHashKey(center);\n                            if (labelLocationHash[hashKey]) {\n                                center[1] -= avgHeight;\n                            }\n                            labelLocationHash[createHashKey(center)] = true;\n                        }\n                        return 'translate(' + center + ')'\n                    }\n                });\n\n                pieLabels.select(\".nv-label text\")\n                    .style('text-anchor', function(d,i) {\n                        //center the text on it's origin or begin/end if orthogonal aligned\n                        return labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle';\n                    })\n                    .text(function(d, i) {\n                        var percent = getSlicePercentage(d);\n                        var label = '';\n                        if (!d.value || percent < labelThreshold) return '';\n\n                        if(typeof labelType === 'function') {\n                            label = labelType(d, i, {\n                                'key': getX(d.data),\n                                'value': getY(d.data),\n                                'percent': valueFormat(percent)\n                            });\n                        } else {\n                            switch (labelType) {\n                                case 'key':\n                                    label = getX(d.data);\n                                    break;\n                                case 'value':\n                                    label = valueFormat(getY(d.data));\n                                    break;\n                                case 'percent':\n                                    label = d3.format('%')(percent);\n                                    break;\n                            }\n                        }\n                        return label;\n                    })\n                ;\n\n                if (hideOverlapLabels) {\n                    pieLabels\n                        .each(function (d, i) {\n                            if (!this.getBBox) return;\n                            var bb = this.getBBox(),\n                            center = labelsArc[i].centroid(d);\n                            var topLeft = {\n                              x : center[0] + bb.x,\n                              y : center[1] + bb.y\n                            };\n\n                            var topRight = {\n                              x : topLeft.x + bb.width,\n                              y : topLeft.y\n                            };\n\n                            var bottomLeft = {\n                              x : topLeft.x,\n                              y : topLeft.y + bb.height\n                            };\n\n                            var bottomRight = {\n                              x : topLeft.x + bb.width,\n                              y : topLeft.y + bb.height\n                            };\n\n                            d.visible = nv.utils.pointIsInArc(topLeft, d, arc) &&\n                            nv.utils.pointIsInArc(topRight, d, arc) &&\n                            nv.utils.pointIsInArc(bottomLeft, d, arc) &&\n                            nv.utils.pointIsInArc(bottomRight, d, arc);\n                        })\n                        .style('display', function (d) {\n                            return d.visible ? null : 'none';\n                        })\n                    ;\n                }\n\n            }\n\n\n            // Computes the angle of an arc, converting from radians to degrees.\n            function angle(d) {\n                var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;\n                return a > 90 ? a - 180 : a;\n            }\n\n            function arcTween(a, idx) {\n                a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle;\n                a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle;\n                if (!donut) a.innerRadius = 0;\n                var i = d3.interpolate(this._current, a);\n                this._current = i(0);\n                return function (t) {\n                    return arcs[idx](i(t));\n                };\n            }\n        });\n\n        renderWatch.renderEnd('pie immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        arcsRadius: { get: function () { return arcsRadius; }, set: function (_) { arcsRadius = _; } },\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}},\n        title:      {get: function(){return title;}, set: function(_){title=_;}},\n        titleOffset:    {get: function(){return titleOffset;}, set: function(_){titleOffset=_;}},\n        labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_;}},\n        hideOverlapLabels: {get: function(){return hideOverlapLabels;}, set: function(_){hideOverlapLabels=_;}},\n        valueFormat:    {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},\n        x:          {get: function(){return getX;}, set: function(_){getX=_;}},\n        id:         {get: function(){return id;}, set: function(_){id=_;}},\n        endAngle:   {get: function(){return endAngle;}, set: function(_){endAngle=_;}},\n        startAngle: {get: function(){return startAngle;}, set: function(_){startAngle=_;}},\n        padAngle:   {get: function(){return padAngle;}, set: function(_){padAngle=_;}},\n        cornerRadius: {get: function(){return cornerRadius;}, set: function(_){cornerRadius=_;}},\n        donutRatio:   {get: function(){return donutRatio;}, set: function(_){donutRatio=_;}},\n        labelsOutside: {get: function(){return labelsOutside;}, set: function(_){labelsOutside=_;}},\n        labelSunbeamLayout: {get: function(){return labelSunbeamLayout;}, set: function(_){labelSunbeamLayout=_;}},\n        donut:              {get: function(){return donut;}, set: function(_){donut=_;}},\n        growOnHover:        {get: function(){return growOnHover;}, set: function(_){growOnHover=_;}},\n\n        // depreciated after 1.7.1\n        pieLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){\n            labelsOutside=_;\n            nv.deprecated('pieLabelsOutside', 'use labelsOutside instead');\n        }},\n        // depreciated after 1.7.1\n        donutLabelsOutside: {get: function(){return labelsOutside;}, set: function(_){\n            labelsOutside=_;\n            nv.deprecated('donutLabelsOutside', 'use labelsOutside instead');\n        }},\n        // deprecated after 1.7.1\n        labelFormat: {get: function(){ return valueFormat;}, set: function(_) {\n            valueFormat=_;\n            nv.deprecated('labelFormat','use valueFormat instead');\n        }},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = typeof _.top    != 'undefined' ? _.top    : margin.top;\n            margin.right  = typeof _.right  != 'undefined' ? _.right  : margin.right;\n            margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;\n            margin.left   = typeof _.left   != 'undefined' ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        y: {get: function(){return getY;}, set: function(_){\n            getY=d3.functor(_);\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color=nv.utils.getColor(_);\n        }},\n        labelType:          {get: function(){return labelType;}, set: function(_){\n            labelType= _ || 'key';\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/pieChart.js",
    "content": "nv.models.pieChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var pie = nv.models.pie();\n    var legend = nv.models.legend();\n    var tooltip = nv.models.tooltip();\n\n    var margin = {top: 30, right: 20, bottom: 20, left: 20}\n        , marginTop = null\n        , width = null\n        , height = null\n        , showTooltipPercent = false\n        , showLegend = true\n        , legendPosition = \"top\"\n        , color = nv.utils.defaultColor()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , duration = 250\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        ;\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d, i) {\n            return pie.valueFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined) {\n                data.forEach(function (series, i) {\n                    series.disabled = !state.active[i];\n                });\n            }\n        }\n    };\n\n    //============================================================\n    // Chart function\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(pie);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var that = this;\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.transition().call(chart); };\n            chart.container = this;\n\n            state.setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            //set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-pieChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-pieChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-pieWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                if (legendPosition === \"top\") {\n                    legend.width( availableWidth ).key(pie.x());\n\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    if (!marginTop && legend.height() !== margin.top) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin);\n                    }\n\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + (-margin.top) +')');\n                } else if (legendPosition === \"right\") {\n                    var legendWidth = nv.models.legend().width();\n                    if (availableWidth / 2 < legendWidth) {\n                        legendWidth = (availableWidth / 2)\n                    }\n                    legend.height(availableHeight).key(pie.x());\n                    legend.width(legendWidth);\n                    availableWidth -= legend.width();\n\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend)\n                        .attr('transform', 'translate(' + (availableWidth) +',0)');\n                } else if (legendPosition === \"bottom\") {\n                    legend.width( availableWidth ).key(pie.x());\n                    wrap.select('.nv-legendWrap')\n                        .datum(data)\n                        .call(legend);\n\n                    margin.bottom = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                    wrap.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + availableHeight +')');\n                }\n            }\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            pie.width(availableWidth).height(availableHeight);\n            var pieWrap = g.select('.nv-pieWrap').datum([data]);\n            d3.transition(pieWrap).call(pie);\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState) {\n                    state[key] = newState[key];\n                }\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n        });\n\n        renderWatch.renderEnd('pieChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    pie.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt['series'] = {\n            key: chart.x()(evt.data),\n            value: chart.y()(evt.data),\n            color: evt.color,\n            percent: evt.percent\n        };\n        if (!showTooltipPercent) {\n            delete evt.percent;\n            delete evt.series.percent;\n        }\n        tooltip.data(evt).hidden(false);\n    });\n\n    pie.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    pie.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.legend = legend;\n    chart.dispatch = dispatch;\n    chart.pie = pie;\n    chart.tooltip = tooltip;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // use Object get/set functionality to map between vars and chart functions\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:              {get: function(){return width;},                set: function(_){width=_;}},\n        height:             {get: function(){return height;},               set: function(_){height=_;}},\n        noData:             {get: function(){return noData;},               set: function(_){noData=_;}},\n        showTooltipPercent: {get: function(){return showTooltipPercent;},   set: function(_){showTooltipPercent=_;}},\n        showLegend:         {get: function(){return showLegend;},           set: function(_){showLegend=_;}},\n        legendPosition:     {get: function(){return legendPosition;},       set: function(_){legendPosition=_;}},\n        defaultState:       {get: function(){return defaultState;},         set: function(_){defaultState=_;}},\n\n        // options that require extra logic in the setter\n        color: {get: function(){return color;}, set: function(_){\n            color = _;\n            legend.color(color);\n            pie.color(color);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            pie.duration(duration);\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }}\n    });\n    nv.utils.inheritOptions(chart, pie);\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/sankey.js",
    "content": "nv.models.sankey = function() {\n    'use strict';\n\n    // Sources:\n    // - https://bost.ocks.org/mike/sankey/\n    // - https://github.com/soxofaan/d3-plugin-captain-sankey\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sankey = {},\n        nodeWidth = 24,\n        nodePadding = 8,\n        size = [1, 1],\n        nodes = [],\n        links = [],\n        sinksRight = true;\n\n    var layout = function(iterations) {\n        computeNodeLinks();\n        computeNodeValues();\n        computeNodeBreadths();\n        computeNodeDepths(iterations);\n    };\n\n    var relayout = function() {\n        computeLinkDepths();\n    };\n\n    // SVG path data generator, to be used as 'd' attribute on 'path' element selection.\n    var link = function() {\n        var curvature = .5;\n\n        function link(d) {\n\n            var x0 = d.source.x + d.source.dx,\n                x1 = d.target.x,\n                xi = d3.interpolateNumber(x0, x1),\n                x2 = xi(curvature),\n                x3 = xi(1 - curvature),\n                y0 = d.source.y + d.sy + d.dy / 2,\n                y1 = d.target.y + d.ty + d.dy / 2;\n            var linkPath = 'M' + x0 + ',' + y0\n                + 'C' + x2 + ',' + y0\n                + ' ' + x3 + ',' + y1\n                + ' ' + x1 + ',' + y1;\n            return linkPath;\n        }\n\n        link.curvature = function(_) {\n            if (!arguments.length) return curvature;\n            curvature = +_;\n            return link;\n        };\n\n        return link;\n    };\n\n    // Y-position of the middle of a node.\n    var center = function(node) {\n        return node.y + node.dy / 2;\n    };\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    // Populate the sourceLinks and targetLinks for each node.\n    // Also, if the source and target are not objects, assume they are indices.\n    function computeNodeLinks() {\n        nodes.forEach(function(node) {\n            // Links that have this node as source.\n            node.sourceLinks = [];\n            // Links that have this node as target.\n            node.targetLinks = [];\n        });\n        links.forEach(function(link) {\n            var source = link.source,\n                target = link.target;\n            if (typeof source === 'number') source = link.source = nodes[link.source];\n            if (typeof target === 'number') target = link.target = nodes[link.target];\n            source.sourceLinks.push(link);\n            target.targetLinks.push(link);\n        });\n    }\n\n    // Compute the value (size) of each node by summing the associated links.\n    function computeNodeValues() {\n        nodes.forEach(function(node) {\n            node.value = Math.max(\n                d3.sum(node.sourceLinks, value),\n                d3.sum(node.targetLinks, value)\n            );\n        });\n    }\n\n    // Iteratively assign the breadth (x-position) for each node.\n    // Nodes are assigned the maximum breadth of incoming neighbors plus one;\n    // nodes with no incoming links are assigned breadth zero, while\n    // nodes with no outgoing links are assigned the maximum breadth.\n    function computeNodeBreadths() {\n        //\n        var remainingNodes = nodes,\n            nextNodes,\n            x = 0;\n\n        // Work from left to right.\n        // Keep updating the breath (x-position) of nodes that are target of recently updated nodes.\n        //\n        while (remainingNodes.length && x < nodes.length) {\n            nextNodes = [];\n            remainingNodes.forEach(function(node) {\n                node.x = x;\n                node.dx = nodeWidth;\n                node.sourceLinks.forEach(function(link) {\n                    if (nextNodes.indexOf(link.target) < 0) {\n                        nextNodes.push(link.target);\n                    }\n                });\n            });\n            remainingNodes = nextNodes;\n            ++x;\n            //\n        }\n\n        // Optionally move pure sinks always to the right.\n        if (sinksRight) {\n            moveSinksRight(x);\n        }\n\n        scaleNodeBreadths((size[0] - nodeWidth) / (x - 1));\n    }\n\n    function moveSourcesRight() {\n        nodes.forEach(function(node) {\n            if (!node.targetLinks.length) {\n                node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1;\n            }\n        });\n    }\n\n    function moveSinksRight(x) {\n        nodes.forEach(function(node) {\n            if (!node.sourceLinks.length) {\n                node.x = x - 1;\n            }\n        });\n    }\n\n    function scaleNodeBreadths(kx) {\n        nodes.forEach(function(node) {\n            node.x *= kx;\n        });\n    }\n\n    // Compute the depth (y-position) for each node.\n    function computeNodeDepths(iterations) {\n        // Group nodes by breath.\n        var nodesByBreadth = d3.nest()\n            .key(function(d) { return d.x; })\n            .sortKeys(d3.ascending)\n            .entries(nodes)\n            .map(function(d) { return d.values; });\n\n        //\n        initializeNodeDepth();\n        resolveCollisions();\n        computeLinkDepths();\n        for (var alpha = 1; iterations > 0; --iterations) {\n            relaxRightToLeft(alpha *= .99);\n            resolveCollisions();\n            computeLinkDepths();\n            relaxLeftToRight(alpha);\n            resolveCollisions();\n            computeLinkDepths();\n        }\n\n        function initializeNodeDepth() {\n            // Calculate vertical scaling factor.\n            var ky = d3.min(nodesByBreadth, function(nodes) {\n                return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value);\n            });\n\n            nodesByBreadth.forEach(function(nodes) {\n                nodes.forEach(function(node, i) {\n                    node.y = i;\n                    node.dy = node.value * ky;\n                });\n            });\n\n            links.forEach(function(link) {\n                link.dy = link.value * ky;\n            });\n        }\n\n        function relaxLeftToRight(alpha) {\n            nodesByBreadth.forEach(function(nodes, breadth) {\n                nodes.forEach(function(node) {\n                    if (node.targetLinks.length) {\n                        // Value-weighted average of the y-position of source node centers linked to this node.\n                        var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value);\n                        node.y += (y - center(node)) * alpha;\n                    }\n                });\n            });\n\n            function weightedSource(link) {\n                return (link.source.y + link.sy + link.dy / 2) * link.value;\n            }\n        }\n\n        function relaxRightToLeft(alpha) {\n            nodesByBreadth.slice().reverse().forEach(function(nodes) {\n                nodes.forEach(function(node) {\n                    if (node.sourceLinks.length) {\n                        // Value-weighted average of the y-positions of target nodes linked to this node.\n                        var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value);\n                        node.y += (y - center(node)) * alpha;\n                    }\n                });\n            });\n\n            function weightedTarget(link) {\n                return (link.target.y + link.ty + link.dy / 2) * link.value;\n            }\n        }\n\n        function resolveCollisions() {\n            nodesByBreadth.forEach(function(nodes) {\n                var node,\n                    dy,\n                    y0 = 0,\n                    n = nodes.length,\n                    i;\n\n                // Push any overlapping nodes down.\n                nodes.sort(ascendingDepth);\n                for (i = 0; i < n; ++i) {\n                    node = nodes[i];\n                    dy = y0 - node.y;\n                    if (dy > 0) node.y += dy;\n                    y0 = node.y + node.dy + nodePadding;\n                }\n\n                // If the bottommost node goes outside the bounds, push it back up.\n                dy = y0 - nodePadding - size[1];\n                if (dy > 0) {\n                    y0 = node.y -= dy;\n\n                    // Push any overlapping nodes back up.\n                    for (i = n - 2; i >= 0; --i) {\n                        node = nodes[i];\n                        dy = node.y + node.dy + nodePadding - y0;\n                        if (dy > 0) node.y -= dy;\n                        y0 = node.y;\n                    }\n                }\n            });\n        }\n\n        function ascendingDepth(a, b) {\n            return a.y - b.y;\n        }\n    }\n\n    // Compute y-offset of the source endpoint (sy) and target endpoints (ty) of links,\n    // relative to the source/target node's y-position.\n    function computeLinkDepths() {\n        nodes.forEach(function(node) {\n            node.sourceLinks.sort(ascendingTargetDepth);\n            node.targetLinks.sort(ascendingSourceDepth);\n        });\n        nodes.forEach(function(node) {\n            var sy = 0, ty = 0;\n            node.sourceLinks.forEach(function(link) {\n                link.sy = sy;\n                sy += link.dy;\n            });\n            node.targetLinks.forEach(function(link) {\n                link.ty = ty;\n                ty += link.dy;\n            });\n        });\n\n        function ascendingSourceDepth(a, b) {\n            return a.source.y - b.source.y;\n        }\n\n        function ascendingTargetDepth(a, b) {\n            return a.target.y - b.target.y;\n        }\n    }\n\n    // Value property accessor.\n    function value(x) {\n        return x.value;\n    }\n\n    sankey.options = nv.utils.optionsFunc.bind(sankey);\n    sankey._options = Object.create({}, {\n        nodeWidth:    {get: function(){return nodeWidth;},   set: function(_){nodeWidth=+_;}},\n        nodePadding:  {get: function(){return nodePadding;}, set: function(_){nodePadding=_;}},\n        nodes:        {get: function(){return nodes;},       set: function(_){nodes=_;}},\n        links:        {get: function(){return links ;},      set: function(_){links=_;}},\n        size:         {get: function(){return size;},        set: function(_){size=_;}},\n        sinksRight:   {get: function(){return sinksRight;},  set: function(_){sinksRight=_;}},\n\n        layout:       {get: function(){layout(32);},         set: function(_){layout(_);}},\n        relayout:     {get: function(){relayout();},         set: function(_){}},\n        center:       {get: function(){return center();},    set: function(_){\n            if(typeof _ === 'function'){\n                center=_;\n            }\n        }},\n        link:         {get: function(){return link();},      set: function(_){\n            if(typeof _ === 'function'){\n                link=_;\n            }\n            return link();\n        }}\n    });\n\n    nv.utils.initOptions(sankey);\n\n    return sankey;\n};\n"
  },
  {
    "path": "src/models/sankeyChart.js",
    "content": "nv.models.sankeyChart = function() {\n    \"use strict\";\n\n    // Sources:\n    // - https://bost.ocks.org/mike/sankey/\n    // - https://github.com/soxofaan/d3-plugin-captain-sankey\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 5, right: 0, bottom: 5, left: 0}\n        , sankey = nv.models.sankey()\n        , width = 600\n        , height = 400\n        , nodeWidth = 36\n        , nodePadding =  40\n        , units = 'units'\n        , center = undefined\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var formatNumber = d3.format(',.0f');    // zero decimal places\n    var format = function(d) {\n        return formatNumber(d) + ' ' + units;\n    };\n    var color = d3.scale.category20();\n    var linkTitle = function(d){\n        return d.source.name + ' → ' + d.target.name + '\\n' + format(d.value);\n    };\n    var nodeFillColor = function(d){\n        return d.color = color(d.name.replace(/ .*/, ''));\n    };\n    var nodeStrokeColor = function(d){\n        return d3.rgb(d.color).darker(2);\n    };\n    var nodeTitle = function(d){\n        return d.name + '\\n' + format(d.value);\n    };\n\n    var showError = function(element, message) {\n        element.append('text')\n            .attr('x', 0)\n            .attr('y', 0)\n            .attr('class', 'nvd3-sankey-chart-error')\n            .attr('text-anchor', 'middle')\n            .text(message);\n    };\n\n    function chart(selection) {\n        selection.each(function(data) {\n\n            var testData = {\n                nodes:\n                    [\n                        {'node': 1, 'name': 'Test 1'},\n                        {'node': 2, 'name': 'Test 2'},\n                        {'node': 3, 'name': 'Test 3'},\n                        {'node': 4, 'name': 'Test 4'},\n                        {'node': 5, 'name': 'Test 5'},\n                        {'node': 6, 'name': 'Test 6'}\n                    ],\n                links:\n                    [\n                        {'source': 0, 'target': 1, 'value': 2295},\n                        {'source': 0, 'target': 5, 'value': 1199},\n                        {'source': 1, 'target': 2, 'value': 1119},\n                        {'source': 1, 'target': 5, 'value': 1176},\n                        {'source': 2, 'target': 3, 'value': 487},\n                        {'source': 2, 'target': 5, 'value': 632},\n                        {'source': 3, 'target': 4, 'value': 301},\n                        {'source': 3, 'target': 5, 'value': 186}\n                    ]\n            };\n\n            // Error handling\n            var isDataValid = false;\n            var dataAvailable = false;\n\n            // check if data is valid\n            if(\n                (typeof data['nodes'] === 'object' && data['nodes'].length) >= 0 &&\n                (typeof data['links'] === 'object' && data['links'].length) >= 0\n            ){\n                isDataValid = true;\n            }\n\n            // check if data is available\n            if(\n                data['nodes'] && data['nodes'].length > 0 &&\n                data['links'] && data['links'].length > 0\n            ) {\n                dataAvailable = true;\n            }\n\n            // show error\n            if(!isDataValid) {\n                console.error('NVD3 Sankey chart error:', 'invalid data format for', data);\n                console.info('Valid data format is: ', testData, JSON.stringify(testData));\n                showError(selection, 'Error loading chart, data is invalid');\n                return false;\n            }\n\n            // TODO use nv.utils.noData\n            if(!dataAvailable) {\n                showError(selection, 'No data available');\n                return false;\n            }\n\n            // No errors, continue\n\n            // append the svg canvas to the page\n            var svg = selection.append('svg')\n                .attr('width', width)\n                .attr('height', height)\n                .append('g')\n                .attr('class', 'nvd3 nv-wrap nv-sankeyChart');\n\n            // Set the sankey diagram properties\n            sankey\n                .nodeWidth(nodeWidth)\n                .nodePadding(nodePadding)\n                .size([width, height]);\n\n            var path = sankey.link();\n\n            sankey\n                .nodes(data.nodes)\n                .links(data.links)\n                .layout(32)\n                .center(center);\n\n            // add in the links\n            var link = svg.append('g').selectAll('.link')\n                .data(data.links)\n                .enter().append('path')\n                .attr('class', 'link')\n                .attr('d', path)\n                .style('stroke-width', function(d) { return Math.max(1, d.dy); })\n            .sort(function(a,b) { return b.dy - a.dy; });\n\n            // add the link titles\n            link.append('title')\n                .text(linkTitle);\n\n            // add in the nodes\n            var node = svg.append('g').selectAll('.node')\n                .data(data.nodes)\n                .enter().append('g')\n                .attr('class', 'node')\n                .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; })\n                .call(\n                    d3.behavior\n                        .drag()\n                        .origin(function(d) { return d; })\n                        .on('dragstart', function() {\n                            this.parentNode.appendChild(this);\n                        })\n                        .on('drag', dragmove)\n                );\n\n            // add the rectangles for the nodes\n            node.append('rect')\n                .attr('height', function(d) { return d.dy; })\n                .attr('width', sankey.nodeWidth())\n                .style('fill', nodeFillColor)\n                .style('stroke', nodeStrokeColor)\n                .append('title')\n                .text(nodeTitle);\n\n            // add in the title for the nodes\n            node.append('text')\n                .attr('x', -6)\n                .attr('y', function(d) { return d.dy / 2; })\n                .attr('dy', '.35em')\n                .attr('text-anchor', 'end')\n                .attr('transform', null)\n                .text(function(d) { return d.name; })\n                .filter(function(d) { return d.x < width / 2; })\n                .attr('x', 6 + sankey.nodeWidth())\n                .attr('text-anchor', 'start');\n\n            // the function for moving the nodes\n            function dragmove(d) {\n                d3.select(this).attr('transform',\n                'translate(' + d.x + ',' + (\n                    d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))\n                ) + ')');\n                sankey.relayout();\n                link.attr('d', path);\n            }\n        });\n\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        units:           {get: function(){return units;},       set: function(_){units=_;}},\n        width:           {get: function(){return width;},       set: function(_){width=_;}},\n        height:          {get: function(){return height;},      set: function(_){height=_;}},\n        format:          {get: function(){return format;},      set: function(_){format=_;}},\n        linkTitle:       {get: function(){return linkTitle;},   set: function(_){linkTitle=_;}},\n        nodeWidth:       {get: function(){return nodeWidth;},   set: function(_){nodeWidth=_;}},\n        nodePadding:     {get: function(){return nodePadding;}, set: function(_){nodePadding=_;}},\n        center:          {get: function(){return center},       set: function(_){center=_}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        nodeStyle: {get: function(){return {};}, set: function(_){\n            nodeFillColor   = _.fillColor   !== undefined ? _.fillColor   : nodeFillColor;\n            nodeStrokeColor = _.strokeColor !== undefined ? _.strokeColor : nodeStrokeColor;\n            nodeTitle       = _.title       !== undefined ? _.title       : nodeTitle;\n        }}\n\n    });\n\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/scatter.js",
    "content": "\nnv.models.scatter = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin       = {top: 0, right: 0, bottom: 0, left: 0}\n        , width        = null\n        , height       = null\n        , color        = nv.utils.defaultColor() // chooses color\n        , pointBorderColor = null\n        , id           = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't select one\n        , container    = null\n        , x            = d3.scale.linear()\n        , y            = d3.scale.linear()\n        , z            = d3.scale.linear() //linear because d3.svg.shape.size is treated as area\n        , getX         = function(d) { return d.x } // accessor to get the x value\n        , getY         = function(d) { return d.y } // accessor to get the y value\n        , getSize      = function(d) { return d.size || 1} // accessor to get the point size\n        , getShape     = function(d) { return d.shape || 'circle' } // accessor to get point shape\n        , forceX       = [] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)\n        , forceY       = [] // List of numbers to Force into the Y scale\n        , forceSize    = [] // List of numbers to Force into the Size scale\n        , interactive  = true // If true, plots a voronoi overlay for advanced point intersection\n        , pointActive  = function(d) { return !d.notActive } // any points that return false will be filtered out\n        , padData      = false // If true, adds half a data points width to front and back, for lining up a line chart with a bar chart\n        , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding\n        , clipEdge     = false // if true, masks points within x and y scale\n        , clipVoronoi  = true // if true, masks each point with a circle... can turn off to slightly increase performance\n        , showVoronoi  = false // display the voronoi areas\n        , clipRadius   = function() { return 25 } // function to get the radius for voronoi point clips\n        , xDomain      = null // Override x domain (skips the calculation from data)\n        , yDomain      = null // Override y domain\n        , xRange       = null // Override x range\n        , yRange       = null // Override y range\n        , sizeDomain   = null // Override point size domain\n        , sizeRange    = null\n        , singlePoint  = false\n        , dispatch     = d3.dispatch('elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout', 'renderEnd')\n        , useVoronoi   = true\n        , duration     = 250\n        , interactiveUpdateDelay = 300\n        , showLabels    = false\n        ;\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0, z0 // used to store previous scales\n        , xDom, yDom // used to store previous domains\n        , width0\n        , height0\n        , timeoutID\n        , needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips\n        , renderWatch = nv.utils.renderWatch(dispatch, duration)\n        , _sizeRange_def = [16, 256]\n        , _cache = {}\n        ;\n\n    //============================================================\n    // Diff and Cache Utilities\n    //------------------------------------------------------------\n    // getDiffs is used to filter unchanged points from the update\n    // selection. It implicitly updates it's cache when called and\n    // therefor the diff is based upon the previous invocation NOT\n    // the previous update.\n    //\n    // getDiffs takes a point as its first argument followed by n\n    // key getter pairs (d, [key, get... key, get]) this approach\n    // was chosen for efficiency. (The filter will call it a LOT).\n    //\n    // It is important to call delCache on point exit to prevent a\n    // memory leak. It is also needed to prevent invalid caches if\n    // a new point uses the same series and point id key.\n    //\n    // Argument Performance Concerns:\n    // - Object property lists for key getter pairs would be very\n    // expensive (points * objects for the GC every update).\n    // - ES6 function names for implicit keys would be nice but\n    // they are not guaranteed to be unique.\n    // - function.toString to obtain implicit keys is possible\n    // but long object keys are not free (internal hash).\n    // - Explicit key without objects are the most efficient.\n\n    function getCache(d) {\n        var key, val;\n        key = d[0].series + ':' + d[1];\n        val = _cache[key] = _cache[key] || {};\n        return val;\n    }\n\n    function delCache(d) {\n        var key, val;\n        key = d[0].series + ':' + d[1];\n        delete _cache[key];\n    }\n\n    function getDiffs(d) {\n        var i, key, val,\n            cache = getCache(d),\n            diffs = false;\n        for (i = 1; i < arguments.length; i += 2) {\n            key = arguments[i];\n            val = arguments[i + 1](d[0], d[1]);\n            if (cache[key] !== val || !cache.hasOwnProperty(key)) {\n                cache[key] = val;\n                diffs = true;\n            }\n        }\n        return diffs;\n    }\n\n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            container = d3.select(this);\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            nv.utils.initSVG(container);\n\n            //add series index to each data point for reference\n            data.forEach(function(series, i) {\n                series.values.forEach(function(point) {\n                    point.series = i;\n                });\n            });\n\n            // Setup Scales\n            var logScale = (typeof(chart.yScale().base) === \"function\"); // Only log scale has a method \"base()\"\n            // remap and flatten the data for use in calculating the scales' domains\n            var seriesData = (xDomain && yDomain && sizeDomain) ? [] : // if we know xDomain and yDomain and sizeDomain, no need to calculate.... if Size is constant remember to set sizeDomain to speed up performance\n                d3.merge(\n                    data.map(function(d) {\n                        return d.values.map(function(d,i) {\n                            return { x: getX(d,i), y: getY(d,i), size: getSize(d,i) }\n                        })\n                    })\n                );\n\n            x   .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x; }).concat(forceX)))\n\n            if (padData && data[0])\n                x.range(xRange || [(availableWidth * padDataOuter +  availableWidth) / (2 *data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 * data[0].values.length)  ]);\n            //x.range([availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5)  / data[0].values.length ]);\n            else\n                x.range(xRange || [0, availableWidth]);\n\n             if (logScale) {\n                    var min = d3.min(seriesData.map(function(d) { if (d.y !== 0) return d.y; }));\n                    y.clamp(true)\n                        .domain(yDomain || d3.extent(seriesData.map(function(d) {\n                            if (d.y !== 0) return d.y;\n                            else return min * 0.1;\n                        }).concat(forceY)))\n                        .range(yRange || [availableHeight, 0]);\n                } else {\n                        y.domain(yDomain || d3.extent(seriesData.map(function (d) { return d.y;}).concat(forceY)))\n                        .range(yRange || [availableHeight, 0]);\n                }\n\n            z   .domain(sizeDomain || d3.extent(seriesData.map(function(d) { return d.size }).concat(forceSize)))\n                .range(sizeRange || _sizeRange_def);\n\n            // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point\n            singlePoint = x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1];\n\n            if (x.domain()[0] === x.domain()[1])\n                x.domain()[0] ?\n                    x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])\n                    : x.domain([-1,1]);\n\n            if (y.domain()[0] === y.domain()[1])\n                y.domain()[0] ?\n                    y.domain([y.domain()[0] - y.domain()[0] * 0.01, y.domain()[1] + y.domain()[1] * 0.01])\n                    : y.domain([-1,1]);\n\n            if ( isNaN(x.domain()[0])) {\n                x.domain([-1,1]);\n            }\n\n            if ( isNaN(y.domain()[0])) {\n                y.domain([-1,1]);\n            }\n\n            x0 = x0 || x;\n            y0 = y0 || y;\n            z0 = z0 || z;\n\n            var scaleDiff = x(1) !== x0(1) || y(1) !== y0(1) || z(1) !== z0(1);\n\n            width0 = width0 || width;\n            height0 = height0 || height;\n\n            var sizeDiff = width0 !== width || height0 !== height;\n\n            // Domain Diffs\n\n            xDom = xDom || [];\n            var domainDiff = xDom[0] !== x.domain()[0] || xDom[1] !== x.domain()[1];\n            xDom = x.domain();\n\n            yDom = yDom || [];\n            domainDiff = domainDiff || yDom[0] !== y.domain()[0] || yDom[1] !== y.domain()[1];\n            yDom = y.domain();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id);\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.classed('nv-single-point', singlePoint);\n            gEnter.append('g').attr('class', 'nv-groups');\n            gEnter.append('g').attr('class', 'nv-point-paths');\n            wrapEnter.append('g').attr('class', 'nv-point-clips');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect')\n                .attr('transform', 'translate( -10, -10)');\n\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth + 20)\n                .attr('height', (availableHeight > 0) ? availableHeight + 20 : 0);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            function updateInteractiveLayer() {\n                // Always clear needs-update flag regardless of whether or not\n                // we will actually do anything (avoids needless invocations).\n                needsUpdate = false;\n\n                if (!interactive) return false;\n                container.selectAll(\".nv-point.hover\").classed(\"hover\", false);\n\n                // nuke all voronoi paths\n                wrap.select('.nv-point-paths').selectAll('path').remove();\n\n                // inject series and point index for reference into voronoi\n                if (useVoronoi === true) {\n                    var vertices = d3.merge(data.map(function(group, groupIndex) {\n                            return group.values\n                                .map(function(point, pointIndex) {\n                                    // *Adding noise to make duplicates very unlikely\n                                    // *Injecting series and point index for reference\n                                    // *Adding a 'jitter' to the points, because there's an issue in d3.geom.voronoi.\n                                    var pX = getX(point,pointIndex);\n                                    var pY = getY(point,pointIndex);\n\n                                    return [nv.utils.NaNtoZero(x(pX)) + Math.random() * 1e-4,\n                                            nv.utils.NaNtoZero(y(pY)) + Math.random() * 1e-4,\n                                        groupIndex,\n                                        pointIndex, point];\n                                })\n                                .filter(function(pointArray, pointIndex) {\n                                    return pointActive(pointArray[4], pointIndex); // Issue #237.. move filter to after map, so pointIndex is correct!\n                                })\n                        })\n                    );\n\n                    if (vertices.length == 0) return false;  // No active points, we're done\n                    if (vertices.length < 3) {\n                        // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min 3 points to work\n                        vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]);\n                        vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]);\n                        vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]);\n                        vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]);\n                    }\n\n                    // keep voronoi sections from going more than 10 outside of graph\n                    // to avoid overlap with other things like legend etc\n                    var bounds = d3.geom.polygon([\n                        [-10,-10],\n                        [-10,height + 10],\n                        [width + 10,height + 10],\n                        [width + 10,-10]\n                    ]);\n\n                    // delete duplicates from vertices - essential assumption for d3.geom.voronoi\n                    var epsilon = 1e-4; // Uses 1e-4 to determine equivalence.\n                    vertices = vertices.sort(function(a,b){return ((a[0] - b[0]) || (a[1] - b[1]))});\n                    for (var i = 0; i < vertices.length - 1; ) {\n                        if ((Math.abs(vertices[i][0] - vertices[i+1][0]) < epsilon) &&\n                        (Math.abs(vertices[i][1] - vertices[i+1][1]) < epsilon)) {\n                            vertices.splice(i+1, 1);\n                        } else {\n                            i++;\n                        }\n                    }\n\n                    var voronoi = d3.geom.voronoi(vertices).map(function(d, i) {\n                        if (d.length === 0) {\n                            return null;\n                        }\n\n                        return {\n                            'data': bounds.clip(d),\n                            'series': vertices[i][2],\n                            'point': vertices[i][3]\n                        }\n                    });\n\n                    var pointPaths = wrap.select('.nv-point-paths').selectAll('path').data(voronoi);\n                    var vPointPaths = pointPaths\n                        .enter().append(\"svg:path\")\n                        .attr(\"d\", function(d) {\n                            if (!d || !d.data || d.data.length === 0)\n                                return 'M 0 0';\n                            else\n                                return \"M\" + d.data.join(\",\") + \"Z\";\n                        })\n                        .attr(\"id\", function(d,i) {\n                            return \"nv-path-\"+i; })\n                        .attr(\"clip-path\", function(d,i) { return \"url(#nv-clip-\"+id+\"-\"+i+\")\"; })\n                        ;\n\n                    // good for debugging point hover issues\n                    if (showVoronoi) {\n                        vPointPaths.style(\"fill\", d3.rgb(230, 230, 230))\n                            .style('fill-opacity', 0.4)\n                            .style('stroke-opacity', 1)\n                            .style(\"stroke\", d3.rgb(200,200,200));\n                    }\n\n                    if (clipVoronoi) {\n                        // voronoi sections are already set to clip,\n                        // just create the circles with the IDs they expect\n                        wrap.select('.nv-point-clips').selectAll('*').remove(); // must do * since it has sub-dom\n                        var pointClips = wrap.select('.nv-point-clips').selectAll('clipPath').data(vertices);\n                        var vPointClips = pointClips\n                            .enter().append(\"svg:clipPath\")\n                            .attr(\"id\", function(d, i) { return \"nv-clip-\"+id+\"-\"+i;})\n                            .append(\"svg:circle\")\n                            .attr('cx', function(d) { return d[0]; })\n                            .attr('cy', function(d) { return d[1]; })\n                            .attr('r', clipRadius);\n                    }\n\n                    var mouseEventCallback = function(el, d, mDispatch) {\n                        if (needsUpdate) return 0;\n                        var series = data[d.series];\n                        if (series === undefined) return;\n                        var point  = series.values[d.point];\n                        point['color'] = color(series, d.series);\n\n                        // standardize attributes for tooltip.\n                        point['x'] = getX(point);\n                        point['y'] = getY(point);\n\n                        // can't just get box of event node since it's actually a voronoi polygon\n                        var box = container.node().getBoundingClientRect();\n                        var scrollTop  = window.pageYOffset || document.documentElement.scrollTop;\n                        var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n                        var pos = {\n                            left: x(getX(point, d.point)) + box.left + scrollLeft + margin.left + 10,\n                            top: y(getY(point, d.point)) + box.top + scrollTop + margin.top + 10\n                        };\n\n                        mDispatch({\n                            point: point,\n                            series: series,\n                            pos: pos,\n                            relativePos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) + margin.top],\n                            seriesIndex: d.series,\n                            pointIndex: d.point,\n                            event: d3.event,\n                            element: el\n                        });\n                    };\n\n                    pointPaths\n                        .on('click', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementClick);\n                        })\n                        .on('dblclick', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementDblClick);\n                        })\n                        .on('mouseover', function(d) {\n                            mouseEventCallback(this, d, dispatch.elementMouseover);\n                        })\n                        .on('mouseout', function(d, i) {\n                            mouseEventCallback(this, d, dispatch.elementMouseout);\n                        });\n\n                } else {\n                    // add event handlers to points instead voronoi paths\n                    wrap.select('.nv-groups').selectAll('.nv-group')\n                        .selectAll('.nv-point')\n                        //.data(dataWithPoints)\n                        //.style('pointer-events', 'auto') // recativate events, disabled by css\n                        .on('click', function(d,i) {\n                            //nv.log('test', d, i);\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n                            var element = this;\n                            dispatch.elementClick({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top], //TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                event: d3.event,\n                                element: element\n                            });\n                        })\n                        .on('dblclick', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementDblClick({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i\n                            });\n                        })\n                        .on('mouseover', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementMouseover({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                color: color(d[0], i)\n                            });\n                        })\n                        .on('mouseout', function(d,i) {\n                            if (needsUpdate || !data[d[0].series]) return 0; //check if this is a dummy point\n                            var series = data[d[0].series],\n                                point  = series.values[i];\n\n                            dispatch.elementMouseout({\n                                point: point,\n                                series: series,\n                                pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],//TODO: make this pos base on the page\n                                relativePos: [x(getX(point, i)) + margin.left, y(getY(point, i)) + margin.top],\n                                seriesIndex: d[0].series,\n                                pointIndex: i,\n                                color: color(d[0], i)\n                            });\n                        });\n                }\n            }\n\n            needsUpdate = true;\n            var groups = wrap.select('.nv-groups').selectAll('.nv-group')\n                .data(function(d) { return d }, function(d) { return d.key });\n            groups.enter().append('g')\n                .style('stroke-opacity', 1e-6)\n                .style('fill-opacity', 1e-6);\n            groups.exit()\n                .remove();\n            groups\n                .attr('class', function(d,i) {\n                    return (d.classed || '') + ' nv-group nv-series-' + i;\n                })\n                .classed('nv-noninteractive', !interactive)\n                .classed('hover', function(d) { return d.hover });\n            groups.watchTransition(renderWatch, 'scatter: groups')\n                .style('fill', function(d,i) { return color(d, i) })\n                .style('stroke', function(d,i) { return d.pointBorderColor || pointBorderColor || color(d, i) })\n                .style('stroke-opacity', 1)\n                .style('fill-opacity', .5);\n\n            // create the points, maintaining their IDs from the original data set\n            var points = groups.selectAll('path.nv-point')\n                .data(function(d) {\n                    return d.values.map(\n                        function (point, pointIndex) {\n                            return [point, pointIndex]\n                        }).filter(\n                            function(pointArray, pointIndex) {\n                                return pointActive(pointArray[0], pointIndex)\n                            })\n                    });\n            points.enter().append('path')\n                .attr('class', function (d) {\n                    return 'nv-point nv-point-' + d[1];\n                })\n                .style('fill', function (d) { return d.color })\n                .style('stroke', function (d) { return d.color })\n                .attr('transform', function(d) {\n                    return 'translate(' + nv.utils.NaNtoZero(x0(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y0(getY(d[0],d[1]))) + ')'\n                })\n                .attr('d',\n                    nv.utils.symbol()\n                    .type(function(d) { return getShape(d[0]); })\n                    .size(function(d) { return z(getSize(d[0],d[1])) })\n            );\n            points.exit().each(delCache).remove();\n            groups.exit().selectAll('path.nv-point')\n                .watchTransition(renderWatch, 'scatter exit')\n                .attr('transform', function(d) {\n                    return 'translate(' + nv.utils.NaNtoZero(x(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'\n                })\n                .remove();\n\n            //============================================================\n            // Point Update Optimisation Notes\n            //------------------------------------------------------------\n            // The following update selections are filtered with getDiffs\n            // (defined at the top of this file) this brings a performance\n            // benefit for charts with large data sets that accumulate a\n            // subset of changes or additions over time.\n            //\n            // Uneccesary and expensive DOM calls are avoided by culling\n            // unchanged points from the selection in exchange for the\n            // cheaper overhead of caching and diffing each point first.\n            //\n            // Due to the way D3 and NVD3 work, other global changes need\n            // to be considered in addition to local point properties.\n            // This is a potential source of bugs (if any of the global\n            // changes that possibly affect points are missed).\n\n            // Update Point Positions [x, y]\n            points.filter(function (d) {\n                // getDiffs must always be called to update cache\n                return getDiffs(d, 'x', getX, 'y', getY) ||\n                    scaleDiff || sizeDiff || domainDiff;\n            })\n            .watchTransition(renderWatch, 'scatter points')\n            .attr('transform', function (d) {\n                return 'translate(' +\n                    nv.utils.NaNtoZero(x(getX(d[0], d[1]))) + ',' +\n                    nv.utils.NaNtoZero(y(getY(d[0], d[1]))) + ')'\n            });\n\n            // Update Point Appearance [shape, size]\n            points.filter(function (d) {\n                // getDiffs must always be called to update cache\n                return getDiffs(d, 'shape', getShape, 'size', getSize) ||\n                    scaleDiff || sizeDiff || domainDiff;\n            })\n            .watchTransition(renderWatch, 'scatter points')\n            .attr('d', nv.utils.symbol()\n                .type(function (d) { return getShape(d[0]) })\n                .size(function (d) { return z(getSize(d[0], d[1])) })\n            );\n\n            // add label a label to scatter chart\n            if(showLabels)\n            {\n                var titles =  groups.selectAll('.nv-label')\n                    .data(function(d) {\n                        return d.values.map(\n                            function (point, pointIndex) {\n                                return [point, pointIndex]\n                            }).filter(\n                                function(pointArray, pointIndex) {\n                                    return pointActive(pointArray[0], pointIndex)\n                                })\n                        });\n\n                titles.enter().append('text')\n                    .style('fill', function (d,i) {\n                        return d.color })\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 1)\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x0(getX(d[0],d[1]))) + Math.sqrt(z(getSize(d[0],d[1]))/Math.PI) + 2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y0(getY(d[0],d[1]))) + ')';\n                    })\n                    .text(function(d,i){\n                        return d[0].label;});\n\n                titles.exit().remove();\n                groups.exit().selectAll('path.nv-label')\n                    .watchTransition(renderWatch, 'scatter exit')\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')';\n                    })\n                    .remove();\n               titles.each(function(d) {\n                  d3.select(this)\n                    .classed('nv-label', true)\n                    .classed('nv-label-' + d[1], false)\n                    .classed('hover',false);\n                });\n                titles.watchTransition(renderWatch, 'scatter labels')\n                    .text(function(d,i){ \n                        return d[0].label;})\n                    .attr('transform', function(d) {\n                        var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;\n                        return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'\n                    });\n            }\n\n            // Delay updating the invisible interactive layer for smoother animation\n            if( interactiveUpdateDelay )\n            {\n                clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer\n                timeoutID = setTimeout(updateInteractiveLayer, interactiveUpdateDelay );\n            }\n            else\n            {\n                updateInteractiveLayer();\n            }\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n            z0 = z.copy();\n\n            width0 = width;\n            height0 = height;\n\n        });\n        renderWatch.renderEnd('scatter immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // utility function calls provided by this chart\n    chart._calls = new function() {\n        this.clearHighlights = function () {\n            nv.dom.write(function() {\n                container.selectAll(\".nv-point.hover\").classed(\"hover\", false);\n            });\n            return null;\n        };\n        this.highlightPoint = function (seriesIndex, pointIndex, isHoverOver) {\n            nv.dom.write(function() {\n                container.select('.nv-groups')\n                  .selectAll(\".nv-series-\" + seriesIndex)\n                  .selectAll(\".nv-point-\" + pointIndex)\n                  .classed(\"hover\", isHoverOver);\n            });\n        };\n    };\n\n    // trigger calls from events too\n    dispatch.on('elementMouseover.point', function(d) {\n        if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,true);\n    });\n\n    dispatch.on('elementMouseout.point', function(d) {\n        if (interactive) chart._calls.highlightPoint(d.seriesIndex,d.pointIndex,false);\n    });\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:        {get: function(){return width;}, set: function(_){width=_;}},\n        height:       {get: function(){return height;}, set: function(_){height=_;}},\n        xScale:       {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:       {get: function(){return y;}, set: function(_){y=_;}},\n        pointScale:   {get: function(){return z;}, set: function(_){z=_;}},\n        xDomain:      {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:      {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        pointDomain:  {get: function(){return sizeDomain;}, set: function(_){sizeDomain=_;}},\n        xRange:       {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:       {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        pointRange:   {get: function(){return sizeRange;}, set: function(_){sizeRange=_;}},\n        forceX:       {get: function(){return forceX;}, set: function(_){forceX=_;}},\n        forceY:       {get: function(){return forceY;}, set: function(_){forceY=_;}},\n        forcePoint:   {get: function(){return forceSize;}, set: function(_){forceSize=_;}},\n        interactive:  {get: function(){return interactive;}, set: function(_){interactive=_;}},\n        pointActive:  {get: function(){return pointActive;}, set: function(_){pointActive=_;}},\n        padDataOuter: {get: function(){return padDataOuter;}, set: function(_){padDataOuter=_;}},\n        padData:      {get: function(){return padData;}, set: function(_){padData=_;}},\n        clipEdge:     {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        clipVoronoi:  {get: function(){return clipVoronoi;}, set: function(_){clipVoronoi=_;}},\n        clipRadius:   {get: function(){return clipRadius;}, set: function(_){clipRadius=_;}},\n        showVoronoi:   {get: function(){return showVoronoi;}, set: function(_){showVoronoi=_;}},\n        id:           {get: function(){return id;}, set: function(_){id=_;}},\n        interactiveUpdateDelay: {get:function(){return interactiveUpdateDelay;}, set: function(_){interactiveUpdateDelay=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){ showLabels = _;}},\n        pointBorderColor: {get: function(){return pointBorderColor;}, set: function(_){pointBorderColor=_;}},\n\n        // simple functor options\n        x:     {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}},\n        y:     {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}},\n        pointSize: {get: function(){return getSize;}, set: function(_){getSize = d3.functor(_);}},\n        pointShape: {get: function(){return getShape;}, set: function(_){getShape = d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        useVoronoi: {get: function(){return useVoronoi;}, set: function(_){\n            useVoronoi = _;\n            if (useVoronoi === false) {\n                clipVoronoi = false;\n            }\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/scatterChart.js",
    "content": "\nnv.models.scatterChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var scatter      = nv.models.scatter()\n        , xAxis        = nv.models.axis()\n        , yAxis        = nv.models.axis()\n        , legend       = nv.models.legend()\n        , distX        = nv.models.distribution()\n        , distY        = nv.models.distribution()\n        , tooltip      = nv.models.tooltip()\n        ;\n\n    var margin       = {top: 30, right: 20, bottom: 50, left: 75}\n        , marginTop = null\n        , width        = null\n        , height       = null\n        , container    = null\n        , color        = nv.utils.defaultColor()\n        , x            = scatter.xScale()\n        , y            = scatter.yScale()\n        , showDistX    = false\n        , showDistY    = false\n        , showLegend   = true\n        , showXAxis    = true\n        , showYAxis    = true\n        , rightAlignYAxis = false\n        , state = nv.utils.state()\n        , defaultState = null\n        , dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')\n        , noData       = null\n        , duration = 250\n        , showLabels    = false\n        ;\n\n    scatter.xScale(x).yScale(y);\n    xAxis.orient('bottom').tickPadding(10);\n    yAxis\n        .orient((rightAlignYAxis) ? 'right' : 'left')\n        .tickPadding(10)\n    ;\n    distX.axis('x');\n    distY.axis('y');\n    tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        });\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var x0, y0\n        , renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled })\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n        if (showDistX) renderWatch.models(distX);\n        if (showDistY) renderWatch.models(distY);\n\n        selection.each(function(data) {\n            var that = this;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0)\n                    container.call(chart);\n                else\n                    container.transition().duration(duration).call(chart);\n            };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disableddisabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display noData message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container);\n                renderWatch.renderEnd('scatter immediate');\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatterChart nv-chart-' + scatter.id());\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            // background for pointer events\n            gEnter.append('rect').attr('class', 'nvd3 nv-background').style(\"pointer-events\",\"none\");\n\n            gEnter.append('g').attr('class', 'nv-x nv-axis');\n            gEnter.append('g').attr('class', 'nv-y nv-axis');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n            gEnter.append('g').attr('class', 'nv-regressionLinesWrap');\n            gEnter.append('g').attr('class', 'nv-distWrap');\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = availableWidth;\n                legend.width(legendWidth);\n\n                wrap.select('.nv-legendWrap')\n                    .datum(data)\n                    .call(legend);\n\n                if (!marginTop && legend.height() !== margin.top) {\n                    margin.top = legend.height();\n                    availableHeight = nv.utils.availableHeight(height, container, margin);\n                }\n\n                wrap.select('.nv-legendWrap')\n                    .attr('transform', 'translate(0' + ',' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            scatter\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    d.color = d.color || color(d, i);\n                    return d.color;\n                }).filter(function(d,i) { return !data[i].disabled }))\n                .showLabels(showLabels);\n\n            wrap.select('.nv-scatterWrap')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(scatter);\n\n\n            wrap.select('.nv-regressionLinesWrap')\n                .attr('clip-path', 'url(#nv-edge-clip-' + scatter.id() + ')');\n\n            var regWrap = wrap.select('.nv-regressionLinesWrap').selectAll('.nv-regLines')\n                .data(function (d) {\n                    return d;\n                });\n\n            regWrap.enter().append('g').attr('class', 'nv-regLines');\n\n            var regLine = regWrap.selectAll('.nv-regLine')\n                .data(function (d) {\n                    return [d]\n                });\n\n            regLine.enter()\n                .append('line').attr('class', 'nv-regLine')\n                .style('stroke-opacity', 0);\n\n            // don't add lines unless we have slope and intercept to use\n            regLine.filter(function(d) {\n                return d.intercept && d.slope;\n            })\n                .watchTransition(renderWatch, 'scatterPlusLineChart: regline')\n                .attr('x1', x.range()[0])\n                .attr('x2', x.range()[1])\n                .attr('y1', function (d, i) {\n                    return y(x.domain()[0] * d.slope + d.intercept)\n                })\n                .attr('y2', function (d, i) {\n                    return y(x.domain()[1] * d.slope + d.intercept)\n                })\n                .style('stroke', function (d, i, j) {\n                    return color(d, j)\n                })\n                .style('stroke-opacity', function (d, i) {\n                    return (d.disabled || typeof d.slope === 'undefined' || typeof d.intercept === 'undefined') ? 0 : 1\n                });\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis\n                    .scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight , 0);\n\n                g.select('.nv-x.nv-axis')\n                    .attr('transform', 'translate(0,' + y.range()[0] + ')')\n                    .call(xAxis);\n            }\n\n            if (showYAxis) {\n                yAxis\n                    .scale(y)\n                    ._ticks( nv.utils.calcTicksY(availableHeight/36, data) )\n                    .tickSize( -availableWidth, 0);\n\n                g.select('.nv-y.nv-axis')\n                    .call(yAxis);\n            }\n\n            // Setup Distribution\n            distX\n                .getData(scatter.x())\n                .scale(x)\n                .width(availableWidth)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n            gEnter.select('.nv-distWrap').append('g')\n                .attr('class', 'nv-distributionX');\n            g.select('.nv-distributionX')\n                .attr('transform', 'translate(0,' + y.range()[0] + ')')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(distX)\n                .style('opacity', function() { return showDistX ? '1' : '1e-6'; })\n                .watchTransition(renderWatch, 'scatterPlusLineChart')\n                .style('opacity', function() { return showDistX ? '1' : '1e-6'; })\n\n\n            distY\n                .getData(scatter.y())\n                .scale(y)\n                .width(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled }));\n            gEnter.select('.nv-distWrap').append('g')\n                .attr('class', 'nv-distributionY');\n            g.select('.nv-distributionY')\n                .attr('transform', 'translate(' + (rightAlignYAxis ? availableWidth : -distY.size() ) + ',0)')\n                .datum(data.filter(function(d) { return !d.disabled }))\n                .call(distY)\n                .style('opacity', function() { return showDistY ? '1' : '1e-6'; })\n                .watchTransition(renderWatch, 'scatterPlusLineChart')\n                .style('opacity', function() { return showDistY ? '1' : '1e-6'; })\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n                if (typeof e.disabled !== 'undefined') {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n                    state.disabled = e.disabled;\n                }\n                chart.update();\n            });\n\n            // mouseover needs availableHeight so we just keep scatter mouse events inside the chart block\n            scatter.dispatch.on('elementMouseout.tooltip', function(evt) {\n                tooltip.hidden(true);\n                container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                    .attr('y1', 0);\n                container.select('.nv-chart-' + scatter.id() + ' .nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                    .attr('x2', distY.size());\n            });\n\n            scatter.dispatch.on('elementMouseover.tooltip', function(evt) {\n                container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)\n                    .attr('y1', evt.relativePos[1] - availableHeight);\n                container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)\n                    .attr('x2', evt.relativePos[0] + distX.size());\n                tooltip.data(evt).hidden(false);\n            });\n\n            //store old scales for use in transitions on update\n            x0 = x.copy();\n            y0 = y.copy();\n\n        });\n\n        renderWatch.renderEnd('scatter with line immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    chart.legend = legend;\n    chart.xAxis = xAxis;\n    chart.yAxis = yAxis;\n    chart.distX = distX;\n    chart.distY = distY;\n    chart.tooltip = tooltip;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        container:  {get: function(){return container;}, set: function(_){container=_;}},\n        showDistX:  {get: function(){return showDistX;}, set: function(_){showDistX=_;}},\n        showDistY:  {get: function(){return showDistY;}, set: function(_){showDistY=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        showXAxis:  {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:  {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:     {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:     {get: function(){return noData;}, set: function(_){noData=_;}},\n        duration:   {get: function(){return duration;}, set: function(_){duration=_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( (_) ? 'right' : 'left');\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            distX.color(color);\n            distY.color(color);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/sparkline.js",
    "content": "\nnv.models.sparkline = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 2, right: 0, bottom: 2, left: 0}\n        , width = 400\n        , height = 32\n        , container = null\n        , animate = true\n        , x = d3.scale.linear()\n        , y = d3.scale.linear()\n        , getX = function(d) { return d.x }\n        , getY = function(d) { return d.y }\n        , color = nv.utils.getColor(['#000'])\n        , xDomain\n        , yDomain\n        , xRange\n        , yRange\n        , showMinMaxPoints = true\n        , showCurrentPoint = true\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    \n    function chart(selection) {\n        renderWatch.reset();\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x   .domain(xDomain || d3.extent(data, getX ))\n                .range(xRange || [0, availableWidth]);\n\n            y   .domain(yDomain || d3.extent(data, getY ))\n                .range(yRange || [availableHeight, 0]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-sparkline').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparkline');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')\n\n            var paths = wrap.selectAll('path')\n                .data(function(d) { return [d] });\n            paths.enter().append('path');\n            paths.exit().remove();\n            paths\n                .style('stroke', function(d,i) { return d.color || color(d, i) })\n                .attr('d', d3.svg.line()\n                    .x(function(d,i) { return x(getX(d,i)) })\n                    .y(function(d,i) { return y(getY(d,i)) })\n            );\n\n            // TODO: Add CURRENT data point (Need Min, Mac, Current / Most recent)\n            var points = wrap.selectAll('circle.nv-point')\n                .data(function(data) {\n                    var yValues = data.map(function(d, i) { return getY(d,i); });\n                    function pointIndex(index) {\n                        if (index != -1) {\n                            var result = data[index];\n                            result.pointIndex = index;\n                            return result;\n                        } else {\n                            return null;\n                        }\n                    }\n                    var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])),\n                        minPoint = pointIndex(yValues.indexOf(y.domain()[0])),\n                        currentPoint = pointIndex(yValues.length - 1);\n                    return [(showMinMaxPoints ? minPoint : null), (showMinMaxPoints ? maxPoint : null), (showCurrentPoint ? currentPoint : null)].filter(function (d) {return d != null;});\n                });\n            points.enter().append('circle');\n            points.exit().remove();\n            points\n                .attr('cx', function(d,i) { return x(getX(d,d.pointIndex)) })\n                .attr('cy', function(d,i) { return y(getY(d,d.pointIndex)) })\n                .attr('r', 2)\n                .attr('class', function(d,i) {\n                    return getX(d, d.pointIndex) == x.domain()[1] ? 'nv-point nv-currentValue' :\n                            getY(d, d.pointIndex) == y.domain()[0] ? 'nv-point nv-minValue' : 'nv-point nv-maxValue'\n                });\n        });\n        \n        renderWatch.renderEnd('sparkline immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:            {get: function(){return width;}, set: function(_){width=_;}},\n        height:           {get: function(){return height;}, set: function(_){height=_;}},\n        xDomain:          {get: function(){return xDomain;}, set: function(_){xDomain=_;}},\n        yDomain:          {get: function(){return yDomain;}, set: function(_){yDomain=_;}},\n        xRange:           {get: function(){return xRange;}, set: function(_){xRange=_;}},\n        yRange:           {get: function(){return yRange;}, set: function(_){yRange=_;}},\n        xScale:           {get: function(){return x;}, set: function(_){x=_;}},\n        yScale:           {get: function(){return y;}, set: function(_){y=_;}},\n        animate:          {get: function(){return animate;}, set: function(_){animate=_;}},\n        showMinMaxPoints: {get: function(){return showMinMaxPoints;}, set: function(_){showMinMaxPoints=_;}},\n        showCurrentPoint: {get: function(){return showCurrentPoint;}, set: function(_){showCurrentPoint=_;}},\n\n        //functor options\n        x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},\n        y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }}\n    });\n\n    chart.dispatch = dispatch;\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/sparklinePlus.js",
    "content": "\nnv.models.sparklinePlus = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sparkline = nv.models.sparkline();\n\n    var margin = {top: 15, right: 100, bottom: 10, left: 50}\n        , width = null\n        , height = null\n        , x\n        , y\n        , index = []\n        , paused = false\n        , xTickFormat = d3.format(',r')\n        , yTickFormat = d3.format(',.2f')\n        , showLastValue = true\n        , alignValue = true\n        , rightAlignValue = false\n        , noData = null\n        , dispatch = d3.dispatch('renderEnd')\n        ;\n        \n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(sparkline);\n        selection.each(function(data) {\n            var container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() { container.call(chart); };\n            chart.container = this;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            var currentValue = sparkline.y()(data[data.length-1], data.length-1);\n\n            // Setup Scales\n            x = sparkline.xScale();\n            y = sparkline.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-sparklineplus').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sparklineplus');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-sparklineWrap');\n            gEnter.append('g').attr('class', 'nv-valueWrap');\n            gEnter.append('g').attr('class', 'nv-hoverArea');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // Main Chart Component(s)\n            var sparklineWrap = g.select('.nv-sparklineWrap');\n\n            sparkline.width(availableWidth).height(availableHeight);\n            sparklineWrap.call(sparkline);\n\n            if (showLastValue) {\n                var valueWrap = g.select('.nv-valueWrap');\n                var value = valueWrap.selectAll('.nv-currentValue')\n                    .data([currentValue]);\n\n                value.enter().append('text').attr('class', 'nv-currentValue')\n                    .attr('dx', rightAlignValue ? -8 : 8)\n                    .attr('dy', '.9em')\n                    .style('text-anchor', rightAlignValue ? 'end' : 'start');\n\n                value\n                    .attr('x', availableWidth + (rightAlignValue ? margin.right : 0))\n                    .attr('y', alignValue ? function (d) {\n                        return y(d)\n                    } : 0)\n                    .style('fill', sparkline.color()(data[data.length - 1], data.length - 1))\n                    .text(yTickFormat(currentValue));\n            }\n\n            gEnter.select('.nv-hoverArea').append('rect')\n                .on('mousemove', sparklineHover)\n                .on('click', function() { paused = !paused })\n                .on('mouseout', function() { index = []; updateValueLine(); });\n\n            g.select('.nv-hoverArea rect')\n                .attr('transform', function(d) { return 'translate(' + -margin.left + ',' + -margin.top + ')' })\n                .attr('width', availableWidth + margin.left + margin.right)\n                .attr('height', availableHeight + margin.top);\n\n            //index is currently global (within the chart), may or may not keep it that way\n            function updateValueLine() {\n                if (paused) return;\n\n                var hoverValue = g.selectAll('.nv-hoverValue').data(index);\n\n                var hoverEnter = hoverValue.enter()\n                    .append('g').attr('class', 'nv-hoverValue')\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 0);\n\n                hoverValue.exit()\n                    .transition().duration(250)\n                    .style('stroke-opacity', 0)\n                    .style('fill-opacity', 0)\n                    .remove();\n\n                hoverValue\n                    .attr('transform', function(d) { return 'translate(' + x(sparkline.x()(data[d],d)) + ',0)' })\n                    .transition().duration(250)\n                    .style('stroke-opacity', 1)\n                    .style('fill-opacity', 1);\n\n                if (!index.length) return;\n\n                hoverEnter.append('line')\n                    .attr('x1', 0)\n                    .attr('y1', -margin.top)\n                    .attr('x2', 0)\n                    .attr('y2', availableHeight);\n\n                hoverEnter.append('text').attr('class', 'nv-xValue')\n                    .attr('x', -6)\n                    .attr('y', -margin.top)\n                    .attr('text-anchor', 'end')\n                    .attr('dy', '.9em');\n\n                g.select('.nv-hoverValue .nv-xValue')\n                    .text(xTickFormat(sparkline.x()(data[index[0]], index[0])));\n\n                hoverEnter.append('text').attr('class', 'nv-yValue')\n                    .attr('x', 6)\n                    .attr('y', -margin.top)\n                    .attr('text-anchor', 'start')\n                    .attr('dy', '.9em');\n\n                g.select('.nv-hoverValue .nv-yValue')\n                    .text(yTickFormat(sparkline.y()(data[index[0]], index[0])));\n            }\n\n            function sparklineHover() {\n                if (paused) return;\n\n                var pos = d3.mouse(this)[0] - margin.left;\n\n                function getClosestIndex(data, x) {\n                    var distance = Math.abs(sparkline.x()(data[0], 0) - x);\n                    var closestIndex = 0;\n                    for (var i = 0; i < data.length; i++){\n                        if (Math.abs(sparkline.x()(data[i], i) - x) < distance) {\n                            distance = Math.abs(sparkline.x()(data[i], i) - x);\n                            closestIndex = i;\n                        }\n                    }\n                    return closestIndex;\n                }\n\n                index = [getClosestIndex(data, Math.round(x.invert(pos)))];\n                updateValueLine();\n            }\n\n        });\n        renderWatch.renderEnd('sparklinePlus immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.sparkline = sparkline;\n\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:           {get: function(){return width;}, set: function(_){width=_;}},\n        height:          {get: function(){return height;}, set: function(_){height=_;}},\n        xTickFormat:     {get: function(){return xTickFormat;}, set: function(_){xTickFormat=_;}},\n        yTickFormat:     {get: function(){return yTickFormat;}, set: function(_){yTickFormat=_;}},\n        showLastValue:   {get: function(){return showLastValue;}, set: function(_){showLastValue=_;}},\n        alignValue:      {get: function(){return alignValue;}, set: function(_){alignValue=_;}},\n        rightAlignValue: {get: function(){return rightAlignValue;}, set: function(_){rightAlignValue=_;}},\n        noData:          {get: function(){return noData;}, set: function(_){noData=_;}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, sparkline);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/stackedArea.js",
    "content": "\nnv.models.stackedArea = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 960\n        , height = 500\n        , color = nv.utils.defaultColor() // a function that computes the color\n        , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user doesn't selet one\n        , container = null\n        , getX = function(d) { return d.x } // accessor to get the x value from a data point\n        , getY = function(d) { return d.y } // accessor to get the y value from a data point\n        , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null } // allows a line to be not continuous when it is not defined\n        , style = 'stack'\n        , offset = 'zero'\n        , order = 'default'\n        , interpolate = 'linear'  // controls the line interpolation\n        , clipEdge = false // if true, masks lines within x and y scale\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , scatter = nv.models.scatter()\n        , duration = 250\n        , transformData = function(d, y0, y) { d.display = { y: y, y0: y0 }; }\n        , areaY1 = function(d) { return y(d.display.y + d.display.y0) }\n        , dispatch =  d3.dispatch('areaClick', 'areaMouseover', 'areaMouseout','renderEnd', 'elementClick', 'elementMouseover', 'elementMouseout')\n        ;\n\n    scatter\n        .pointSize(2.2) // default size\n        .pointDomain([2.2, 2.2]) // all the same size by default\n    ;\n\n    /************************************\n     * offset:\n     *   'wiggle' (stream)\n     *   'zero' (stacked)\n     *   'expand' (normalize to 100%)\n     *   'silhouette' (simple centered)\n     *\n     * order:\n     *   'inside-out' (stream)\n     *   'default' (input order)\n     ************************************/\n\n    var renderWatch = nv.utils.renderWatch(dispatch, duration);\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(scatter);\n        selection.each(function(data) {\n            var availableWidth = width - margin.left - margin.right,\n                availableHeight = height - margin.top - margin.bottom;\n\n            container = d3.select(this);\n            nv.utils.initSVG(container);\n\n            // Setup Scales\n            x = scatter.xScale();\n            y = scatter.yScale();\n\n            var dataRaw = data;\n            // Injecting point index into each point because d3.layout.stack().out does not give index\n            data.forEach(function(aseries, i) {\n                aseries.seriesIndex = i;\n                aseries.values = aseries.values.map(function(d, j) {\n                    d.index = j;\n                    d.seriesIndex = i;\n                    return d;\n                });\n            });\n\n            var dataFiltered = data.filter(function(series) {\n                return !series.disabled;\n            });\n\n            data = d3.layout.stack()\n                .order(order)\n                .offset(offset)\n                .values(function(d) { return d.values })  //TODO: make values customizeable in EVERY model in this fashion\n                .x(getX)\n                .y(getY)\n                .out(transformData)\n            (dataFiltered);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-stackedarea').data([data]);\n            var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedarea');\n            var defsEnter = wrapEnter.append('defs');\n            var gEnter = wrapEnter.append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-areaWrap');\n            gEnter.append('g').attr('class', 'nv-scatterWrap');\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            // If the user has not specified forceY, make sure 0 is included in the domain\n            // Otherwise, use user-specified values for forceY\n            if (scatter.forceY().length == 0) {\n                scatter.forceY().push(0);\n            }\n\n            scatter\n                .width(availableWidth)\n                .height(availableHeight)\n                .x(getX)\n                .y(function(d) {\n                    if (d.display !== undefined) { return d.display.y + d.display.y0; }\n                })\n                .color(data.map(function(d,i) {\n                    d.color = d.color || color(d, d.seriesIndex);\n                    return d.color;\n                }));\n\n            var scatterWrap = g.select('.nv-scatterWrap')\n                .datum(data);\n\n            scatterWrap.call(scatter);\n\n            defsEnter.append('clipPath')\n                .attr('id', 'nv-edge-clip-' + id)\n                .append('rect');\n\n            wrap.select('#nv-edge-clip-' + id + ' rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            g.attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id + ')' : '');\n\n            var area = d3.svg.area()\n                .defined(defined)\n                .x(function(d,i)  { return x(getX(d,i)) })\n                .y0(function(d) {\n                    return y(d.display.y0)\n                })\n                .y1(areaY1)\n                .interpolate(interpolate);\n\n            var zeroArea = d3.svg.area()\n                .defined(defined)\n                .x(function(d,i)  { return x(getX(d,i)) })\n                .y0(function(d) { return y(d.display.y0) })\n                .y1(function(d) { return y(d.display.y0) });\n\n            var path = g.select('.nv-areaWrap').selectAll('path.nv-area')\n                .data(function(d) { return d });\n\n            path.enter().append('path').attr('class', function(d,i) { return 'nv-area nv-area-' + i })\n                .attr('d', function(d,i){\n                    return zeroArea(d.values, d.seriesIndex);\n                })\n                .on('mouseover', function(d,i) {\n                    d3.select(this).classed('hover', true);\n                    dispatch.areaMouseover({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                })\n                .on('mouseout', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.areaMouseout({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                })\n                .on('click', function(d,i) {\n                    d3.select(this).classed('hover', false);\n                    dispatch.areaClick({\n                        point: d,\n                        series: d.key,\n                        pos: [d3.event.pageX, d3.event.pageY],\n                        seriesIndex: d.seriesIndex\n                    });\n                });\n\n            path.exit().remove();\n            path.style('fill', function(d,i){\n                    return d.color || color(d, d.seriesIndex)\n                })\n                .style('stroke', function(d,i){ return d.color || color(d, d.seriesIndex) });\n            path.watchTransition(renderWatch,'stackedArea path')\n                .attr('d', function(d,i) {\n                    return area(d.values,i)\n                });\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            scatter.dispatch.on('elementMouseover.area', function(e) {\n                g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', true);\n            });\n            scatter.dispatch.on('elementMouseout.area', function(e) {\n                g.select('.nv-chart-' + id + ' .nv-area-' + e.seriesIndex).classed('hover', false);\n            });\n\n            //Special offset functions\n            chart.d3_stackedOffset_stackPercent = function(stackData) {\n                var n = stackData.length,    //How many series\n                    m = stackData[0].length,     //how many points per series\n                    i,\n                    j,\n                    o,\n                    y0 = [];\n\n                for (j = 0; j < m; ++j) { //Looping through all points\n                    for (i = 0, o = 0; i < dataRaw.length; i++) { //looping through all series\n                        o += getY(dataRaw[i].values[j]); //total y value of all series at a certian point in time.\n                    }\n\n                    if (o) for (i = 0; i < n; i++) { //(total y value of all series at point in time i) != 0\n                        stackData[i][j][1] /= o;\n                    } else { //(total y value of all series at point in time i) == 0\n                        for (i = 0; i < n; i++) {\n                            stackData[i][j][1] = 0;\n                        }\n                    }\n                }\n                for (j = 0; j < m; ++j) y0[j] = 0;\n                return y0;\n            };\n\n        });\n\n        renderWatch.renderEnd('stackedArea immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Global getters and setters\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n\n    scatter.dispatch.on('elementClick', function(){ dispatch.elementClick.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseover', function(){ dispatch.elementMouseover.apply(this, arguments); });\n    scatter.dispatch.on('elementMouseout', function(){ dispatch.elementMouseout.apply(this, arguments); });\n\n    chart.interpolate = function(_) {\n        if (!arguments.length) return interpolate;\n        interpolate = _;\n        return chart;\n    };\n\n    chart.duration = function(_) {\n        if (!arguments.length) return duration;\n        duration = _;\n        renderWatch.reset(duration);\n        scatter.duration(duration);\n        return chart;\n    };\n\n    chart.dispatch = dispatch;\n    chart.scatter = scatter;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        defined: {get: function(){return defined;}, set: function(_){defined=_;}},\n        clipEdge: {get: function(){return clipEdge;}, set: function(_){clipEdge=_;}},\n        offset:      {get: function(){return offset;}, set: function(_){offset=_;}},\n        order:    {get: function(){return order;}, set: function(_){order=_;}},\n        interpolate:    {get: function(){return interpolate;}, set: function(_){interpolate=_;}},\n\n        // simple functor options\n        x:     {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}},\n        y:     {get: function(){return getY;}, set: function(_){getY = d3.functor(_);}},\n\n        areaY1:     {get: function(){return areaY1;}, set: function(_){ areaY1 = d3.functor(_);}},\n        transformData:     {get: function(){return transformData;}, set: function(_){ transformData = d3.functor(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n        }},\n        style: {get: function(){return style;}, set: function(_){\n            style = _;\n            switch (style) {\n                case 'stack':\n                    chart.offset('zero');\n                    chart.order('default');\n                    break;\n                case 'stream':\n                    chart.offset('wiggle');\n                    chart.order('inside-out');\n                    break;\n                case 'stream-center':\n                    chart.offset('silhouette');\n                    chart.order('inside-out');\n                    break;\n                case 'expand':\n                    chart.offset('expand');\n                    chart.order('default');\n                    break;\n                case 'stack_percent':\n                    chart.offset(chart.d3_stackedOffset_stackPercent);\n                    chart.order('default');\n                    break;\n            }\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            scatter.duration(duration);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, scatter);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n"
  },
  {
    "path": "src/models/stackedAreaChart.js",
    "content": "\nnv.models.stackedAreaChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var stacked = nv.models.stackedArea()\n        , xAxis = nv.models.axis()\n        , yAxis = nv.models.axis()\n        , legend = nv.models.legend()\n        , controls = nv.models.legend()\n        , interactiveLayer = nv.interactiveGuideline()\n        , tooltip = nv.models.tooltip()\n        , focus = nv.models.focus(nv.models.stackedArea())\n        ;\n\n    var margin = {top: 10, right: 25, bottom: 50, left: 60}\n        , marginTop = null\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showControls = true\n        , showLegend = true\n        , legendPosition = 'top'\n        , showXAxis = true\n        , showYAxis = true\n        , rightAlignYAxis = false\n        , focusEnable = false\n        , useInteractiveGuideline = false\n        , showTotalInTooltip = true\n        , totalLabel = 'TOTAL'\n        , x //can be accessed via chart.xScale()\n        , y //can be accessed via chart.yScale()\n        , state = nv.utils.state()\n        , defaultState = null\n        , noData = null\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')\n        , controlWidth = 250\n        , controlOptions = ['Stacked','Stream','Expanded']\n        , controlLabels = {}\n        , duration = 250\n        ;\n\n    state.style = stacked.style();\n    xAxis.orient('bottom').tickPadding(7);\n    yAxis.orient((rightAlignYAxis) ? 'right' : 'left');\n\n    tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return yAxis.tickFormat()(d, i);\n        });\n\n    interactiveLayer.tooltip\n        .headerFormatter(function(d, i) {\n            return xAxis.tickFormat()(d, i);\n        })\n        .valueFormatter(function(d, i) {\n            return d == null ? \"N/A\" : yAxis.tickFormat()(d, i);\n        });\n\n    var oldYTickFormat = null,\n        oldValueFormatter = null;\n\n    controls.updateState(false);\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n    var style = stacked.style();\n\n    var stateGetter = function(data) {\n        return function(){\n            return {\n                active: data.map(function(d) { return !d.disabled }),\n                style: stacked.style()\n            };\n        }\n    };\n\n    var stateSetter = function(data) {\n        return function(state) {\n            if (state.style !== undefined)\n                style = state.style;\n            if (state.active !== undefined)\n                data.forEach(function(series,i) {\n                    series.disabled = !state.active[i];\n                });\n        }\n    };\n\n    var percentFormatter = d3.format('%');\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(stacked);\n        if (showXAxis) renderWatch.models(xAxis);\n        if (showYAxis) renderWatch.models(yAxis);\n\n        selection.each(function(data) {\n            var container = d3.select(this),\n                that = this;\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin),\n                availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n\n            chart.update = function() { container.transition().duration(duration).call(chart); };\n            chart.container = this;\n\n            state\n                .setter(stateSetter(data), chart.update)\n                .getter(stateGetter(data))\n                .update();\n\n            // DEPRECATED set state.disabled\n            state.disabled = data.map(function(d) { return !!d.disabled });\n\n            if (!defaultState) {\n                var key;\n                defaultState = {};\n                for (key in state) {\n                    if (state[key] instanceof Array)\n                        defaultState[key] = state[key].slice(0);\n                    else\n                        defaultState[key] = state[key];\n                }\n            }\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length || !data.filter(function(d) { return d.values.length }).length) {\n                nv.utils.noData(chart, container)\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n            // Setup Scales\n            x = stacked.xScale();\n            y = stacked.yScale();\n\n            // Setup containers and skeleton of chart\n            var wrap = container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]);\n            var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-stackedAreaChart').append('g');\n            var g = wrap.select('g');\n\n            gEnter.append('g').attr('class', 'nv-legendWrap');\n            gEnter.append('g').attr('class', 'nv-controlsWrap');\n\n            var focusEnter = gEnter.append('g').attr('class', 'nv-focus');\n            focusEnter.append('g').attr('class', 'nv-background').append('rect');\n            focusEnter.append('g').attr('class', 'nv-x nv-axis');\n            focusEnter.append('g').attr('class', 'nv-y nv-axis');\n            focusEnter.append('g').attr('class', 'nv-stackedWrap');\n            focusEnter.append('g').attr('class', 'nv-interactive');\n\n            // g.select(\"rect\").attr(\"width\",availableWidth).attr(\"height\",availableHeight);\n\n            var contextEnter = gEnter.append('g').attr('class', 'nv-focusWrap');\n\n            // Legend\n            if (!showLegend) {\n                g.select('.nv-legendWrap').selectAll('*').remove();\n            } else {\n                var legendWidth = (showControls && legendPosition === 'top') ? availableWidth - controlWidth : availableWidth;\n\n                legend.width(legendWidth);\n                g.select('.nv-legendWrap').datum(data).call(legend);\n\n                if (legendPosition === 'bottom') {\n                \tvar xAxisHeight = xAxis.height();\n                   \tmargin.bottom = Math.max(legend.height() + xAxisHeight, margin.bottom);\n                   \tavailableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                \tvar legendTop = availableHeight + xAxisHeight;\n                    g.select('.nv-legendWrap')\n                        .attr('transform', 'translate(0,' + legendTop +')');\n                } else if (legendPosition === 'top') {\n                    if (!marginTop && margin.top != legend.height()) {\n                        margin.top = legend.height();\n                        availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                    }\n\n                    g.select('.nv-legendWrap')\n                    \t.attr('transform', 'translate(' + (availableWidth-legendWidth) + ',' + (-margin.top) +')');\n                }\n            }\n\n            // Controls\n            if (!showControls) {\n                 g.select('.nv-controlsWrap').selectAll('*').remove();\n            } else {\n                var controlsData = [\n                    {\n                        key: controlLabels.stacked || 'Stacked',\n                        metaKey: 'Stacked',\n                        disabled: stacked.style() != 'stack',\n                        style: 'stack'\n                    },\n                    {\n                        key: controlLabels.stream || 'Stream',\n                        metaKey: 'Stream',\n                        disabled: stacked.style() != 'stream',\n                        style: 'stream'\n                    },\n                    {\n                        key: controlLabels.stream_center || 'Stream Center',\n                        metaKey: 'Stream_Center',\n                        disabled: stacked.style() != 'stream_center',\n                        style: 'stream-center'\n                    },\n                    {\n                        key: controlLabels.expanded || 'Expanded',\n                        metaKey: 'Expanded',\n                        disabled: stacked.style() != 'expand',\n                        style: 'expand'\n                    },\n                    {\n                        key: controlLabels.stack_percent || 'Stack %',\n                        metaKey: 'Stack_Percent',\n                        disabled: stacked.style() != 'stack_percent',\n                        style: 'stack_percent'\n                    }\n                ];\n\n                controlWidth = (controlOptions.length/3) * 260;\n                controlsData = controlsData.filter(function(d) {\n                    return controlOptions.indexOf(d.metaKey) !== -1;\n                });\n\n                controls\n                    .width( controlWidth )\n                    .color(['#444', '#444', '#444']);\n\n                g.select('.nv-controlsWrap')\n                    .datum(controlsData)\n                    .call(controls);\n\n                var requiredTop = Math.max(controls.height(), showLegend && (legendPosition === 'top') ? legend.height() : 0);\n\n                if ( margin.top != requiredTop ) {\n                    margin.top = requiredTop;\n                    availableHeight = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focus.height() : 0);\n                }\n\n                g.select('.nv-controlsWrap')\n                    .attr('transform', 'translate(0,' + (-margin.top) +')');\n            }\n\n            wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');\n\n            if (rightAlignYAxis) {\n                g.select(\".nv-y.nv-axis\")\n                    .attr(\"transform\", \"translate(\" + availableWidth + \",0)\");\n            }\n\n            //Set up interactive layer\n            if (useInteractiveGuideline) {\n                interactiveLayer\n                    .width(availableWidth)\n                    .height(availableHeight)\n                    .margin({left: margin.left, top: margin.top})\n                    .svgContainer(container)\n                    .xScale(x);\n                wrap.select(\".nv-interactive\").call(interactiveLayer);\n            }\n\n            g.select('.nv-focus .nv-background rect')\n                .attr('width', availableWidth)\n                .attr('height', availableHeight);\n\n            stacked\n                .width(availableWidth)\n                .height(availableHeight)\n                .color(data.map(function(d,i) {\n                    return d.color || color(d, i);\n                }).filter(function(d,i) { return !data[i].disabled; }));\n\n            var stackedWrap = g.select('.nv-focus .nv-stackedWrap')\n                .datum(data.filter(function(d) { return !d.disabled; }));\n\n            // Setup Axes\n            if (showXAxis) {\n                xAxis.scale(x)\n                    ._ticks( nv.utils.calcTicksX(availableWidth/100, data) )\n                    .tickSize( -availableHeight, 0);\n            }\n\n            if (showYAxis) {\n                var ticks;\n                if (stacked.offset() === 'wiggle') {\n                    ticks = 0;\n                }\n                else {\n                    ticks = nv.utils.calcTicksY(availableHeight/36, data);\n                }\n                yAxis.scale(y)\n                    ._ticks(ticks)\n                    .tickSize(-availableWidth, 0);\n            }\n\n            //============================================================\n            // Update Axes\n            //============================================================\n            function updateXAxis() {\n                if(showXAxis) {\n                    g.select('.nv-focus .nv-x.nv-axis')\n                        .attr('transform', 'translate(0,' + availableHeight + ')')\n                        .transition()\n                        .duration(duration)\n                        .call(xAxis)\n                        ;\n                }\n            }\n\n            function updateYAxis() {\n                if(showYAxis) {\n                    if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') {\n                        var currentFormat = yAxis.tickFormat();\n\n                        if ( !oldYTickFormat || currentFormat !== percentFormatter )\n                            oldYTickFormat = currentFormat;\n\n                        //Forces the yAxis to use percentage in 'expand' mode.\n                        yAxis.tickFormat(percentFormatter);\n                    }\n                    else {\n                        if (oldYTickFormat) {\n                            yAxis.tickFormat(oldYTickFormat);\n                            oldYTickFormat = null;\n                        }\n                    }\n\n                    g.select('.nv-focus .nv-y.nv-axis')\n                    .transition().duration(0)\n                    .call(yAxis);\n                }\n            }\n\n            //============================================================\n            // Update Focus\n            //============================================================\n            if(!focusEnable) {\n                stackedWrap.transition().call(stacked);\n                updateXAxis();\n                updateYAxis();\n            } else {\n                focus.width(availableWidth);\n                g.select('.nv-focusWrap')\n                    .attr('transform', 'translate(0,' + ( availableHeight + margin.bottom + focus.margin().top) + ')')\n                    .datum(data.filter(function(d) { return !d.disabled; }))\n                    .call(focus);\n                var extent = focus.brush.empty() ? focus.xDomain() : focus.brush.extent();\n                if(extent !== null){\n                    onBrush(extent);\n                }\n            }\n\n            //============================================================\n            // Event Handling/Dispatching (in chart's scope)\n            //------------------------------------------------------------\n\n            stacked.dispatch.on('areaClick.toggle', function(e) {\n                if (data.filter(function(d) { return !d.disabled }).length === 1)\n                    data.forEach(function(d) {\n                        d.disabled = false;\n                    });\n                else\n                    data.forEach(function(d,i) {\n                        d.disabled = (i != e.seriesIndex);\n                    });\n\n                state.disabled = data.map(function(d) { return !!d.disabled });\n                dispatch.stateChange(state);\n\n                chart.update();\n            });\n\n            legend.dispatch.on('stateChange', function(newState) {\n                for (var key in newState)\n                    state[key] = newState[key];\n                dispatch.stateChange(state);\n                chart.update();\n            });\n\n            controls.dispatch.on('legendClick', function(d,i) {\n                if (!d.disabled) return;\n\n                controlsData = controlsData.map(function(s) {\n                    s.disabled = true;\n                    return s;\n                });\n                d.disabled = false;\n\n                stacked.style(d.style);\n\n\n                state.style = stacked.style();\n                dispatch.stateChange(state);\n\n                chart.update();\n            });\n\n            interactiveLayer.dispatch.on('elementMousemove', function(e) {\n                stacked.clearHighlights();\n                var singlePoint, pointIndex, pointXLocation, allData = [], valueSum = 0, allNullValues = true, atleastOnePoint = false;\n                data\n                    .filter(function(series, i) {\n                        series.seriesIndex = i;\n                        return !series.disabled;\n                    })\n                    .forEach(function(series,i) {\n                        pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());\n                        var point = series.values[pointIndex];\n                        var pointYValue = chart.y()(point, pointIndex);\n                        if (pointYValue != null && pointYValue > 0) {\n                            stacked.highlightPoint(i, pointIndex, true);\n                            atleastOnePoint = true;\n                        }\n\n                        // Draw at least one point if all values are zero.\n                        if (i === (data.length - 1) && !atleastOnePoint) {\n                            stacked.highlightPoint(i, pointIndex, true);\n                        }\n                        if (typeof point === 'undefined') return;\n                        if (typeof singlePoint === 'undefined') singlePoint = point;\n                        if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));\n\n                        //If we are in 'expand' mode, use the stacked percent value instead of raw value.\n                        var tooltipValue = (stacked.style() == 'expand') ? point.display.y : chart.y()(point,pointIndex);\n                        allData.push({\n                            key: series.key,\n                            value: tooltipValue,\n                            color: color(series,series.seriesIndex),\n                            point: point\n                        });\n\n                        if (showTotalInTooltip && stacked.style() != 'expand' && tooltipValue != null) {\n                          valueSum += tooltipValue;\n                          allNullValues = false;\n                        };\n                    });\n\n                allData.reverse();\n\n                //Highlight the tooltip entry based on which stack the mouse is closest to.\n                if (allData.length > 2) {\n                    var yValue = chart.yScale().invert(e.mouseY);\n                    var yDistMax = Infinity, indexToHighlight = null;\n                    allData.forEach(function(series,i) {\n\n                        //To handle situation where the stacked area chart is negative, we need to use absolute values\n                        //when checking if the mouse Y value is within the stack area.\n                        yValue = Math.abs(yValue);\n                        var stackedY0 = Math.abs(series.point.display.y0);\n                        var stackedY = Math.abs(series.point.display.y);\n                        if ( yValue >= stackedY0 && yValue <= (stackedY + stackedY0))\n                        {\n                            indexToHighlight = i;\n                            return;\n                        }\n                    });\n                    if (indexToHighlight != null)\n                        allData[indexToHighlight].highlight = true;\n                }\n\n                //If we are not in 'expand' mode, add a 'Total' row to the tooltip.\n                if (showTotalInTooltip && stacked.style() != 'expand' && allData.length >= 2 && !allNullValues) {\n                    allData.push({\n                        key: totalLabel,\n                        value: valueSum,\n                        total: true\n                    });\n                }\n\n                var xValue = chart.x()(singlePoint,pointIndex);\n\n                var valueFormatter = interactiveLayer.tooltip.valueFormatter();\n                // Keeps track of the tooltip valueFormatter if the chart changes to expanded view\n                if (stacked.style() === 'expand' || stacked.style() === 'stack_percent') {\n                    if ( !oldValueFormatter ) {\n                        oldValueFormatter = valueFormatter;\n                    }\n                    //Forces the tooltip to use percentage in 'expand' mode.\n                    valueFormatter = d3.format(\".1%\");\n                }\n                else {\n                    if (oldValueFormatter) {\n                        valueFormatter = oldValueFormatter;\n                        oldValueFormatter = null;\n                    }\n                }\n\n                interactiveLayer.tooltip\n                    .valueFormatter(valueFormatter)\n                    .data(\n                    {\n                        value: xValue,\n                        series: allData\n                    }\n                )();\n\n                interactiveLayer.renderGuideLine(pointXLocation);\n\n            });\n\n            interactiveLayer.dispatch.on(\"elementMouseout\",function(e) {\n                stacked.clearHighlights();\n            });\n\n            /* Update `main' graph on brush update. */\n            focus.dispatch.on(\"onBrush\", function(extent) {\n                onBrush(extent);\n            });\n\n            // Update chart from a state object passed to event handler\n            dispatch.on('changeState', function(e) {\n\n                if (typeof e.disabled !== 'undefined' && data.length === e.disabled.length) {\n                    data.forEach(function(series,i) {\n                        series.disabled = e.disabled[i];\n                    });\n\n                    state.disabled = e.disabled;\n                }\n\n                if (typeof e.style !== 'undefined') {\n                    stacked.style(e.style);\n                    style = e.style;\n                }\n\n                chart.update();\n            });\n\n            //============================================================\n            // Functions\n            //------------------------------------------------------------\n\n            function onBrush(extent) {\n                // Update Main (Focus)\n                var stackedWrap = g.select('.nv-focus .nv-stackedWrap')\n                    .datum(\n                    data.filter(function(d) { return !d.disabled; })\n                        .map(function(d,i) {\n                            return {\n                                key: d.key,\n                                area: d.area,\n                                classed: d.classed,\n                                values: d.values.filter(function(d,i) {\n                                    return stacked.x()(d,i) >= extent[0] && stacked.x()(d,i) <= extent[1];\n                                }),\n                                disableTooltip: d.disableTooltip\n                            };\n                        })\n                );\n                stackedWrap.transition().duration(duration).call(stacked);\n\n                // Update Main (Focus) Axes\n                updateXAxis();\n                updateYAxis();\n            }\n\n        });\n\n        renderWatch.renderEnd('stacked Area chart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    stacked.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.point['x'] = stacked.x()(evt.point);\n        evt.point['y'] = stacked.y()(evt.point);\n        tooltip.data(evt).hidden(false);\n    });\n\n    stacked.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true)\n    });\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.stacked = stacked;\n    chart.legend = legend;\n    chart.controls = controls;\n    chart.xAxis = xAxis;\n    chart.x2Axis = focus.xAxis;\n    chart.yAxis = yAxis;\n    chart.y2Axis = focus.yAxis;\n    chart.interactiveLayer = interactiveLayer;\n    chart.tooltip = tooltip;\n    chart.focus = focus;\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},\n        legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},\n        showXAxis:      {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},\n        showYAxis:    {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},\n        defaultState:    {get: function(){return defaultState;}, set: function(_){defaultState=_;}},\n        noData:    {get: function(){return noData;}, set: function(_){noData=_;}},\n        showControls:    {get: function(){return showControls;}, set: function(_){showControls=_;}},\n        controlLabels:    {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},\n        controlOptions:    {get: function(){return controlOptions;}, set: function(_){controlOptions=_;}},\n        showTotalInTooltip:      {get: function(){return showTotalInTooltip;}, set: function(_){showTotalInTooltip=_;}},\n        totalLabel:      {get: function(){return totalLabel;}, set: function(_){totalLabel=_;}},\n        focusEnable:    {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},\n        focusHeight:     {get: function(){return focus.height();}, set: function(_){focus.height(_);}},\n        brushExtent: {get: function(){return focus.brushExtent();}, set: function(_){focus.brushExtent(_);}},\n\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            if (_.top !== undefined) {\n                margin.top = _.top;\n                marginTop = _.top;\n            }\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n        }},\n        focusMargin: {get: function(){return focus.margin}, set: function(_){\n            focus.margin.top    = _.top    !== undefined ? _.top    : focus.margin.top;\n            focus.margin.right  = _.right  !== undefined ? _.right  : focus.margin.right;\n            focus.margin.bottom = _.bottom !== undefined ? _.bottom : focus.margin.bottom;\n            focus.margin.left   = _.left   !== undefined ? _.left   : focus.margin.left;\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            stacked.duration(duration);\n            xAxis.duration(duration);\n            yAxis.duration(duration);\n        }},\n        color:  {get: function(){return color;}, set: function(_){\n            color = nv.utils.getColor(_);\n            legend.color(color);\n            stacked.color(color);\n            focus.color(color);\n        }},\n        x: {get: function(){return stacked.x();}, set: function(_){\n            stacked.x(_);\n            focus.x(_);\n        }},\n        y: {get: function(){return stacked.y();}, set: function(_){\n            stacked.y(_);\n            focus.y(_);\n        }},\n        rightAlignYAxis: {get: function(){return rightAlignYAxis;}, set: function(_){\n            rightAlignYAxis = _;\n            yAxis.orient( rightAlignYAxis ? 'right' : 'left');\n        }},\n        useInteractiveGuideline: {get: function(){return useInteractiveGuideline;}, set: function(_){\n            useInteractiveGuideline = !!_;\n            chart.interactive(!_);\n            chart.useVoronoi(!_);\n            stacked.scatter.interactive(!_);\n        }}\n    });\n\n    nv.utils.inheritOptions(chart, stacked);\n    nv.utils.initOptions(chart);\n\n    return chart;\n};\n\nnv.models.stackedAreaWithFocusChart = function() {\n  return nv.models.stackedAreaChart()\n    .margin({ bottom: 30 })\n    .focusEnable( true );\n};\n"
  },
  {
    "path": "src/models/sunburst.js",
    "content": "// based on http://bl.ocks.org/kerryrodden/477c1bfb081b783f80ad\nnv.models.sunburst = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var margin = {top: 0, right: 0, bottom: 0, left: 0}\n        , width = 600\n        , height = 600\n        , mode = \"count\"\n        , modes = {count: function(d) { return 1; }, value: function(d) { return d.value || d.size }, size: function(d) { return d.value || d.size }}\n        , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one\n        , container = null\n        , color = nv.utils.defaultColor()\n        , showLabels = false\n        , labelFormat = function(d){if(mode === 'count'){return d.name + ' #' + d.value}else{return d.name + ' ' + (d.value || d.size)}}\n        , labelThreshold = 0.02\n        , sort = function(d1, d2){return d1.name > d2.name;}\n        , key = function(d,i){\n            if (d.parent !== undefined) {\n                return d.name + '-' + d.parent.name + '-' + i;\n            } else {\n                return d.name;\n            }\n        }\n        , groupColorByParent = true\n        , duration = 500\n        , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd');\n\n    //============================================================\n    // aux functions and setup\n    //------------------------------------------------------------\n\n    var x = d3.scale.linear().range([0, 2 * Math.PI]);\n    var y = d3.scale.sqrt();\n\n    var partition = d3.layout.partition().sort(sort);\n\n    var node, availableWidth, availableHeight, radius;\n    var prevPositions = {};\n\n    var arc = d3.svg.arc()\n        .startAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x))) })\n        .endAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))) })\n        .innerRadius(function(d) {return Math.max(0, y(d.y)) })\n        .outerRadius(function(d) {return Math.max(0, y(d.y + d.dy)) });\n\n    function rotationToAvoidUpsideDown(d) {\n        var centerAngle = computeCenterAngle(d);\n        if(centerAngle > 90){\n            return 180;\n        }\n        else {\n            return 0;\n        }\n    }\n\n    function computeCenterAngle(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n        var centerAngle = (((startAngle + endAngle) / 2) * (180 / Math.PI)) - 90;\n        return centerAngle;\n    }\n\n    function computeNodePercentage(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n        return (endAngle - startAngle) / (2 * Math.PI);\n    }\n\n    function labelThresholdMatched(d) {\n        var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));\n        var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));\n\n        var size = endAngle - startAngle;\n        return size > labelThreshold;\n    }\n\n    // When zooming: interpolate the scales.\n    function arcTweenZoom(e,i) {\n        var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]),\n        yd = d3.interpolate(y.domain(), [node.y, 1]),\n        yr = d3.interpolate(y.range(), [node.y ? 20 : 0, radius]);\n\n        if (i === 0) {\n            return function() {return arc(e);}\n        }\n        else {\n            return function (t) {\n                x.domain(xd(t));\n                y.domain(yd(t)).range(yr(t));\n                return arc(e);\n            }\n        };\n    }\n\n    function arcTweenUpdate(d) {\n        var ipo = d3.interpolate({x: d.x0, dx: d.dx0, y: d.y0, dy: d.dy0}, d);\n\n        return function (t) {\n            var b = ipo(t);\n\n            d.x0 = b.x;\n            d.dx0 = b.dx;\n            d.y0 = b.y;\n            d.dy0 = b.dy;\n\n            return arc(b);\n        };\n    }\n\n    function updatePrevPosition(node) {\n        var k = key(node);\n        if(! prevPositions[k]) prevPositions[k] = {};\n        var pP = prevPositions[k];\n        pP.dx = node.dx;\n        pP.x = node.x;\n        pP.dy = node.dy;\n        pP.y = node.y;\n    }\n\n    function storeRetrievePrevPositions(nodes) {\n        nodes.forEach(function(n){\n            var k = key(n);\n            var pP = prevPositions[k];\n            //console.log(k,n,pP);\n            if( pP ){\n                n.dx0 = pP.dx;\n                n.x0 = pP.x;\n                n.dy0 = pP.dy;\n                n.y0 = pP.y;\n            }\n            else {\n                n.dx0 = n.dx;\n                n.x0 = n.x;\n                n.dy0 = n.dy;\n                n.y0 = n.y;\n            }\n            updatePrevPosition(n);\n        });\n    }\n\n    function zoomClick(d) {\n        var labels = container.selectAll('text')\n        var path = container.selectAll('path')\n\n        // fade out all text elements\n        labels.transition().attr(\"opacity\",0);\n\n        // to allow reference to the new center node\n        node = d;\n\n        path.transition()\n            .duration(duration)\n            .attrTween(\"d\", arcTweenZoom)\n            .each('end', function(e) {\n                // partially taken from here: http://bl.ocks.org/metmajer/5480307\n                // check if the animated element's data e lies within the visible angle span given in d\n                if(e.x >= d.x && e.x < (d.x + d.dx) ){\n                    if(e.depth >= d.depth){\n                        // get a selection of the associated text element\n                        var parentNode = d3.select(this.parentNode);\n                        var arcText = parentNode.select('text');\n\n                        // fade in the text element and recalculate positions\n                        arcText.transition().duration(duration)\n                        .text( function(e){return labelFormat(e) })\n                        .attr(\"opacity\", function(d){\n                            if(labelThresholdMatched(d)) {\n                                return 1;\n                            }\n                            else {\n                                return 0;\n                            }\n                        })\n                        .attr(\"transform\", function() {\n                            var width = this.getBBox().width;\n                            if(e.depth === 0)\n                            return \"translate(\" + (width / 2 * - 1) + \",0)\";\n                            else if(e.depth === d.depth){\n                                return \"translate(\" + (y(e.y) + 5) + \",0)\";\n                            }\n                            else {\n                                var centerAngle = computeCenterAngle(e);\n                                var rotation = rotationToAvoidUpsideDown(e);\n                                if (rotation === 0) {\n                                    return 'rotate('+ centerAngle +')translate(' + (y(e.y) + 5) + ',0)';\n                                }\n                                else {\n                                    return 'rotate('+ centerAngle +')translate(' + (y(e.y) + width + 5) + ',0)rotate(' + rotation + ')';\n                                }\n                            }\n                        });\n                    }\n                }\n            })\n    }\n\n    //============================================================\n    // chart function\n    //------------------------------------------------------------\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    function chart(selection) {\n        renderWatch.reset();\n\n        selection.each(function(data) {\n            container = d3.select(this);\n            availableWidth = nv.utils.availableWidth(width, container, margin);\n            availableHeight = nv.utils.availableHeight(height, container, margin);\n            radius = Math.min(availableWidth, availableHeight) / 2;\n\n            y.range([0, radius]);\n\n            // Setup containers and skeleton of chart\n            var wrap = container.select('g.nvd3.nv-wrap.nv-sunburst');\n            if( !wrap[0][0] ) {\n                wrap = container.append('g')\n                    .attr('class', 'nvd3 nv-wrap nv-sunburst nv-chart-' + id)\n                    .attr('transform', 'translate(' + ((availableWidth / 2) + margin.left + margin.right) + ',' + ((availableHeight / 2) + margin.top + margin.bottom) + ')');\n            } else {\n                wrap.attr('transform', 'translate(' + ((availableWidth / 2) + margin.left + margin.right) + ',' + ((availableHeight / 2) + margin.top + margin.bottom) + ')');\n            }\n\n            container.on('click', function (d, i) {\n                dispatch.chartClick({\n                    data: d,\n                    index: i,\n                    pos: d3.event,\n                    id: id\n                });\n            });\n\n            partition.value(modes[mode] || modes[\"count\"]);\n\n            //reverse the drawing order so that the labels of inner\n            //arcs are drawn on top of the outer arcs.\n            var nodes = partition.nodes(data[0]).reverse()\n\n            storeRetrievePrevPositions(nodes);\n            var cG = wrap.selectAll('.arc-container').data(nodes, key)\n\n            //handle new datapoints\n            var cGE = cG.enter()\n                .append(\"g\")\n                .attr(\"class\",'arc-container')\n\n            cGE.append(\"path\")\n                .attr(\"d\", arc)\n                .style(\"fill\", function (d) {\n                    if (d.color) {\n                        return d.color;\n                    }\n                    else if (groupColorByParent) {\n                        return color((d.children ? d : d.parent).name);\n                    }\n                    else {\n                        return color(d.name);\n                    }\n                })\n                .style(\"stroke\", \"#FFF\")\n                .on(\"click\", function(d,i){\n                    zoomClick(d);\n                    dispatch.elementClick({\n                        data: d,\n                        index: i\n                    })\n                })\n                .on('mouseover', function(d,i){\n                    d3.select(this).classed('hover', true).style('opacity', 0.8);\n                    dispatch.elementMouseover({\n                        data: d,\n                        color: d3.select(this).style(\"fill\"),\n                        percent: computeNodePercentage(d)\n                    });\n                })\n                .on('mouseout', function(d,i){\n                    d3.select(this).classed('hover', false).style('opacity', 1);\n                    dispatch.elementMouseout({\n                        data: d\n                    });\n                })\n                .on('mousemove', function(d,i){\n                    dispatch.elementMousemove({\n                        data: d\n                    });\n                });\n\n            ///Iterating via each and selecting based on the this\n            ///makes it work ... a cG.selectAll('path') doesn't.\n            ///Without iteration the data (in the element) didn't update.\n            cG.each(function(d){\n                d3.select(this).select('path')\n                    .transition()\n                    .duration(duration)\n                    .attrTween('d', arcTweenUpdate);\n            });\n\n            if(showLabels){\n                //remove labels first and add them back\n                cG.selectAll('text').remove();\n\n                //this way labels are on top of newly added arcs\n                cG.append('text')\n                    .text( function(e){ return labelFormat(e)})\n                    .transition()\n                    .duration(duration)\n                    .attr(\"opacity\", function(d){\n                        if(labelThresholdMatched(d)) {\n                            return 1;\n                        }\n                        else {\n                            return 0;\n                        }\n                    })\n                    .attr(\"transform\", function(d) {\n                        var width = this.getBBox().width;\n                        if(d.depth === 0){\n                            return \"rotate(0)translate(\" + (width / 2 * -1) + \",0)\";\n                        }\n                        else {\n                            var centerAngle = computeCenterAngle(d);\n                            var rotation = rotationToAvoidUpsideDown(d);\n                            if (rotation === 0) {\n                                return 'rotate('+ centerAngle +')translate(' + (y(d.y) + 5) + ',0)';\n                            }\n                            else {\n                                return 'rotate('+ centerAngle +')translate(' + (y(d.y) + width + 5) + ',0)rotate(' + rotation + ')';\n                            }\n                        }\n                    });\n            }\n\n            //zoom out to the center when the data is updated.\n            zoomClick(nodes[nodes.length - 1])\n\n\n            //remove unmatched elements ...\n            cG.exit()\n                .transition()\n                .duration(duration)\n                .attr('opacity',0)\n                .each('end',function(d){\n                    var k = key(d);\n                    prevPositions[k] = undefined;\n                })\n                .remove();\n        });\n\n\n        renderWatch.renderEnd('sunburst immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    chart.dispatch = dispatch;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        width:      {get: function(){return width;}, set: function(_){width=_;}},\n        height:     {get: function(){return height;}, set: function(_){height=_;}},\n        mode:       {get: function(){return mode;}, set: function(_){mode=_;}},\n        id:         {get: function(){return id;}, set: function(_){id=_;}},\n        duration:   {get: function(){return duration;}, set: function(_){duration=_;}},\n        groupColorByParent: {get: function(){return groupColorByParent;}, set: function(_){groupColorByParent=!!_;}},\n        showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=!!_}},\n        labelFormat: {get: function(){return labelFormat;}, set: function(_){labelFormat=_}},\n        labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_}},\n        sort: {get: function(){return sort;}, set: function(_){sort=_}},\n        key: {get: function(){return key;}, set: function(_){key=_}},\n        // options that require extra logic in the setter\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    != undefined ? _.top    : margin.top;\n            margin.right  = _.right  != undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom != undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   != undefined ? _.left   : margin.left;\n        }},\n        color: {get: function(){return color;}, set: function(_){\n            color=nv.utils.getColor(_);\n        }}\n    });\n\n    nv.utils.initOptions(chart);\n    return chart;\n};\n"
  },
  {
    "path": "src/models/sunburstChart.js",
    "content": "nv.models.sunburstChart = function() {\n    \"use strict\";\n\n    //============================================================\n    // Public Variables with Default Settings\n    //------------------------------------------------------------\n\n    var sunburst = nv.models.sunburst();\n    var tooltip = nv.models.tooltip();\n\n    var margin = {top: 30, right: 20, bottom: 20, left: 20}\n        , width = null\n        , height = null\n        , color = nv.utils.defaultColor()\n        , showTooltipPercent = false\n        , id = Math.round(Math.random() * 100000)\n        , defaultState = null\n        , noData = null\n        , duration = 250\n        , dispatch = d3.dispatch('stateChange', 'changeState','renderEnd');\n\n\n    //============================================================\n    // Private Variables\n    //------------------------------------------------------------\n\n    var renderWatch = nv.utils.renderWatch(dispatch);\n\n    tooltip\n        .duration(0)\n        .headerEnabled(false)\n        .valueFormatter(function(d){return d;});\n\n    //============================================================\n    // Chart function\n    //------------------------------------------------------------\n\n    function chart(selection) {\n        renderWatch.reset();\n        renderWatch.models(sunburst);\n\n        selection.each(function(data) {\n            var container = d3.select(this);\n\n            nv.utils.initSVG(container);\n\n            var availableWidth = nv.utils.availableWidth(width, container, margin);\n            var availableHeight = nv.utils.availableHeight(height, container, margin);\n\n            chart.update = function() {\n                if (duration === 0) {\n                    container.call(chart);\n                } else {\n                    container.transition().duration(duration).call(chart);\n                }\n            };\n            chart.container = container;\n\n            // Display No Data message if there's nothing to show.\n            if (!data || !data.length) {\n                nv.utils.noData(chart, container);\n                return chart;\n            } else {\n                container.selectAll('.nv-noData').remove();\n            }\n\n            sunburst.width(availableWidth).height(availableHeight).margin(margin);\n            container.call(sunburst);\n        });\n\n        renderWatch.renderEnd('sunburstChart immediate');\n        return chart;\n    }\n\n    //============================================================\n    // Event Handling/Dispatching (out of chart's scope)\n    //------------------------------------------------------------\n\n    sunburst.dispatch.on('elementMouseover.tooltip', function(evt) {\n        evt.series = {\n            key: evt.data.name,\n            value: (evt.data.value || evt.data.size),\n            color: evt.color,\n            percent: evt.percent\n        };\n        if (!showTooltipPercent) {\n            delete evt.percent;\n            delete evt.series.percent;\n        }\n        tooltip.data(evt).hidden(false);\n    });\n\n    sunburst.dispatch.on('elementMouseout.tooltip', function(evt) {\n        tooltip.hidden(true);\n    });\n\n    sunburst.dispatch.on('elementMousemove.tooltip', function(evt) {\n        tooltip();\n    });\n\n    //============================================================\n    // Expose Public Variables\n    //------------------------------------------------------------\n\n    // expose chart's sub-components\n    chart.dispatch = dispatch;\n    chart.sunburst = sunburst;\n    chart.tooltip = tooltip;\n    chart.options = nv.utils.optionsFunc.bind(chart);\n\n    // use Object get/set functionality to map between vars and chart functions\n    chart._options = Object.create({}, {\n        // simple options, just get/set the necessary values\n        noData:             {get: function(){return noData;},               set: function(_){noData=_;}},\n        defaultState:       {get: function(){return defaultState;},         set: function(_){defaultState=_;}},\n        showTooltipPercent: {get: function(){return showTooltipPercent;},   set: function(_){showTooltipPercent=_;}},\n\n        // options that require extra logic in the setter\n        color: {get: function(){return color;}, set: function(_){\n            color = _;\n            sunburst.color(color);\n        }},\n        duration: {get: function(){return duration;}, set: function(_){\n            duration = _;\n            renderWatch.reset(duration);\n            sunburst.duration(duration);\n        }},\n        margin: {get: function(){return margin;}, set: function(_){\n            margin.top    = _.top    !== undefined ? _.top    : margin.top;\n            margin.right  = _.right  !== undefined ? _.right  : margin.right;\n            margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;\n            margin.left   = _.left   !== undefined ? _.left   : margin.left;\n            sunburst.margin(margin);\n        }}\n    });\n    nv.utils.inheritOptions(chart, sunburst);\n    nv.utils.initOptions(chart);\n    return chart;\n\n};\n"
  },
  {
    "path": "src/tooltip.js",
    "content": "\n/* Model which can be instantiated to handle tooltip rendering.\n Example usage:\n var tip = nv.models.tooltip().gravity('w').distance(23)\n .data(myDataObject);\n\n tip();    //just invoke the returned function to render tooltip.\n */\nnv.models.tooltip = function() {\n    \"use strict\";\n\n    /*\n    Tooltip data. If data is given in the proper format, a consistent tooltip is generated.\n    Example Format of data:\n    {\n        key: \"Date\",\n        value: \"August 2009\",\n        series: [\n            {key: \"Series 1\", value: \"Value 1\", color: \"#000\"},\n            {key: \"Series 2\", value: \"Value 2\", color: \"#00f\"}\n        ]\n    }\n    */\n    var id = \"nvtooltip-\" + Math.floor(Math.random() * 100000) // Generates a unique id when you create a new tooltip() object.\n        ,   data = null\n        ,   gravity = 'w'   // Can be 'n','s','e','w'. Determines how tooltip is positioned.\n        ,   distance = 25 // Distance to offset tooltip from the mouse location.\n        ,   snapDistance = 0   // Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)\n        ,   classes = null  // Attaches additional CSS classes to the tooltip DIV that is created.\n        ,   hidden = true  // Start off hidden, toggle with hide/show functions below.\n        ,   hideDelay = 200  // Delay (in ms) before the tooltip hides after calling hide().\n        ,   tooltip = null // d3 select of the tooltip div.\n        ,   lastPosition = { left: null, top: null } // Last position the tooltip was in.\n        ,   enabled = true  // True -> tooltips are rendered. False -> don't render tooltips.\n        ,   duration = 100 // Tooltip movement duration, in ms.\n        ,   headerEnabled = true // If is to show the tooltip header.\n        ,   nvPointerEventsClass = \"nv-pointer-events-none\" // CSS class to specify whether element should not have mouse events.\n    ;\n\n    // Format function for the tooltip values column.\n    // d is value,\n    // i is series index\n    // p is point containing the value\n    var valueFormatter = function(d, i, p) {\n        return d;\n    };\n\n    // Format function for the tooltip header value.\n    var headerFormatter = function(d) {\n        return d;\n    };\n\n    var keyFormatter = function(d, i) {\n        return d;\n    };\n\n    // By default, the tooltip model renders a beautiful table inside a DIV, returned as HTML\n    // You can override this function if a custom tooltip is desired. For instance, you could directly manipulate\n    // the DOM by accessing elem and returning false.\n    var contentGenerator = function(d, elem) {\n        if (d === null) {\n            return '';\n        }\n\n        var table = d3.select(document.createElement(\"table\"));\n        if (headerEnabled) {\n            var theadEnter = table.selectAll(\"thead\")\n                .data([d])\n                .enter().append(\"thead\");\n\n            theadEnter.append(\"tr\")\n                .append(\"td\")\n                .attr(\"colspan\", 3)\n                .append(\"strong\")\n                .classed(\"x-value\", true)\n                .html(headerFormatter(d.value));\n        }\n\n        var tbodyEnter = table.selectAll(\"tbody\")\n            .data([d])\n            .enter().append(\"tbody\");\n\n        var trowEnter = tbodyEnter.selectAll(\"tr\")\n                .data(function(p) { return p.series})\n                .enter()\n                .append(\"tr\")\n                .classed(\"highlight\", function(p) { return p.highlight});\n\n        trowEnter.append(\"td\")\n            .classed(\"legend-color-guide\",true)\n            .append(\"div\")\n            .style(\"background-color\", function(p) { return p.color});\n\n        trowEnter.append(\"td\")\n            .classed(\"key\",true)\n            .classed(\"total\",function(p) { return !!p.total})\n            .html(function(p, i) { return keyFormatter(p.key, i)});\n\n        trowEnter.append(\"td\")\n            .classed(\"value\",true)\n            .html(function(p, i) { return valueFormatter(p.value, i, p) });\n\n        trowEnter.filter(function (p,i) { return p.percent !== undefined }).append(\"td\")\n            .classed(\"percent\", true)\n            .html(function(p, i) { return \"(\" + d3.format('%')(p.percent) + \")\" });\n\n        trowEnter.selectAll(\"td\").each(function(p) {\n            if (p.highlight) {\n                var opacityScale = d3.scale.linear().domain([0,1]).range([\"#fff\",p.color]);\n                var opacity = 0.6;\n                d3.select(this)\n                    .style(\"border-bottom-color\", opacityScale(opacity))\n                    .style(\"border-top-color\", opacityScale(opacity))\n                ;\n            }\n        });\n\n        var html = table.node().outerHTML;\n        if (d.footer !== undefined)\n            html += \"<div class='footer'>\" + d.footer + \"</div>\";\n        return html;\n\n    };\n\n    /*\n     Function that returns the position (relative to the viewport/document.body)\n     the tooltip should be placed in.\n     Should return: {\n        left: <leftPos>,\n        top: <topPos>\n     }\n     */\n    var position = function() {\n        var pos = {\n            left: d3.event !== null ? d3.event.clientX : 0,\n            top: d3.event !== null ? d3.event.clientY : 0\n        };\n\n        if(getComputedStyle(document.body).transform != 'none') {\n            // Take the offset into account, as now the tooltip is relative\n            // to document.body.\n            var client = document.body.getBoundingClientRect();\n            pos.left -= client.left;\n            pos.top -= client.top;\n        }\n\n        return pos;\n    };\n\n    var dataSeriesExists = function(d) {\n        if (d && d.series) {\n            if (nv.utils.isArray(d.series)) {\n                return true;\n            }\n            // if object, it's okay just convert to array of the object\n            if (nv.utils.isObject(d.series)) {\n                d.series = [d.series];\n                return true;\n            }\n        }\n        return false;\n    };\n\n    // Calculates the gravity offset of the tooltip. Parameter is position of tooltip\n    // relative to the viewport.\n    var calcGravityOffset = function(pos) {\n        var height = tooltip.node().offsetHeight,\n            width = tooltip.node().offsetWidth,\n            clientWidth = document.documentElement.clientWidth, // Don't want scrollbars.\n            clientHeight = document.documentElement.clientHeight, // Don't want scrollbars.\n            left, top, tmp;\n\n        // calculate position based on gravity\n        switch (gravity) {\n            case 'e':\n                left = - width - distance;\n                top = - (height / 2);\n                if(pos.left + left < 0) left = distance;\n                if((tmp = pos.top + top) < 0) top -= tmp;\n                if((tmp = pos.top + top + height) > clientHeight) top -= tmp - clientHeight;\n                break;\n            case 'w':\n                left = distance;\n                top = - (height / 2);\n                if (pos.left + left + width > clientWidth) left = - width - distance;\n                if ((tmp = pos.top + top) < 0) top -= tmp;\n                if ((tmp = pos.top + top + height) > clientHeight) top -= tmp - clientHeight;\n                break;\n            case 'n':\n                left = - (width / 2) - 5; // - 5 is an approximation of the mouse's height.\n                top = distance;\n                if (pos.top + top + height > clientHeight) top = - height - distance;\n                if ((tmp = pos.left + left) < 0) left -= tmp;\n                if ((tmp = pos.left + left + width) > clientWidth) left -= tmp - clientWidth;\n                break;\n            case 's':\n                left = - (width / 2);\n                top = - height - distance;\n                if (pos.top + top < 0) top = distance;\n                if ((tmp = pos.left + left) < 0) left -= tmp;\n                if ((tmp = pos.left + left + width) > clientWidth) left -= tmp - clientWidth;\n                break;\n            case 'center':\n                left = - (width / 2);\n                top = - (height / 2);\n                break;\n            default:\n                left = 0;\n                top = 0;\n                break;\n        }\n\n        return { 'left': left, 'top': top };\n    };\n\n    /*\n     Positions the tooltip in the correct place, as given by the position() function.\n     */\n    var positionTooltip = function() {\n        nv.dom.read(function() {\n            var pos = position(),\n                gravityOffset = calcGravityOffset(pos),\n                left = pos.left + gravityOffset.left,\n                top = pos.top + gravityOffset.top;\n\n            // delay hiding a bit to avoid flickering\n            if (hidden) {\n                tooltip\n                    .interrupt()\n                    .transition()\n                    .delay(hideDelay)\n                    .duration(0)\n                    .style('opacity', 0);\n            } else {\n                // using tooltip.style('transform') returns values un-usable for tween\n                var old_translate = 'translate(' + lastPosition.left + 'px, ' + lastPosition.top + 'px)';\n                var new_translate = 'translate(' + Math.round(left) + 'px, ' + Math.round(top) + 'px)';\n                var translateInterpolator = d3.interpolateString(old_translate, new_translate);\n                var is_hidden = tooltip.style('opacity') < 0.1;\n\n                tooltip\n                    .interrupt() // cancel running transitions\n                    .transition()\n                    .duration(is_hidden ? 0 : duration)\n                    // using tween since some versions of d3 can't auto-tween a translate on a div\n                    .styleTween('transform', function (d) {\n                        return translateInterpolator;\n                    }, 'important')\n                    // Safari has its own `-webkit-transform` and does not support `transform`\n                    .styleTween('-webkit-transform', function (d) {\n                        return translateInterpolator;\n                    })\n                    .style('-ms-transform', new_translate)\n                    .style('opacity', 1);\n            }\n\n            lastPosition.left = left;\n            lastPosition.top = top;\n        });\n    };\n\n    // Creates new tooltip container, or uses existing one on DOM.\n    function initTooltip() {\n        if (!tooltip || !tooltip.node()) {\n            // Create new tooltip div if it doesn't exist on DOM.\n\n            var data = [1];\n            tooltip = d3.select(document.body).selectAll('#'+id).data(data);\n\n            tooltip.enter().append('div')\n                   .attr(\"class\", \"nvtooltip \" + (classes ? classes : \"xy-tooltip\"))\n                   .attr(\"id\", id)\n                   .style(\"top\", 0).style(\"left\", 0)\n                   .style('opacity', 0)\n                   .style('position', 'absolute')\n                   .selectAll(\"div, table, td, tr\").classed(nvPointerEventsClass, true)\n                   .classed(nvPointerEventsClass, true);\n\n            tooltip.exit().remove()\n        }\n    }\n\n    // Draw the tooltip onto the DOM.\n    function nvtooltip() {\n        if (!enabled) return;\n        if (!dataSeriesExists(data)) return;\n\n        nv.dom.write(function () {\n            initTooltip();\n            // Generate data and set it into tooltip.\n            // Bonus - If you override contentGenerator and return false, you can use something like\n            //         Angular, React or Knockout to bind the data for your tooltip directly to the DOM.\n            var newContent = contentGenerator(data, tooltip.node());\n            if (newContent) {\n                tooltip.node().innerHTML = newContent;\n            }\n\n            positionTooltip();\n        });\n\n        return nvtooltip;\n    }\n\n    nvtooltip.nvPointerEventsClass = nvPointerEventsClass;\n    nvtooltip.options = nv.utils.optionsFunc.bind(nvtooltip);\n\n    nvtooltip._options = Object.create({}, {\n        // simple read/write options\n        duration: {get: function(){return duration;}, set: function(_){duration=_;}},\n        gravity: {get: function(){return gravity;}, set: function(_){gravity=_;}},\n        distance: {get: function(){return distance;}, set: function(_){distance=_;}},\n        snapDistance: {get: function(){return snapDistance;}, set: function(_){snapDistance=_;}},\n        classes: {get: function(){return classes;}, set: function(_){classes=_;}},\n        enabled: {get: function(){return enabled;}, set: function(_){enabled=_;}},\n        hideDelay: {get: function(){return hideDelay;}, set: function(_){hideDelay=_;}},\n        contentGenerator: {get: function(){return contentGenerator;}, set: function(_){contentGenerator=_;}},\n        valueFormatter: {get: function(){return valueFormatter;}, set: function(_){valueFormatter=_;}},\n        headerFormatter: {get: function(){return headerFormatter;}, set: function(_){headerFormatter=_;}},\n        keyFormatter: {get: function(){return keyFormatter;}, set: function(_){keyFormatter=_;}},\n        headerEnabled: {get: function(){return headerEnabled;}, set: function(_){headerEnabled=_;}},\n        position: {get: function(){return position;}, set: function(_){position=_;}},\n\n        // Deprecated options\n        chartContainer: {get: function(){return document.body;}, set: function(_){\n            // deprecated after 1.8.3\n            nv.deprecated('chartContainer', 'feature removed after 1.8.3');\n        }},\n        fixedTop: {get: function(){return null;}, set: function(_){\n            // deprecated after 1.8.1\n            nv.deprecated('fixedTop', 'feature removed after 1.8.1');\n        }},\n        offset: {get: function(){return {left: 0, top: 0};}, set: function(_){\n            // deprecated after 1.8.1\n            nv.deprecated('offset', 'use chart.tooltip.distance() instead');\n        }},\n\n        // options with extra logic\n        hidden: {get: function(){return hidden;}, set: function(_){\n            if (hidden != _) {\n                hidden = !!_;\n                nvtooltip();\n            }\n        }},\n        data: {get: function(){return data;}, set: function(_){\n            // if showing a single data point, adjust data format with that\n            if (_.point) {\n                _.value = _.point.x;\n                _.series = _.series || {};\n                _.series.value = _.point.y;\n                _.series.color = _.point.color || _.series.color;\n            }\n            data = _;\n        }},\n\n        // read only properties\n        node: {get: function(){return tooltip.node();}, set: function(_){}},\n        id: {get: function(){return id;}, set: function(_){}}\n    });\n\n    nv.utils.initOptions(nvtooltip);\n    return nvtooltip;\n};\n"
  },
  {
    "path": "src/utils.js",
    "content": "\n\n/*\nGets the browser window size\n\nReturns object with height and width properties\n */\nnv.utils.windowSize = function() {\n    // Sane defaults\n    var size = {width: 640, height: 480};\n\n    // Most recent browsers use\n    if (window.innerWidth && window.innerHeight) {\n        size.width = window.innerWidth;\n        size.height = window.innerHeight;\n        return (size);\n    }\n\n    // IE can use depending on mode it is in\n    if (document.compatMode=='CSS1Compat' &&\n        document.documentElement &&\n        document.documentElement.offsetWidth ) {\n\n        size.width = document.documentElement.offsetWidth;\n        size.height = document.documentElement.offsetHeight;\n        return (size);\n    }\n\n    // Earlier IE uses Doc.body\n    if (document.body && document.body.offsetWidth) {\n        size.width = document.body.offsetWidth;\n        size.height = document.body.offsetHeight;\n        return (size);\n    }\n\n    return (size);\n};\n\n\n/* handle dumb browser quirks...  isinstance breaks if you use frames\ntypeof returns 'object' for null, NaN is a number, etc.\n */\nnv.utils.isArray = Array.isArray;\nnv.utils.isObject = function(a) {\n    return a !== null && typeof a === 'object';\n};\nnv.utils.isFunction = function(a) {\n    return typeof a === 'function';\n};\nnv.utils.isDate = function(a) {\n    return toString.call(a) === '[object Date]';\n};\nnv.utils.isNumber = function(a) {\n    return !isNaN(a) && typeof a === 'number';\n};\n\n\n/*\nBinds callback function to run when window is resized\n */\nnv.utils.windowResize = function(handler) {\n    if (window.addEventListener) {\n        window.addEventListener('resize', handler);\n    } else {\n        nv.log(\"ERROR: Failed to bind to window.resize with: \", handler);\n    }\n    // return object with clear function to remove the single added callback.\n    return {\n        callback: handler,\n        clear: function() {\n            window.removeEventListener('resize', handler);\n        }\n    }\n};\n\n\n/*\nBackwards compatible way to implement more d3-like coloring of graphs.\nCan take in nothing, an array, or a function/scale\nTo use a normal scale, get the range and pass that because we must be able\nto take two arguments and use the index to keep backward compatibility\n*/\nnv.utils.getColor = function(color) {\n    //if you pass in nothing, get default colors back\n    if (color === undefined) {\n        return nv.utils.defaultColor();\n\n    //if passed an array, turn it into a color scale\n    } else if(nv.utils.isArray(color)) {\n        var color_scale = d3.scale.ordinal().range(color);\n        return function(d, i) {\n            var key = i === undefined ? d : i;\n            return d.color || color_scale(key);\n        };\n\n    //if passed a function or scale, return it, or whatever it may be\n    //external libs, such as angularjs-nvd3-directives use this\n    } else {\n        //can't really help it if someone passes rubbish as color\n        return color;\n    }\n};\n\n\n/*\nDefault color chooser uses a color scale of 20 colors from D3\n https://github.com/mbostock/d3/wiki/Ordinal-Scales#categorical-colors\n */\nnv.utils.defaultColor = function() {\n    // get range of the scale so we'll turn it into our own function.\n    return nv.utils.getColor(d3.scale.category20().range());\n};\n\n\n/*\nReturns a color function that takes the result of 'getKey' for each series and\nlooks for a corresponding color from the dictionary\n*/\nnv.utils.customTheme = function(dictionary, getKey, defaultColors) {\n    // use default series.key if getKey is undefined\n    getKey = getKey || function(series) { return series.key };\n    defaultColors = defaultColors || d3.scale.category20().range();\n\n    // start at end of default color list and walk back to index 0\n    var defIndex = defaultColors.length;\n\n    return function(series, index) {\n        var key = getKey(series);\n        if (nv.utils.isFunction(dictionary[key])) {\n            return dictionary[key]();\n        } else if (dictionary[key] !== undefined) {\n            return dictionary[key];\n        } else {\n            // no match in dictionary, use a default color\n            if (!defIndex) {\n                // used all the default colors, start over\n                defIndex = defaultColors.length;\n            }\n            defIndex = defIndex - 1;\n            return defaultColors[defIndex];\n        }\n    };\n};\n\n\n/*\nFrom the PJAX example on d3js.org, while this is not really directly needed\nit's a very cool method for doing pjax, I may expand upon it a little bit,\nopen to suggestions on anything that may be useful\n*/\nnv.utils.pjax = function(links, content) {\n\n    var load = function(href) {\n        d3.html(href, function(fragment) {\n            var target = d3.select(content).node();\n            target.parentNode.replaceChild(\n                d3.select(fragment).select(content).node(),\n                target);\n            nv.utils.pjax(links, content);\n        });\n    };\n\n    d3.selectAll(links).on(\"click\", function() {\n        history.pushState(this.href, this.textContent, this.href);\n        load(this.href);\n        d3.event.preventDefault();\n    });\n\n    d3.select(window).on(\"popstate\", function() {\n        if (d3.event.state) {\n            load(d3.event.state);\n        }\n    });\n};\n\n\n/*\nFor when we want to approximate the width in pixels for an SVG:text element.\nMost common instance is when the element is in a display:none; container.\nForumla is : text.length * font-size * constant_factor\n*/\nnv.utils.calcApproxTextWidth = function (svgTextElem) {\n    if (nv.utils.isFunction(svgTextElem.style) && nv.utils.isFunction(svgTextElem.text)) {\n        var fontSize = parseInt(svgTextElem.style(\"font-size\").replace(\"px\",\"\"), 10);\n        var textLength = svgTextElem.text().length;\n        return nv.utils.NaNtoZero(textLength * fontSize * 0.5);\n    }\n    return 0;\n};\n\n\n/*\nNumbers that are undefined, null or NaN, convert them to zeros.\n*/\nnv.utils.NaNtoZero = function(n) {\n    if (!nv.utils.isNumber(n)\n        || isNaN(n)\n        || n === null\n        || n === Infinity\n        || n === -Infinity) {\n\n        return 0;\n    }\n    return n;\n};\n\n/*\nAdd a way to watch for d3 transition ends to d3\n*/\nd3.selection.prototype.watchTransition = function(renderWatch){\n    var args = [this].concat([].slice.call(arguments, 1));\n    return renderWatch.transition.apply(renderWatch, args);\n};\n\n\n/*\nHelper object to watch when d3 has rendered something\n*/\nnv.utils.renderWatch = function(dispatch, duration) {\n    if (!(this instanceof nv.utils.renderWatch)) {\n        return new nv.utils.renderWatch(dispatch, duration);\n    }\n\n    var _duration = duration !== undefined ? duration : 250;\n    var renderStack = [];\n    var self = this;\n\n    this.models = function(models) {\n        models = [].slice.call(arguments, 0);\n        models.forEach(function(model){\n            model.__rendered = false;\n            (function(m){\n                m.dispatch.on('renderEnd', function(arg){\n                    m.__rendered = true;\n                    self.renderEnd('model');\n                });\n            })(model);\n\n            if (renderStack.indexOf(model) < 0) {\n                renderStack.push(model);\n            }\n        });\n    return this;\n    };\n\n    this.reset = function(duration) {\n        if (duration !== undefined) {\n            _duration = duration;\n        }\n        renderStack = [];\n    };\n\n    this.transition = function(selection, args, duration) {\n        args = arguments.length > 1 ? [].slice.call(arguments, 1) : [];\n\n        if (args.length > 1) {\n            duration = args.pop();\n        } else {\n            duration = _duration !== undefined ? _duration : 250;\n        }\n        selection.__rendered = false;\n\n        if (renderStack.indexOf(selection) < 0) {\n            renderStack.push(selection);\n        }\n\n        if (duration === 0) {\n            selection.__rendered = true;\n            selection.delay = function() { return this; };\n            selection.duration = function() { return this; };\n            return selection;\n        } else {\n            if (selection.length === 0) {\n                selection.__rendered = true;\n            } else if (selection.every( function(d){ return !d.length; } )) {\n                selection.__rendered = true;\n            } else {\n                selection.__rendered = false;\n            }\n\n            var n = 0;\n            return selection\n                .transition()\n                .duration(duration)\n                .each(function(){ ++n; })\n                .each('end', function(d, i) {\n                    if (--n === 0) {\n                        selection.__rendered = true;\n                        self.renderEnd.apply(this, args);\n                    }\n                });\n        }\n    };\n\n    this.renderEnd = function() {\n        if (renderStack.every( function(d){ return d.__rendered; } )) {\n            renderStack.forEach( function(d){ d.__rendered = false; });\n            dispatch.renderEnd.apply(this, arguments);\n        }\n    }\n\n};\n\n\n/*\nTakes multiple objects and combines them into the first one (dst)\nexample:  nv.utils.deepExtend({a: 1}, {a: 2, b: 3}, {c: 4});\ngives:  {a: 2, b: 3, c: 4}\n*/\nnv.utils.deepExtend = function(dst){\n    var sources = arguments.length > 1 ? [].slice.call(arguments, 1) : [];\n    sources.forEach(function(source) {\n        for (var key in source) {\n            var isArray = nv.utils.isArray(dst[key]);\n            var isObject = nv.utils.isObject(dst[key]);\n            var srcObj = nv.utils.isObject(source[key]);\n\n            if (isObject && !isArray && srcObj) {\n                nv.utils.deepExtend(dst[key], source[key]);\n            } else {\n                dst[key] = source[key];\n            }\n        }\n    });\n};\n\n\n/*\nstate utility object, used to track d3 states in the models\n*/\nnv.utils.state = function(){\n    if (!(this instanceof nv.utils.state)) {\n        return new nv.utils.state();\n    }\n    var state = {};\n    var _self = this;\n    var _setState = function(){};\n    var _getState = function(){ return {}; };\n    var init = null;\n    var changed = null;\n\n    this.dispatch = d3.dispatch('change', 'set');\n\n    this.dispatch.on('set', function(state){\n        _setState(state, true);\n    });\n\n    this.getter = function(fn){\n        _getState = fn;\n        return this;\n    };\n\n    this.setter = function(fn, callback) {\n        if (!callback) {\n            callback = function(){};\n        }\n        _setState = function(state, update){\n            fn(state);\n            if (update) {\n                callback();\n            }\n        };\n        return this;\n    };\n\n    this.init = function(state){\n        init = init || {};\n        nv.utils.deepExtend(init, state);\n    };\n\n    var _set = function(){\n        var settings = _getState();\n\n        if (JSON.stringify(settings) === JSON.stringify(state)) {\n            return false;\n        }\n\n        for (var key in settings) {\n            if (state[key] === undefined) {\n                state[key] = {};\n            }\n            state[key] = settings[key];\n            changed = true;\n        }\n        return true;\n    };\n\n    this.update = function(){\n        if (init) {\n            _setState(init, false);\n            init = null;\n        }\n        if (_set.call(this)) {\n            this.dispatch.change(state);\n        }\n    };\n\n};\n\n\n/*\nSnippet of code you can insert into each nv.models.* to give you the ability to\ndo things like:\nchart.options({\n  showXAxis: true,\n  tooltips: true\n});\n\nTo enable in the chart:\nchart.options = nv.utils.optionsFunc.bind(chart);\n*/\nnv.utils.optionsFunc = function(args) {\n    if (args) {\n        d3.map(args).forEach((function(key,value) {\n            if (nv.utils.isFunction(this[key])) {\n                this[key](value);\n            }\n        }).bind(this));\n    }\n    return this;\n};\n\n\n/*\nnumTicks:  requested number of ticks\ndata:  the chart data\n\nreturns the number of ticks to actually use on X axis, based on chart data\nto avoid duplicate ticks with the same value\n*/\nnv.utils.calcTicksX = function(numTicks, data) {\n    // find max number of values from all data streams\n    var numValues = 1;\n    var i = 0;\n    for (i; i < data.length; i += 1) {\n        var stream_len = data[i] && data[i].values ? data[i].values.length : 0;\n        numValues = stream_len > numValues ? stream_len : numValues;\n    }\n    nv.log(\"Requested number of ticks: \", numTicks);\n    nv.log(\"Calculated max values to be: \", numValues);\n    // make sure we don't have more ticks than values to avoid duplicates\n    numTicks = numTicks > numValues ? numTicks = numValues - 1 : numTicks;\n    // make sure we have at least one tick\n    numTicks = numTicks < 1 ? 1 : numTicks;\n    // make sure it's an integer\n    numTicks = Math.floor(numTicks);\n    nv.log(\"Calculating tick count as: \", numTicks);\n    return numTicks;\n};\n\n\n/*\n returns number of ticks to actually use on Y axis, based on chart data\n */\nnv.utils.calcTicksY = function(numTicks, data, getY) {\n    if (getY) {\n        var numValues = 1;\n        for (var i=0; i < data.length; i += 1) {\n            var values = data[i] && data[i].values ? data[i].values : [];\n            var maxValue;\n            for (var j=0; j < values.length; j += 1) {\n                maxValue = values[j] && getY(values[j]) ? getY(values[j]): 0;\n                numValues = maxValue > numValues ? maxValue : numValues;\n            }\n        }\n        nv.log(\"Requested number of ticks: \", numTicks);\n        nv.log(\"Calculated max values to be: \", numValues);\n        // make sure we don't have more ticks than values to avoid duplicates\n        numTicks = numTicks > numValues ? numValues - 1 : numTicks;\n        // make sure we have at least one tick\n        numTicks = numTicks < 1 ? 1 : numTicks;\n        // make sure it's an integer\n        numTicks = Math.floor(numTicks);\n        nv.log(\"Calculating tick count as: \", numTicks);\n        return numTicks;\n    } else {\n        return nv.utils.calcTicksX(numTicks, data);\n    }\n};\n\n\n/*\nAdd a particular option from an options object onto chart\nOptions exposed on a chart are a getter/setter function that returns chart\non set to mimic typical d3 option chaining, e.g. svg.option1('a').option2('b');\n\noption objects should be generated via Object.create() to provide\nthe option of manipulating data via get/set functions.\n*/\nnv.utils.initOption = function(chart, name) {\n    // if it's a call option, just call it directly, otherwise do get/set\n    if (chart._calls && chart._calls[name]) {\n        chart[name] = chart._calls[name];\n    } else {\n        chart[name] = function (_) {\n            if (!arguments.length) return chart._options[name];\n            chart._overrides[name] = true;\n            chart._options[name] = _;\n            return chart;\n        };\n        // calling the option as _option will ignore if set by option already\n        // so nvd3 can set options internally but the stop if set manually\n        chart['_' + name] = function(_) {\n            if (!arguments.length) return chart._options[name];\n            if (!chart._overrides[name]) {\n                chart._options[name] = _;\n            }\n            return chart;\n        }\n    }\n};\n\n\n/*\nAdd all options in an options object to the chart\n*/\nnv.utils.initOptions = function(chart) {\n    chart._overrides = chart._overrides || {};\n    var ops = Object.getOwnPropertyNames(chart._options || {});\n    var calls = Object.getOwnPropertyNames(chart._calls || {});\n    ops = ops.concat(calls);\n    for (var i in ops) {\n        nv.utils.initOption(chart, ops[i]);\n    }\n};\n\n\n/*\nInherit options from a D3 object\nd3.rebind makes calling the function on target actually call it on source\nAlso use _d3options so we can track what we inherit for documentation and chained inheritance\n*/\nnv.utils.inheritOptionsD3 = function(target, d3_source, oplist) {\n    target._d3options = oplist.concat(target._d3options || []);\n    // Find unique d3 options (string) and update d3options\n    target._d3options = (target._d3options || []).filter(function(item, i, ar){ return ar.indexOf(item) === i; });\n    oplist.unshift(d3_source);\n    oplist.unshift(target);\n    d3.rebind.apply(this, oplist);\n};\n\n\n/*\nRemove duplicates from an array\n*/\nnv.utils.arrayUnique = function(a) {\n    return a.sort().filter(function(item, pos) {\n        return !pos || item != a[pos - 1];\n    });\n};\n\n\n/*\nKeeps a list of custom symbols to draw from in addition to d3.svg.symbol\nNecessary since d3 doesn't let you extend its list -_-\nAdd new symbols by doing nv.utils.symbols.set('name', function(size){...});\n*/\nnv.utils.symbolMap = d3.map();\n\n\n/*\nReplaces d3.svg.symbol so that we can look both there and our own map\n */\nnv.utils.symbol = function() {\n    var type,\n        size = 64;\n    function symbol(d,i) {\n        var t = type.call(this,d,i);\n        var s = size.call(this,d,i);\n        if (d3.svg.symbolTypes.indexOf(t) !== -1) {\n            return d3.svg.symbol().type(t).size(s)();\n        } else {\n            return nv.utils.symbolMap.get(t)(s);\n        }\n    }\n    symbol.type = function(_) {\n        if (!arguments.length) return type;\n        type = d3.functor(_);\n        return symbol;\n    };\n    symbol.size = function(_) {\n        if (!arguments.length) return size;\n        size = d3.functor(_);\n        return symbol;\n    };\n    return symbol;\n};\n\n\n/*\nInherit option getter/setter functions from source to target\nd3.rebind makes calling the function on target actually call it on source\nAlso track via _inherited and _d3options so we can track what we inherit\nfor documentation generation purposes and chained inheritance\n*/\nnv.utils.inheritOptions = function(target, source) {\n    // inherit all the things\n    var ops = Object.getOwnPropertyNames(source._options || {});\n    var calls = Object.getOwnPropertyNames(source._calls || {});\n    var inherited = source._inherited || [];\n    var d3ops = source._d3options || [];\n    var args = ops.concat(calls).concat(inherited).concat(d3ops);\n    args.unshift(source);\n    args.unshift(target);\n    d3.rebind.apply(this, args);\n    // pass along the lists to keep track of them, don't allow duplicates\n    target._inherited = nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited || []));\n    target._d3options = nv.utils.arrayUnique(d3ops.concat(target._d3options || []));\n};\n\n\n/*\nRuns common initialize code on the svg before the chart builds\n*/\nnv.utils.initSVG = function(svg) {\n    svg.classed({'nvd3-svg':true});\n};\n\n\n/*\nSanitize and provide default for the container height.\n*/\nnv.utils.sanitizeHeight = function(height, container) {\n    return (height || parseInt(container.style('height'), 10) || 400);\n};\n\n\n/*\nSanitize and provide default for the container width.\n*/\nnv.utils.sanitizeWidth = function(width, container) {\n    return (width || parseInt(container.style('width'), 10) || 960);\n};\n\n\n/*\nCalculate the available height for a chart.\n*/\nnv.utils.availableHeight = function(height, container, margin) {\n    return Math.max(0,nv.utils.sanitizeHeight(height, container) - margin.top - margin.bottom);\n};\n\n/*\nCalculate the available width for a chart.\n*/\nnv.utils.availableWidth = function(width, container, margin) {\n    return Math.max(0,nv.utils.sanitizeWidth(width, container) - margin.left - margin.right);\n};\n\n/*\nClear any rendered chart components and display a chart's 'noData' message\n*/\nnv.utils.noData = function(chart, container) {\n    var opt = chart.options(),\n        margin = opt.margin(),\n        noData = opt.noData(),\n        data = (noData == null) ? [\"No Data Available.\"] : [noData],\n        height = nv.utils.availableHeight(null, container, margin),\n        width = nv.utils.availableWidth(null, container, margin),\n        x = margin.left + width/2,\n        y = margin.top + height/2;\n\n    //Remove any previously created chart components\n    container.selectAll('g').remove();\n\n    var noDataText = container.selectAll('.nv-noData').data(data);\n\n    noDataText.enter().append('text')\n        .attr('class', 'nvd3 nv-noData')\n        .attr('dy', '-.7em')\n        .style('text-anchor', 'middle');\n\n    noDataText\n        .attr('x', x)\n        .attr('y', y)\n        .text(function(t){ return t; });\n};\n\n/*\n Wrap long labels.\n */\nnv.utils.wrapTicks = function (text, width) {\n    text.each(function() {\n        var text = d3.select(this),\n            words = text.text().split(/\\s+/).reverse(),\n            word,\n            line = [],\n            lineNumber = 0,\n            lineHeight = 1.1,\n            y = text.attr(\"y\"),\n            dy = parseFloat(text.attr(\"dy\")),\n            tspan = text.text(null).append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", dy + \"em\");\n        while (word = words.pop()) {\n            line.push(word);\n            tspan.text(line.join(\" \"));\n            if (tspan.node().getComputedTextLength() > width) {\n                line.pop();\n                tspan.text(line.join(\" \"));\n                line = [word];\n                tspan = text.append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", ++lineNumber * lineHeight + dy + \"em\").text(word);\n            }\n        }\n    });\n};\n\n/*\nCheck equality of 2 array\n*/\nnv.utils.arrayEquals = function (array1, array2) {\n    if (array1 === array2)\n        return true;\n\n    if (!array1 || !array2)\n        return false;\n\n    // compare lengths - can save a lot of time\n    if (array1.length != array2.length)\n        return false;\n\n    for (var i = 0,\n        l = array1.length; i < l; i++) {\n        // Check if we have nested arrays\n        if (array1[i] instanceof Array && array2[i] instanceof Array) {\n            // recurse into the nested arrays\n            if (!nv.arrayEquals(array1[i], array2[i]))\n                return false;\n        } else if (array1[i] != array2[i]) {\n            // Warning - two different object instances will never be equal: {x:20} != {x:20}\n            return false;\n        }\n    }\n    return true;\n};\n\n/*\n Check if a point within an arc\n */\nnv.utils.pointIsInArc = function(pt, ptData, d3Arc) {\n    // Center of the arc is assumed to be 0,0\n    // (pt.x, pt.y) are assumed to be relative to the center\n    var r1 = d3Arc.innerRadius()(ptData), // Note: Using the innerRadius\n      r2 = d3Arc.outerRadius()(ptData),\n      theta1 = d3Arc.startAngle()(ptData),\n      theta2 = d3Arc.endAngle()(ptData);\n\n    var dist = pt.x * pt.x + pt.y * pt.y,\n      angle = Math.atan2(pt.x, -pt.y); // Note: different coordinate system.\n\n    angle = (angle < 0) ? (angle + Math.PI * 2) : angle;\n\n    return (r1 * r1 <= dist) && (dist <= r2 * r2) &&\n      (theta1 <= angle) && (angle <= theta2);\n};\n\n"
  },
  {
    "path": "test/ScatterChartTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<body>\n<div style='position:relative;' class='with-transitions'>\n  <h3>Scatter chart tests</h3>\n  <div class='navigation'>\n          Tests:\n          <a href=\"lineChartTest.html\">Line Chart</a>\n          <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n          <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n          <a href=\"ScatterChartTest.html\">Scatter</a>\n  </div>\n  <div id=\"test1\" class=\"chart third\">\n    Normal - four series', all random (40 points)\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test2\" class=\"chart third\">\n    Normal - one series', all random (5 points), zero left margin\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test3\" class=\"chart third\">\n    Zero right margin, 200 points\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test4\" class=\"chart third\">\n    Bigger margins\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test5\" class=\"chart third\">\n    Zero data points\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test6\" class=\"chart third\">\n    One point.\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test7\" class=\"chart third\">\n    Two points\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test8\" class=\"chart third\">\n    Three series', one point each\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test9\" class=\"chart third\">\n    Three series', first one has zero points\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test10\" class=\"chart third\">\n    Lots of series\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test11\" class=\"chart third\">\n    Scatter plus line: y=2x + 0\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test12\" class=\"chart third\">\n    Scatter plus line: y=2x + 10;\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test13\" class=\"chart third\">\n    Scatter plus line: y=-0.5x + 1.0;\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test14\" class=\"chart third\">\n    Scatter chart: duplicate y values\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test15\" class=\"chart third\">\n    Scatter chart: duplicate x values\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n  <div id=\"test16\" class=\"chart third\">\n    Scatter chart: extremely small data points (1e-10)\n    <button>Select chart</button>\n    <svg></svg>\n  </div>\n\n\n</div>\n\n<script src=\"testScript.js\"></script>\n<script>\n\ndefaultChartTest(\"test1\", randomData(4,40));\ndefaultChartTest(\"test2\", randomData(1,5), {left:0});\ndefaultChartTest(\"test3\", randomData(2,200), {right: 0});\ndefaultChartTest(\"test4\", randomData(2, 8), {top:40, right: 90, bottom: 150, left: 150});\ndefaultChartTest(\"test5\", randomData(0,0));\ndefaultChartTest(\"test6\", randomData(1,1));\ndefaultChartTest(\"test7\", randomData(1,2));\ndefaultChartTest(\"test8\", randomData(3,1));\n\ndefaultChartTest(\"test9\", [\n  {key: \"Group 0\", values: []},\n  {key: \"Group 1\", values: [{x:1, y:1}]}\n]);\n\ndefaultChartTest(\"test10\", randomData(30,2));\n\nscatterPlusLineTest(\"test11\", randomDataSloped(2,0));\nscatterPlusLineTest(\"test12\", randomDataSloped(2,10));\nscatterPlusLineTest(\"test13\", randomDataSloped(-0.5,1));\n\ndefaultChartTest(\"test14\", [\n{key: \"Duplicate Y\",\n     values: [\n        {x: 0, y: 10}, {x:1, y:10},{x:2, y:10},{x:3, y:10}\n     ]\n    }\n]);\n\ndefaultChartTest(\"test15\",[\n   {key: \"Duplicate X\",\n      area: true,\n      values: [\n        {x: 4, y: 10},\n        {x: 4, y: 11},\n        {x: 4, y: 12},\n        {x: 4, y: 13}\n      ]\n    }\n]);\n\ndefaultChartTest(\"test16\",tinyPoints());\n\nfunction defaultChartTest(container, data, margin) {\n  nv.addGraph(function() {\n    var chart;\n    chart = nv.models.scatterChart()\n                  .showDistX(true).showDistY(true)\n                  ;\n    chart.xAxis.tickFormat(d3.format('.02f')).ticks(10);\n    chart.yAxis.tickFormat(d3.format('.02f')).ticks(10);\n    if (margin) {\n      chart.margin(margin);\n    }\n    chart.tooltipContent(function(key) {\n        return \"<h3>\" + key + \"</h3>\";\n    });\n    d3.select('#' + container + ' svg').datum(data).transition().duration(500).call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n    return chart;\n  });\n}\n\nfunction scatterPlusLineTest(container, data) {\n  nv.addGraph(function() {\n    var chart;\n    chart = nv.models.scatterChart()\n                  .showDistX(true).showDistY(true);\n    chart.xAxis.tickFormat(d3.format('.02f'));\n    chart.yAxis.tickFormat(d3.format('.02f'));\n    chart.tooltipContent(function(key) {\n        return \"<h3>\" + key + \"</h3>\";\n    });\n    d3.select('#' + container + ' svg').datum(data).transition().duration(500).call(chart);\n    nv.utils.windowResize(chart.update);\n    return chart;\n  });\n}\n\nfunction randomData(groups, points) { //# groups,# points per group\n  var data = [],\n      shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],\n      random = d3.random.normal();\n\n  for (i = 0; i < groups; i++) {\n    data.push({\n      key: 'Group ' + i,\n      values: []\n    });\n\n    for (j = 0; j < points; j++) {\n      data[i].values.push({\n        x: random(),\n        y: random(),\n        size: Math.random(),\n        shape: shapes[j % 6]\n      });\n    }\n  }\n\n  return data;\n}\n\nfunction randomDataSloped(slope,intercept) { //# groups,# points per group\n  var data = [],\n      shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],\n      random = d3.random.normal();\n\n  var groups = 2, points = 10;\n  for (i = 0; i < groups; i++) {\n    data.push({\n      key: 'Group ' + i,\n      values: [],\n      slope: slope,\n      intercept: intercept\n    });\n\n    for (j = 0; j < points; j++) {\n      data[i].values.push({\n        x: random(),\n        y: random(),\n        size: Math.random(),\n        shape: shapes[j % 6]\n      });\n    }\n  }\n\n  return data;\n}\n\nfunction tinyPoints() {\n  var rval = {key: \"Tiny points\", values: []};\n  for(var i =1; i < 20; i++) {\n    rval.values.push({\n       x: Math.random() * 1e-10,\n       y: Math.random() * 1e-10\n    });\n  }\n  return [rval];\n}\n</script>\n"
  },
  {
    "path": "test/bootstrapModalTest.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"../bower_components/d3/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script   src=\"https://code.jquery.com/jquery-2.2.4.min.js\"   integrity=\"sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=\"   crossorigin=\"anonymous\"></script>\n    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\">\n</head>\n<body>\n    <div class=\"container\">\n        <h3>Noraml Example</h3>\n        <div id=\"noraml-container\"></div>\n\n        <h3>Modal Example</h3>\n        <div>\n            <a href=\"#myModal\" role=\"button\" class=\"btn btn-default\" data-toggle=\"modal\">Launch Modal</a>\n        </div>\n\n        <div class=\"modal\" id=\"myModal\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-lg modal-offset-top\">\n                <div class=\"modal-content\">\n                    <div class=\"modal-body\">\n\n                    </div>\n                    <div class=\"modal-footer\">\n                        <button type=\"button\" class=\"btn btn-default\" data-dismiss=\"modal\">Close</button>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n    <script>\n$(function(){\n\n    drawGraph('#noraml-container');\n    \n    $('#myModal').on('shown.bs.modal', function () {\n      drawGraph('#myModal .modal-body');\n\t\t});\n    \n    \n    function drawGraph(containerSelector) {\n        nv.addGraph(function() {\n            var chart = nv.models.multiBarChart().useInteractiveGuideline(true);\n            var values = [{x: 1, y: 8}, {x: 2, y: 5}, {x: 3, y: 10}];\n            var myData = [ { key: 'key', values: values } ];\n\n            $(containerSelector).html('');\n            d3.select(containerSelector).append('svg')\n                .datum(myData)\n                .call(chart);\n\n            return chart;\n        });\n    }\n});\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "test/boxPlotTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<body class='with-3d-shadow with-transitions'>\n  <h3>Box Plot test cases</h3>\n  <div class='chart half' id=\"outlierObjects\">\n    Normal data with outlier objects (partial overrides: value/label/color)\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"customModel\">\n    Custom data model overrides\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"emptyChart\">\n    Empty chart\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"chart1\">\n    Normal data (maxBoxWidth and staggerLabel options)\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"forceY\">\n    Normal data (forceY)\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"chart3\">\n    Single box\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"chart4\">\n    Twelve boxes (repeating)\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"bad_whiskers\">\n    Bad whiskers\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"bad_outliers\">\n    Bad outliers\n    <svg></svg>\n  </div>\n  <div class='chart half' id=\"zeroWhiskers\">\n    Zero whiskers\n    <svg></svg>\n  </div>\n<script>\n\nfunction testData1() {\n    return  [\n       {\n         label: \"Sample A\",\n         values: {\n           Q1: 120,\n           Q2: 150,\n           Q3: 200,\n           whisker_low: 115,\n           whisker_high: 210,\n           outliers: [50, 100, 225]\n         },\n       },\n       {\n         label: \"Sample B\",\n         values: {\n           Q1: 300,\n           Q2: 350,\n           Q3: 400,\n           whisker_low: 225,\n           whisker_high: 400,\n           outliers: [175]\n         },\n       },\n       {\n         label: \"Sample C\",\n         values: {\n           Q1: 50,\n           Q2: 100,\n           Q3: 125,\n           whisker_low: 25,\n           whisker_high: 175,\n           outliers: [0]\n         },\n       }\n     ];\n}\n\nfunction testOutlierObjects() {\n    return [\n        {\n            label: \"A1\",\n            values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210,\n                outliers: [\n                    {value: 50, label: 'apples'}, {value: 100, color: '#000000'},\n                    {value: 250, label: 'Artifical outlier', color: '#F00'}, {value: 225}\n                ]\n            }\n        },\n        {\n            label: \"B2\",\n            values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 225, whisker_high: 400,\n                outliers: [{value: 75}]\n            }\n        },\n        {\n            label: \"C3\",\n            values: { Q1: 50, Q2: 100, Q3: 125, whisker_low: 25, whisker_high: 175,\n                outliers: [{value: 0, label: 'Bananas', color: '#000000'}]\n            }\n        }\n    ];\n}\n\nfunction testCustomObjectModel() {\n    return [\n        {\n            title: 'Custom Attributes 1',\n            q1: 1.05, q3: 2.7, maxOutlier: 6, maxRegularValue: 4.4,\n            mean: 3.365, median: 1.3, minOutlier: 0.4, minRegularValue: 0.4,\n            outlData: [\n                {data: 6, text: 'Source 1'},\n                {data: 14.5, text: 'Source 2'},\n                {data: 12, text: 'Reference Value', color: '#000'},\n                {data: 4.5, text: 'Source 3'}\n            ],\n            seriesColor: '#247E42'\n        },\n        {\n            title: 'Custom Attributes 2',\n            q1: 1.05, q3: 2.849999996, maxOutlier: 4.9, maxRegularValue: 4.9,\n            mean: 3.4949999, median: 1.5, minOutlier: 0.3, minRegularValue: 0.3,\n            outlData: [\n                {data: 15.2, text: 'Source 1'},\n                {data: 10, text: 'Reference Value', color: '#F00'},\n                {data: 7.5, color: '#00F'}\n            ],\n            seriesColor: '#334693'\n        }\n    ]\n}\n\nfunction testSingleBox() {\n    return [\n        {\n            label: 'Sample A',\n            values: {\n                Q1: 120,\n                Q2: 150,\n                Q3: 200,\n                whisker_low: 115,\n                whisker_high: 210,\n                outliers: [50, 100, 225]\n            }\n        }\n    ]\n}\n\nfunction testDozenBoxes() {\n    return [\n       { label: \"Sample A\", values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210, outliers: [50, 100, 225] } },\n       { label: \"Sample B\", values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 225, whisker_high: 400, outliers: [175] } },\n       { label: \"Sample C\", values: { Q1: 50, Q2: 100, Q3: 125, whisker_low: 25, whisker_high: 75, outliers: [0] } },\n\n       { label: \"Sample D\", values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210, outliers: [50, 100, 225] } },\n       { label: \"Sample E\", values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 225, whisker_high: 400, outliers: [175] } },\n       { label: \"Sample F\", values: { Q1: 50, Q2: 100, Q3: 125, whisker_low: 25, whisker_high: 75, outliers: [0] } },\n\n       { label: \"Sample H\", values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210, outliers: [50, 100, 225] } },\n       { label: \"Sample I\", values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 225, whisker_high: 400, outliers: [175] } },\n       { label: \"Sample J\", values: { Q1: 50, Q2: 100, Q3: 125, whisker_low: 25, whisker_high: 75, outliers: [0] } },\n\n       { label: \"Sample K\", values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210, outliers: [50, 100, 225] } },\n       { label: \"Sample L\", values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 225, whisker_high: 400, outliers: [175] } },\n       { label: \"Sample M\", values: { Q1: 50, Q2: 100, Q3: 125, whisker_low: 25, whisker_high: 75, outliers: [0] } },\n    ]\n}\n\nfunction badWhiskers() {\n    return [\n        {\n          \"label\": \"Missing High\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: 50,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Missing Low\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_high: 200,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Null High\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: 50,\n            whisker_high: null,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Null Low\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: null,\n            whisker_high: 200,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Both Missing\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Both Null\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: null,\n            whisker_high: null,\n            outliers: []\n          }\n        },\n        {\n          \"label\": \"Both Missing with Outliers\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            outliers: [25, 250]\n          }\n        }\n    ]\n}\n\nfunction badOutliers() {\n    return [\n        {\n          \"label\": \"Empty outlier list\",\n          \"values\": {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: 50,\n            whisker_high: 200,\n            outliers: []\n          }\n        },\n        {\n          label: \"Null outliers\",\n          values: {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: 50,\n            whisker_high: 200,\n            outliers: null\n          }\n        },\n        {\n          label: \"No outliers\",\n          values: {\n            Q1: 100,\n            Q2: 125,\n            Q3: 150,\n            whisker_low: 50,\n            whisker_high: 200,\n          }\n        }\n    ]\n}\n\nfunction zeroWhiskers() {\n  return [\n    {\n      label: 'Zero Whisker Low',\n      values: {\n        Q1: 1,\n        Q2: 2,\n        Q3: 3,\n        whisker_high: 10,\n        whisker_low: 0,\n        outliers: [-1, 11]\n      }\n    },\n    {\n      label: 'Zero Whisker High',\n      values: {\n        Q1: -3,\n        Q2: -2,\n        Q3: -1,\n        whisker_high: 0,\n        whisker_low: -5,\n        outliers: [-10, 1]\n      }\n    }\n  ];\n};\n\ndefaultChartConfig(\"outlierObjects\", testOutlierObjects, {\n  outlierValue: function (d) { return d.value },\n  outlierColor: function (d) { return d.color },\n  outlierLabel: function (d) {\n    if (d.label) { return d.value + ' ' + d.label }\n    return d.value;\n  }\n});\n\ndefaultChartConfig(\"customModel\", testCustomObjectModel, {\n    x: function (d) { return d.title },\n    itemColor: function (d) { return d.seriesColor },\n    outliers: function (d) { return d.outlData },\n    outlierValue: function (d) { return d.data },\n    outlierLabel: function (d) {\n        if (d.text) { return d.data + ' ' + d.text }\n        return d.data;\n    },\n    outlierColor: function (d) { return d.color },\n    q1: function (d) { return d.q1 },\n    q2: function (d) { return d.median },\n    q3: function (d) { return d.q3 },\n    wl: function (d) { return d.minRegularValue },\n    wh: function (d) { return d.maxRegularValue }\n});\n\ndefaultChartConfig(\"emptyChart\", {}, {});\n\ndefaultChartConfig(\"chart1\", testData1, {\n  staggerLabels: true,\n  maxBoxWidth: 32\n});\n\ndefaultChartConfig(\"forceY\", testData1, {\n  yDomain: [0, 500]\n});\n\ndefaultChartConfig(\"chart3\", testSingleBox, {});\n\ndefaultChartConfig(\"chart4\", testDozenBoxes, {\n  staggerLabels: true,\n  maxBoxWidth: 32\n});\n\ndefaultChartConfig(\"bad_whiskers\", badWhiskers, {\n  staggerLabels: true\n});\ndefaultChartConfig(\"bad_outliers\", badOutliers, {});\ndefaultChartConfig(\"zeroWhiskers\", zeroWhiskers, {});\n\nfunction defaultChartConfig(containerId, data, chartOptions) {\n  nv.addGraph(function() {\n      var chart;\n      chart = nv.models.boxPlotChart()\n        .x(function(d) { return d.label })\n        .y(function(d) { return d.values.Q3 })\n        .margin({bottom: 100});\n      chart.options(chartOptions);\n\n      d3.select('#' + containerId + ' svg')\n        .datum(data)\n        .call(chart);\n\n      nv.utils.windowResize(chart.update);\n\n      return chart;\n  });\n}\n</script>\n"
  },
  {
    "path": "test/cumulativeLineChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n\n.chart svg {\n  height: 450px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  margin: 50px;\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n</style>\n<body>\n  <div class='navigation'>\n      Tests:\n      <a href=\"../test/lineChartTest.html\">Line Chart</a>\n      <a href=\"../test/stackedAreaChartTest.html\">Stacked Area</a>\n      <a href=\"cumulativeLineChart.html\">Cumulative Line</a>\n  </div>\n  <div id=\"chart1\" class='chart with-transitions'>\n    <strong>Chart with new tooltips and guide line (with-transitions)</strong>\n    <svg></svg>\n  </div>\n  <div id=\"chart2\" class='chart with-transitions'>\n    <strong>Chart with old tooltips (with-transitions)</strong>\n    <svg></svg>\n  </div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/interactiveLayer.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/line.js\"></script>\n<script src=\"../src/models/cumulativeLineChart.js\"></script>\n<script>\n\n// Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required\n\nnv.addGraph(function() {  \n  var chart = nv.models.cumulativeLineChart()\n              .useInteractiveGuideline(true)\n              .x(function(d) { return d[0] })\n              .y(function(d) { return d[1]/100 })\n              .color(d3.scale.category10().range())\n              .average(function(d) { return d.mean/100; })\n              .duration(300)\n              .clipVoronoi(false);\n  chart.dispatch.on('renderEnd', function() {\n    console.log('render complete: cumulative line with guide line');\n  });\n\n  chart.xAxis\n    .tickFormat(function(d) {\n      return d3.time.format('%m/%d/%y')(new Date(d))\n    });\n\n  chart.yAxis\n      .tickFormat(d3.format(',.1%'));\n\n  d3.select('#chart1 svg')\n      .datum(cumulativeTestData())\n      .call(chart);\n\n  //TODO: Figure out a good way to do this automatically\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\nnv.addGraph(function() {  \n   var chart = nv.models.cumulativeLineChart()\n             .useInteractiveGuideline(false)\n             .rightAlignYAxis(true)\n             .margin({right:90})\n             .x(function(d) { return d[0] })\n             .y(function(d) { return d[1]/100 })\n             .color(d3.scale.category10().range())\n             .average(function(d) { return d.mean/100; })\n             .duration(300)\n             .clipVoronoi(false);\n\n  chart.dispatch.on('renderEnd', function() {\n    console.log('render complete: cumulative line without guide line');\n  });\n\n   chart.xAxis\n      .tickFormat(function(d) {\n          return d3.time.format('%m/%d/%y')(new Date(d))\n        });\n\n  chart.yAxis\n      .tickFormat(d3.format(',.1%'));\n\n  d3.select('#chart2 svg')\n      .datum(cumulativeTestData())\n      .call(chart);\n\n  //TODO: Figure out a good way to do this automatically\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\n\nfunction flatTestData() {\n  return [\n    {\n      key: \"Snakes\",\n      values: [0,1,2,3,4,5,6,7,8,9].map(function(d) {\n        var currentDate = new Date();\n        currentDate.setDate(currentDate.getDate() + d);\n        return [currentDate, 0]\n      })\n    }\n  ];\n}\n\n\nfunction cumulativeTestData() {\n\n\n\n  return [\n\n                {\n                    key: \"Long\",\n                    values: [ [ 1083297600000 , -2.974623048543] , [ 1085976000000 , -1.7740300785979] , [ 1088568000000 , 4.4681318138177] , [ 1091246400000 , 7.0242541001353] , [ 1093924800000 , 7.5709603667586] , [ 1096516800000 , 20.612245065736] , [ 1099195200000 , 21.698065237316] , [ 1101790800000 , 40.501189458018] , [ 1104469200000 , 50.464679413194] , [ 1107147600000 , 48.917421973355] , [ 1109566800000 , 63.750936549160] , [ 1112245200000 , 59.072499126460] , [ 1114833600000 , 43.373158880492] , [ 1117512000000 , 54.490918947556] , [ 1120104000000 , 56.661178852079] , [ 1122782400000 , 73.450103545496] , [ 1125460800000 , 71.714526354907] , [ 1128052800000 , 85.221664349607] , [ 1130734800000 , 77.769261392481] , [ 1133326800000 , 95.966528716500] , [ 1136005200000 , 107.59132116397] , [ 1138683600000 , 127.25740096723] , [ 1141102800000 , 122.13917498830] , [ 1143781200000 , 126.53657279774] , [ 1146369600000 , 132.39300992970] , [ 1149048000000 , 120.11238242904] , [ 1151640000000 , 118.41408917750] , [ 1154318400000 , 107.92918924621] , [ 1156996800000 , 110.28057249569] , [ 1159588800000 , 117.20485334692] , [ 1162270800000 , 141.33556756948] , [ 1164862800000 , 159.59452727893] , [ 1167541200000 , 167.09801853304] , [ 1170219600000 , 185.46849659215] , [ 1172638800000 , 184.82474099990] , [ 1175313600000 , 195.63155213887] , [ 1177905600000 , 207.40597044171] , [ 1180584000000 , 230.55966698196] , [ 1183176000000 , 239.55649035292] , [ 1185854400000 , 241.35915085208] , [ 1188532800000 , 239.89428956243] , [ 1191124800000 , 260.47781917715] , [ 1193803200000 , 276.39457482225] , [ 1196398800000 , 258.66530682672] , [ 1199077200000 , 250.98846121893] , [ 1201755600000 , 226.89902618127] , [ 1204261200000 , 227.29009273807] , [ 1206936000000 , 218.66476654350] , [ 1209528000000 , 232.46605902918] , [ 1212206400000 , 253.25667081117] , [ 1214798400000 , 235.82505363925] , [ 1217476800000 , 229.70112774254] , [ 1220155200000 , 225.18472705952] , [ 1222747200000 , 189.13661746552] , [ 1225425600000 , 149.46533007301] , [ 1228021200000 , 131.00340772114] , [ 1230699600000 , 135.18341728866] , [ 1233378000000 , 109.15296887173] , [ 1235797200000 , 84.614772549760] , [ 1238472000000 , 100.60810015326] , [ 1241064000000 , 141.50134895610] , [ 1243742400000 , 142.50405083675] , [ 1246334400000 , 139.81192372672] , [ 1249012800000 , 177.78205544583] , [ 1251691200000 , 194.73691933074] , [ 1254283200000 , 209.00838460225] , [ 1256961600000 , 198.19855877420] , [ 1259557200000 , 222.37102417812] , [ 1262235600000 , 234.24581081250] , [ 1264914000000 , 228.26087689346] , [ 1267333200000 , 248.81895126250] , [ 1270008000000 , 270.57301075186] , [ 1272600000000 , 292.64604322550] , [ 1275278400000 , 265.94088520518] , [ 1277870400000 , 237.82887467569] , [ 1280548800000 , 265.55973314204] , [ 1283227200000 , 248.30877330928] , [ 1285819200000 , 278.14870066912] , [ 1288497600000 , 292.69260960288] , [ 1291093200000 , 300.84263809599] , [ 1293771600000 , 326.17253914628] , [ 1296450000000 , 337.69335966505] , [ 1298869200000 , 339.73260965121] , [ 1301544000000 , 346.87865120765] , [ 1304136000000 , 347.92991526628] , [ 1306814400000 , 342.04627502669] , [ 1309406400000 , 333.45386231233] , [ 1312084800000 , 323.15034181243] , [ 1314763200000 , 295.66126882331] , [ 1317355200000 , 251.48014579253] , [ 1320033600000 , 295.15424257905] , [ 1322629200000 , 294.54766764397] , [ 1325307600000 , 295.72906119051] , [ 1327986000000 , 325.73351347613] , [ 1330491600000 , 340.16106061186] , [ 1333166400000 , 345.15514071490] , [ 1335758400000 , 337.10259395679] , [ 1338436800000 , 318.68216333837] , [ 1341028800000 , 317.03683945246] , [ 1343707200000 , 318.53549659997] , [ 1346385600000 , 332.85381464104] , [ 1348977600000 , 337.36534373477] , [ 1351656000000 , 350.27872156161] , [ 1354251600000 , 349.45128876100]]\n                    ,\n                    mean: 250\n                },\n                {\n                    key: \"Short\",\n                    values: [ [ 1083297600000 , -0.77078283705125] , [ 1085976000000 , -1.8356366650335] , [ 1088568000000 , -5.3121322073127] , [ 1091246400000 , -4.9320975829662] , [ 1093924800000 , -3.9835408823225] , [ 1096516800000 , -6.8694685316805] , [ 1099195200000 , -8.4854877428545] , [ 1101790800000 , -15.933627197384] , [ 1104469200000 , -15.920980069544] , [ 1107147600000 , -12.478685045651] , [ 1109566800000 , -17.297761889305] , [ 1112245200000 , -15.247129891020] , [ 1114833600000 , -11.336459046839] , [ 1117512000000 , -13.298990907415] , [ 1120104000000 , -16.360027000056] , [ 1122782400000 , -18.527929522030] , [ 1125460800000 , -22.176516738685] , [ 1128052800000 , -23.309665368330] , [ 1130734800000 , -21.629973409748] , [ 1133326800000 , -24.186429093486] , [ 1136005200000 , -29.116707312531] , [ 1138683600000 , -37.188037874864] , [ 1141102800000 , -34.689264821198] , [ 1143781200000 , -39.505932105359] , [ 1146369600000 , -45.339572492759] , [ 1149048000000 , -43.849353192764] , [ 1151640000000 , -45.418353922571] , [ 1154318400000 , -44.579281059919] , [ 1156996800000 , -44.027098363370] , [ 1159588800000 , -41.261306759439] , [ 1162270800000 , -47.446018534027] , [ 1164862800000 , -53.413782948909] , [ 1167541200000 , -50.700723647419] , [ 1170219600000 , -56.374090913296] , [ 1172638800000 , -61.754245220322] , [ 1175313600000 , -66.246241587629] , [ 1177905600000 , -75.351650899999] , [ 1180584000000 , -81.699058262032] , [ 1183176000000 , -82.487023368081] , [ 1185854400000 , -86.230055113277] , [ 1188532800000 , -84.746914818507] , [ 1191124800000 , -100.77134971977] , [ 1193803200000 , -109.95435565947] , [ 1196398800000 , -99.605672965057] , [ 1199077200000 , -99.607249394382] , [ 1201755600000 , -94.874614950188] , [ 1204261200000 , -105.35899063105] , [ 1206936000000 , -106.01931193802] , [ 1209528000000 , -110.28883571771] , [ 1212206400000 , -119.60256203030] , [ 1214798400000 , -115.62201315802] , [ 1217476800000 , -106.63824185202] , [ 1220155200000 , -99.848746318951] , [ 1222747200000 , -85.631219602987] , [ 1225425600000 , -63.547909262067] , [ 1228021200000 , -59.753275364457] , [ 1230699600000 , -63.874977883542] , [ 1233378000000 , -56.865697387488] , [ 1235797200000 , -54.285579501988] , [ 1238472000000 , -56.474659581885] , [ 1241064000000 , -63.847137745644] , [ 1243742400000 , -68.754247867325] , [ 1246334400000 , -69.474257009155] , [ 1249012800000 , -75.084828197067] , [ 1251691200000 , -77.101028237237] , [ 1254283200000 , -80.454866854387] , [ 1256961600000 , -78.984349952220] , [ 1259557200000 , -83.041230807854] , [ 1262235600000 , -84.529748348935] , [ 1264914000000 , -83.837470195508] , [ 1267333200000 , -87.174487671969] , [ 1270008000000 , -90.342293007487] , [ 1272600000000 , -93.550928464991] , [ 1275278400000 , -85.833102140765] , [ 1277870400000 , -79.326501831592] , [ 1280548800000 , -87.986196903537] , [ 1283227200000 , -85.397862121771] , [ 1285819200000 , -94.738167050020] , [ 1288497600000 , -98.661952897151] , [ 1291093200000 , -99.609665952708] , [ 1293771600000 , -103.57099836183] , [ 1296450000000 , -104.04353411322] , [ 1298869200000 , -108.21382792587] , [ 1301544000000 , -108.74006900920] , [ 1304136000000 , -112.07766650960] , [ 1306814400000 , -109.63328199118] , [ 1309406400000 , -106.53578966772] , [ 1312084800000 , -103.16480871469] , [ 1314763200000 , -95.945078001828] , [ 1317355200000 , -81.226687340874] , [ 1320033600000 , -90.782206596168] , [ 1322629200000 , -89.484445370113] , [ 1325307600000 , -88.514723135326] , [ 1327986000000 , -93.381292724320] , [ 1330491600000 , -97.529705609172] , [ 1333166400000 , -99.520481439189] , [ 1335758400000 , -99.430184898669] , [ 1338436800000 , -93.349934521973] , [ 1341028800000 , -95.858475286491] , [ 1343707200000 , -95.522755836605] , [ 1346385600000 , -98.503848862036] , [ 1348977600000 , -101.49415251896] , [ 1351656000000 , -101.50099325672] , [ 1354251600000 , -99.487094927489]]\n                    ,\n                    mean: -60\n                },\n                \n                 \n                {\n                    key: \"Gross\",\n                    mean: 125,\n                    values: [ [ 1083297600000 , -3.7454058855943] , [ 1085976000000 , -3.6096667436314] , [ 1088568000000 , -0.8440003934950] , [ 1091246400000 , 2.0921565171691] , [ 1093924800000 , 3.5874194844361] , [ 1096516800000 , 13.742776534056] , [ 1099195200000 , 13.212577494462] , [ 1101790800000 , 24.567562260634] , [ 1104469200000 , 34.543699343650] , [ 1107147600000 , 36.438736927704] , [ 1109566800000 , 46.453174659855] , [ 1112245200000 , 43.825369235440] , [ 1114833600000 , 32.036699833653] , [ 1117512000000 , 41.191928040141] , [ 1120104000000 , 40.301151852023] , [ 1122782400000 , 54.922174023466] , [ 1125460800000 , 49.538009616222] , [ 1128052800000 , 61.911998981277] , [ 1130734800000 , 56.139287982733] , [ 1133326800000 , 71.780099623014] , [ 1136005200000 , 78.474613851439] , [ 1138683600000 , 90.069363092366] , [ 1141102800000 , 87.449910167102] , [ 1143781200000 , 87.030640692381] , [ 1146369600000 , 87.053437436941] , [ 1149048000000 , 76.263029236276] , [ 1151640000000 , 72.995735254929] , [ 1154318400000 , 63.349908186291] , [ 1156996800000 , 66.253474132320] , [ 1159588800000 , 75.943546587481] , [ 1162270800000 , 93.889549035453] , [ 1164862800000 , 106.18074433002] , [ 1167541200000 , 116.39729488562] , [ 1170219600000 , 129.09440567885] , [ 1172638800000 , 123.07049577958] , [ 1175313600000 , 129.38531055124] , [ 1177905600000 , 132.05431954171] , [ 1180584000000 , 148.86060871993] , [ 1183176000000 , 157.06946698484] , [ 1185854400000 , 155.12909573880] , [ 1188532800000 , 155.14737474392] , [ 1191124800000 , 159.70646945738] , [ 1193803200000 , 166.44021916278] , [ 1196398800000 , 159.05963386166] , [ 1199077200000 , 151.38121182455] , [ 1201755600000 , 132.02441123108] , [ 1204261200000 , 121.93110210702] , [ 1206936000000 , 112.64545460548] , [ 1209528000000 , 122.17722331147] , [ 1212206400000 , 133.65410878087] , [ 1214798400000 , 120.20304048123] , [ 1217476800000 , 123.06288589052] , [ 1220155200000 , 125.33598074057] , [ 1222747200000 , 103.50539786253] , [ 1225425600000 , 85.917420810943] , [ 1228021200000 , 71.250132356683] , [ 1230699600000 , 71.308439405118] , [ 1233378000000 , 52.287271484242] , [ 1235797200000 , 30.329193047772] , [ 1238472000000 , 44.133440571375] , [ 1241064000000 , 77.654211210456] , [ 1243742400000 , 73.749802969425] , [ 1246334400000 , 70.337666717565] , [ 1249012800000 , 102.69722724876] , [ 1251691200000 , 117.63589109350] , [ 1254283200000 , 128.55351774786] , [ 1256961600000 , 119.21420882198] , [ 1259557200000 , 139.32979337027] , [ 1262235600000 , 149.71606246357] , [ 1264914000000 , 144.42340669795] , [ 1267333200000 , 161.64446359053] , [ 1270008000000 , 180.23071774437] , [ 1272600000000 , 199.09511476051] , [ 1275278400000 , 180.10778306442] , [ 1277870400000 , 158.50237284410] , [ 1280548800000 , 177.57353623850] , [ 1283227200000 , 162.91091118751] , [ 1285819200000 , 183.41053361910] , [ 1288497600000 , 194.03065670573] , [ 1291093200000 , 201.23297214328] , [ 1293771600000 , 222.60154078445] , [ 1296450000000 , 233.35556801977] , [ 1298869200000 , 231.22452435045] , [ 1301544000000 , 237.84432503045] , [ 1304136000000 , 235.55799131184] , [ 1306814400000 , 232.11873570751] , [ 1309406400000 , 226.62381538123] , [ 1312084800000 , 219.34811113539] , [ 1314763200000 , 198.69242285581] , [ 1317355200000 , 168.90235629066] , [ 1320033600000 , 202.64725756733] , [ 1322629200000 , 203.05389378105] , [ 1325307600000 , 204.85986680865] , [ 1327986000000 , 229.77085616585] , [ 1330491600000 , 239.65202435959] , [ 1333166400000 , 242.33012622734] , [ 1335758400000 , 234.11773262149] , [ 1338436800000 , 221.47846307887] , [ 1341028800000 , 216.98308827912] , [ 1343707200000 , 218.37781386755] , [ 1346385600000 , 229.39368622736] , [ 1348977600000 , 230.54656412916] , [ 1351656000000 , 243.06087025523] , [ 1354251600000 , 244.24733578385]]\n                },\n                {\n                    key: \"S&P 1500\",\n                    values: [ [ 1083297600000 , -1.7798428181819] , [ 1085976000000 , -0.36883324836999] , [ 1088568000000 , 1.7312581046040] , [ 1091246400000 , -1.8356125950460] , [ 1093924800000 , -1.5396564170877] , [ 1096516800000 , -0.16867791409247] , [ 1099195200000 , 1.3754263993413] , [ 1101790800000 , 5.8171640898041] , [ 1104469200000 , 9.4350145241608] , [ 1107147600000 , 6.7649081510160] , [ 1109566800000 , 9.1568499314776] , [ 1112245200000 , 7.2485090994419] , [ 1114833600000 , 4.8762222306595] , [ 1117512000000 , 8.5992339354652] , [ 1120104000000 , 9.0896517982086] , [ 1122782400000 , 13.394644048577] , [ 1125460800000 , 12.311842010760] , [ 1128052800000 , 13.221003650717] , [ 1130734800000 , 11.218481009206] , [ 1133326800000 , 15.565352598445] , [ 1136005200000 , 15.623703865926] , [ 1138683600000 , 19.275255326383] , [ 1141102800000 , 19.432433717836] , [ 1143781200000 , 21.232881244655] , [ 1146369600000 , 22.798299192958] , [ 1149048000000 , 19.006125095476] , [ 1151640000000 , 19.151889158536] , [ 1154318400000 , 19.340022855452] , [ 1156996800000 , 22.027934841859] , [ 1159588800000 , 24.903300681329] , [ 1162270800000 , 29.146492833877] , [ 1164862800000 , 31.781626082589] , [ 1167541200000 , 33.358770738428] , [ 1170219600000 , 35.622684613497] , [ 1172638800000 , 33.332821711366] , [ 1175313600000 , 34.878748635832] , [ 1177905600000 , 40.582332613844] , [ 1180584000000 , 45.719535502920] , [ 1183176000000 , 43.239344722386] , [ 1185854400000 , 38.550955100342] , [ 1188532800000 , 40.585368816283] , [ 1191124800000 , 45.601374057981] , [ 1193803200000 , 48.051404337892] , [ 1196398800000 , 41.582581696032] , [ 1199077200000 , 40.650580792748] , [ 1201755600000 , 32.252222066493] , [ 1204261200000 , 28.106390258553] , [ 1206936000000 , 27.532698196687] , [ 1209528000000 , 33.986390463852] , [ 1212206400000 , 36.302660526438] , [ 1214798400000 , 25.015574480172] , [ 1217476800000 , 23.989494069029] , [ 1220155200000 , 25.934351445531] , [ 1222747200000 , 14.627592011699] , [ 1225425600000 , -5.2249403809749] , [ 1228021200000 , -12.330933408050] , [ 1230699600000 , -11.000291508188] , [ 1233378000000 , -18.563864948088] , [ 1235797200000 , -27.213097001687] , [ 1238472000000 , -20.834133840523] , [ 1241064000000 , -12.717886701719] , [ 1243742400000 , -8.1644613083526] , [ 1246334400000 , -7.9108408918201] , [ 1249012800000 , -0.77002391591209] , [ 1251691200000 , 2.8243816569672] , [ 1254283200000 , 6.8761411421070] , [ 1256961600000 , 4.5060912230294] , [ 1259557200000 , 10.487179794349] , [ 1262235600000 , 13.251375597594] , [ 1264914000000 , 9.2207594803415] , [ 1267333200000 , 12.836276936538] , [ 1270008000000 , 19.816793904978] , [ 1272600000000 , 22.156787167211] , [ 1275278400000 , 12.518039090576] , [ 1277870400000 , 6.4253587440854] , [ 1280548800000 , 13.847372028409] , [ 1283227200000 , 8.5454736090364] , [ 1285819200000 , 18.542801953304] , [ 1288497600000 , 23.037064683183] , [ 1291093200000 , 23.517422401888] , [ 1293771600000 , 31.804723416068] , [ 1296450000000 , 34.778247386072] , [ 1298869200000 , 39.584883855230] , [ 1301544000000 , 40.080647664875] , [ 1304136000000 , 44.180050667889] , [ 1306814400000 , 42.533535927221] , [ 1309406400000 , 40.105374449011] , [ 1312084800000 , 37.014659267156] , [ 1314763200000 , 29.263745084262] , [ 1317355200000 , 19.637463417584] , [ 1320033600000 , 33.157645345770] , [ 1322629200000 , 32.895053150988] , [ 1325307600000 , 34.111544824647] , [ 1327986000000 , 40.453985817473] , [ 1330491600000 , 46.435700783313] , [ 1333166400000 , 51.062385488671] , [ 1335758400000 , 50.130448220658] , [ 1338436800000 , 41.035476682018] , [ 1341028800000 , 46.591932296457] , [ 1343707200000 , 48.349391180634] , [ 1346385600000 , 51.913011286919] , [ 1348977600000 , 55.747238313752] , [ 1351656000000 , 52.991824077209] , [ 1354251600000 , 49.556311883284]]\n                }\n            ];\n\n\n\n\n\n  return [\n                {\n                    key: \"Series 1\",\n                    values: [ [ 1025409600000 , 0] , [ 1028088000000 , -6.3382185140371] , [ 1030766400000 , -5.9507873460847] , [ 1033358400000 , -11.569146943813] , [ 1036040400000 , -5.4767332317425] , [ 1038632400000 , 0.50794682203014] , [ 1041310800000 , -5.5310285460542] , [ 1043989200000 , -5.7838296963382] , [ 1046408400000 , -7.3249341615649] , [ 1049086800000 , -6.7078630712489] , [ 1051675200000 , 0.44227126150934] , [ 1054353600000 , 7.2481659343222] , [ 1056945600000 , 9.2512381306992] , [ 1059624000000 , 11.341210982529] , [ 1062302400000 , 14.734820409020] , [ 1064894400000 , 12.387148007542] , [ 1067576400000 , 18.436471461827] , [ 1070168400000 , 19.830742266977] , [ 1072846800000 , 22.643205829887] , [ 1075525200000 , 26.743156781239] , [ 1078030800000 , 29.597478802228] , [ 1080709200000 , 30.831697585341] , [ 1083297600000 , 28.054068024708] , [ 1085976000000 , 29.294079423832] , [ 1088568000000 , 30.269264061274] , [ 1091246400000 , 24.934526898906] , [ 1093924800000 , 24.265982759406] , [ 1096516800000 , 27.217794897473] , [ 1099195200000 , 30.802601992077] , [ 1101790800000 , 36.331003758254] , [ 1104469200000 , 43.142498700060] , [ 1107147600000 , 40.558263931958] , [ 1109566800000 , 42.543622385800] , [ 1112245200000 , 41.683584710331] , [ 1114833600000 , 36.375367302328] , [ 1117512000000 , 40.719688980730] , [ 1120104000000 , 43.897963036919] , [ 1122782400000 , 49.797033975368] , [ 1125460800000 , 47.085993935989] , [ 1128052800000 , 46.601972859745] , [ 1130734800000 , 41.567784572762] , [ 1133326800000 , 47.296923737245] , [ 1136005200000 , 47.642969612080] , [ 1138683600000 , 50.781515820954] , [ 1141102800000 , 52.600229204305] , [ 1143781200000 , 55.599684490628] , [ 1146369600000 , 57.920388436633] , [ 1149048000000 , 53.503593218971] , [ 1151640000000 , 53.522973979964] , [ 1154318400000 , 49.846822298548] , [ 1156996800000 , 54.721341614650] , [ 1159588800000 , 58.186236223191] , [ 1162270800000 , 63.908065540997] , [ 1164862800000 , 69.767285129367] , [ 1167541200000 , 72.534013373592] , [ 1170219600000 , 77.991819436573] , [ 1172638800000 , 78.143584404990] , [ 1175313600000 , 83.702398665233] , [ 1177905600000 , 91.140859312418] , [ 1180584000000 , 98.590960607028] , [ 1183176000000 , 96.245634754228] , [ 1185854400000 , 92.326364432615] , [ 1188532800000 , 97.068765332230] , [ 1191124800000 , 105.81025556260] , [ 1193803200000 , 114.38348777791] , [ 1196398800000 , 103.59604949810] , [ 1199077200000 , 101.72488429307] , [ 1201755600000 , 89.840147735028] , [ 1204261200000 , 86.963597532664] , [ 1206936000000 , 84.075505208491] , [ 1209528000000 , 93.170105645831] , [ 1212206400000 , 103.62838083121] , [ 1214798400000 , 87.458241365091] , [ 1217476800000 , 85.808374141319] , [ 1220155200000 , 93.158054469193] , [ 1222747200000 , 65.973252382360] , [ 1225425600000 , 44.580686638224] , [ 1228021200000 , 36.418977140128] , [ 1230699600000 , 38.727678144761] , [ 1233378000000 , 36.692674173387] , [ 1235797200000 , 30.033022809480] , [ 1238472000000 , 36.707532162718] , [ 1241064000000 , 52.191457688389] , [ 1243742400000 , 56.357883979735] , [ 1246334400000 , 57.629002180305] , [ 1249012800000 , 66.650985790166] , [ 1251691200000 , 70.839243432186] , [ 1254283200000 , 78.731998491499] , [ 1256961600000 , 72.375528540349] , [ 1259557200000 , 81.738387881630] , [ 1262235600000 , 87.539792394232] , [ 1264914000000 , 84.320762662273] , [ 1267333200000 , 90.621278391889] , [ 1270008000000 , 102.47144881651] , [ 1272600000000 , 102.79320353429] , [ 1275278400000 , 90.529736050479] , [ 1277870400000 , 76.580859994531] , [ 1280548800000 , 86.548979376972] , [ 1283227200000 , 81.879653334089] , [ 1285819200000 , 101.72550015956] , [ 1288497600000 , 107.97964852260] , [ 1291093200000 , 106.16240630785] , [ 1293771600000 , 114.84268599533] , [ 1296450000000 , 121.60793322282] , [ 1298869200000 , 133.41437346605] , [ 1301544000000 , 125.46646042904] , [ 1304136000000 , 129.76784954301] , [ 1306814400000 , 128.15798861044] , [ 1309406400000 , 121.92388706072] , [ 1312084800000 , 116.70036100870] , [ 1314763200000 , 88.367701837033] , [ 1317355200000 , 59.159665765725] , [ 1320033600000 , 79.793568139753] , [ 1322629200000 , 75.903834028417] , [ 1325307600000 , 72.704218209157] , [ 1327986000000 , 84.936990804097] , [ 1330491600000 , 93.388148670744]]\n                },\n                {\n                    key: \"Series 2\",\n                    values: [ [ 1025409600000 , 0] , [ 1028088000000 , 0] , [ 1030766400000 , 0] , [ 1033358400000 , 0] , [ 1036040400000 , 0] , [ 1038632400000 , 0] , [ 1041310800000 , 0] , [ 1043989200000 , 0] , [ 1046408400000 , 0] , [ 1049086800000 , 0] , [ 1051675200000 , 0] , [ 1054353600000 , 0] , [ 1056945600000 , 0] , [ 1059624000000 , 0] , [ 1062302400000 , 0] , [ 1064894400000 , 0] , [ 1067576400000 , 0] , [ 1070168400000 , 0] , [ 1072846800000 , 0] , [ 1075525200000 , -0.049184266875945] , [ 1078030800000 , -0.10757569491991] , [ 1080709200000 , -0.075601531307242] , [ 1083297600000 , -0.061245277988149] , [ 1085976000000 , -0.068227316401169] , [ 1088568000000 , -0.11242758058502] , [ 1091246400000 , -0.074848439408270] , [ 1093924800000 , -0.11465623676497] , [ 1096516800000 , -0.24370633342416] , [ 1099195200000 , -0.21523268478893] , [ 1101790800000 , -0.37859370911822] , [ 1104469200000 , -0.41932884345151] , [ 1107147600000 , -0.45393735984802] , [ 1109566800000 , -0.50868179522598] , [ 1112245200000 , -0.48164396881207] , [ 1114833600000 , -0.41605962887194] , [ 1117512000000 , -0.48490348490240] , [ 1120104000000 , -0.55071036101311] , [ 1122782400000 , -0.67489170505394] , [ 1125460800000 , -0.74978070939342] , [ 1128052800000 , -0.86395050745343] , [ 1130734800000 , -0.78524898506764] , [ 1133326800000 , -0.99800440950854] , [ 1136005200000 , -1.1177951153878] , [ 1138683600000 , -1.4119975432964] , [ 1141102800000 , -1.2409959736465] , [ 1143781200000 , -1.3088936375431] , [ 1146369600000 , -1.5495785469683] , [ 1149048000000 , -1.1563414981293] , [ 1151640000000 , -0.87192471725994] , [ 1154318400000 , -0.84073995183442] , [ 1156996800000 , -0.88761892867370] , [ 1159588800000 , -0.81748513917485] , [ 1162270800000 , -1.2874081041274] , [ 1164862800000 , -1.9234702981339] , [ 1167541200000 , -1.8377768147648] , [ 1170219600000 , -2.7107654031830] , [ 1172638800000 , -2.6493268125418] , [ 1175313600000 , -3.0814553134551] , [ 1177905600000 , -3.8509837783574] , [ 1180584000000 , -5.2919167850718] , [ 1183176000000 , -5.2297750650773] , [ 1185854400000 , -3.9335668501451] , [ 1188532800000 , -2.3695525190114] , [ 1191124800000 , -2.3084243151854] , [ 1193803200000 , -3.0753680726738] , [ 1196398800000 , -2.2346609938962] , [ 1199077200000 , -3.0598810361615] , [ 1201755600000 , -1.8410154270386] , [ 1204261200000 , -1.6479442038620] , [ 1206936000000 , -1.9293858622780] , [ 1209528000000 , -3.0769590460943] , [ 1212206400000 , -4.2423933501421] , [ 1214798400000 , -2.6951491617768] , [ 1217476800000 , -2.8981825939957] , [ 1220155200000 , -2.9662727940324] , [ 1222747200000 , 0.21556750497498] , [ 1225425600000 , 2.6784995167088] , [ 1228021200000 , 4.1296711248958] , [ 1230699600000 , 3.7311068218734] , [ 1233378000000 , 4.7695330866954] , [ 1235797200000 , 5.1919133040990] , [ 1238472000000 , 4.1025856045660] , [ 1241064000000 , 2.8498939666225] , [ 1243742400000 , 2.8106017222851] , [ 1246334400000 , 2.8456526669963] , [ 1249012800000 , 0.65563070754298] , [ 1251691200000 , -0.30022343874633] , [ 1254283200000 , -1.1600358228964] , [ 1256961600000 , -0.26674408835052] , [ 1259557200000 , -1.4693389757812] , [ 1262235600000 , -2.7855421590594] , [ 1264914000000 , -1.2668244065703] , [ 1267333200000 , -2.5537804115548] , [ 1270008000000 , -4.9144552474502] , [ 1272600000000 , -6.0484408234831] , [ 1275278400000 , -3.3834349033750] , [ 1277870400000 , -0.46752826932523] , [ 1280548800000 , -1.8030186027963] , [ 1283227200000 , -0.99623230097881] , [ 1285819200000 , -3.3475370235594] , [ 1288497600000 , -3.8187026520342] , [ 1291093200000 , -4.2354146250353] , [ 1293771600000 , -5.6795404292885] , [ 1296450000000 , -6.2928665328172] , [ 1298869200000 , -6.8549277434419] , [ 1301544000000 , -6.9925308360918] , [ 1304136000000 , -8.3216548655839] , [ 1306814400000 , -7.7682867271435] , [ 1309406400000 , -6.9244213301058] , [ 1312084800000 , -5.7407624451404] , [ 1314763200000 , -2.1813149077927] , [ 1317355200000 , 2.9407596325999] , [ 1320033600000 , -1.1130607112134] , [ 1322629200000 , -2.0274822307752] , [ 1325307600000 , -1.8372559072154] , [ 1327986000000 , -4.0732815531148] , [ 1330491600000 , -6.4417038470291]]\n                },\n                {\n                    key: \"Series 3\",\n                    values: [ [ 1025409600000 , 0] , [ 1028088000000 , -6.3382185140371] , [ 1030766400000 , -5.9507873460847] , [ 1033358400000 , -11.569146943813] , [ 1036040400000 , -5.4767332317425] , [ 1038632400000 , 0.50794682203014] , [ 1041310800000 , -5.5310285460542] , [ 1043989200000 , -5.7838296963382] , [ 1046408400000 , -7.3249341615649] , [ 1049086800000 , -6.7078630712489] , [ 1051675200000 , 0.44227126150934] , [ 1054353600000 , 7.2481659343222] , [ 1056945600000 , 9.2512381306992] , [ 1059624000000 , 11.341210982529] , [ 1062302400000 , 14.734820409020] , [ 1064894400000 , 12.387148007542] , [ 1067576400000 , 18.436471461827] , [ 1070168400000 , 19.830742266977] , [ 1072846800000 , 22.643205829887] , [ 1075525200000 , 26.693972514363] , [ 1078030800000 , 29.489903107308] , [ 1080709200000 , 30.756096054034] , [ 1083297600000 , 27.992822746720] , [ 1085976000000 , 29.225852107431] , [ 1088568000000 , 30.156836480689] , [ 1091246400000 , 24.859678459498] , [ 1093924800000 , 24.151326522641] , [ 1096516800000 , 26.974088564049] , [ 1099195200000 , 30.587369307288] , [ 1101790800000 , 35.952410049136] , [ 1104469200000 , 42.723169856608] , [ 1107147600000 , 40.104326572110] , [ 1109566800000 , 42.034940590574] , [ 1112245200000 , 41.201940741519] , [ 1114833600000 , 35.959307673456] , [ 1117512000000 , 40.234785495828] , [ 1120104000000 , 43.347252675906] , [ 1122782400000 , 49.122142270314] , [ 1125460800000 , 46.336213226596] , [ 1128052800000 , 45.738022352292] , [ 1130734800000 , 40.782535587694] , [ 1133326800000 , 46.298919327736] , [ 1136005200000 , 46.525174496692] , [ 1138683600000 , 49.369518277658] , [ 1141102800000 , 51.359233230659] , [ 1143781200000 , 54.290790853085] , [ 1146369600000 , 56.370809889665] , [ 1149048000000 , 52.347251720842] , [ 1151640000000 , 52.651049262704] , [ 1154318400000 , 49.006082346714] , [ 1156996800000 , 53.833722685976] , [ 1159588800000 , 57.368751084016] , [ 1162270800000 , 62.620657436870] , [ 1164862800000 , 67.843814831233] , [ 1167541200000 , 70.696236558827] , [ 1170219600000 , 75.281054033390] , [ 1172638800000 , 75.494257592448] , [ 1175313600000 , 80.620943351778] , [ 1177905600000 , 87.289875534061] , [ 1180584000000 , 93.299043821956] , [ 1183176000000 , 91.015859689151] , [ 1185854400000 , 88.392797582470] , [ 1188532800000 , 94.699212813219] , [ 1191124800000 , 103.50183124741] , [ 1193803200000 , 111.30811970524] , [ 1196398800000 , 101.36138850420] , [ 1199077200000 , 98.665003256909] , [ 1201755600000 , 87.999132307989] , [ 1204261200000 , 85.315653328802] , [ 1206936000000 , 82.146119346213] , [ 1209528000000 , 90.093146599737] , [ 1212206400000 , 99.385987481068] , [ 1214798400000 , 84.763092203314] , [ 1217476800000 , 82.910191547323] , [ 1220155200000 , 90.191781675161] , [ 1222747200000 , 66.188819887335] , [ 1225425600000 , 47.259186154933] , [ 1228021200000 , 40.548648265024] , [ 1230699600000 , 42.458784966634] , [ 1233378000000 , 41.462207260082] , [ 1235797200000 , 35.224936113579] , [ 1238472000000 , 40.810117767284] , [ 1241064000000 , 55.041351655012] , [ 1243742400000 , 59.168485702020] , [ 1246334400000 , 60.474654847301] , [ 1249012800000 , 67.306616497709] , [ 1251691200000 , 70.539019993440] , [ 1254283200000 , 77.571962668603] , [ 1256961600000 , 72.108784451998] , [ 1259557200000 , 80.269048905849] , [ 1262235600000 , 84.754250235173] , [ 1264914000000 , 83.053938255703] , [ 1267333200000 , 88.067497980334] , [ 1270008000000 , 97.556993569060] , [ 1272600000000 , 96.744762710807] , [ 1275278400000 , 87.146301147104] , [ 1277870400000 , 76.113331725206] , [ 1280548800000 , 84.745960774176] , [ 1283227200000 , 80.883421033110] , [ 1285819200000 , 98.377963136001] , [ 1288497600000 , 104.16094587057] , [ 1291093200000 , 101.92699168281] , [ 1293771600000 , 109.16314556604] , [ 1296450000000 , 115.31506669000] , [ 1298869200000 , 126.55944572261] , [ 1301544000000 , 118.47392959295] , [ 1304136000000 , 121.44619467743] , [ 1306814400000 , 120.38970188330] , [ 1309406400000 , 114.99946573061] , [ 1312084800000 , 110.95959856356] , [ 1314763200000 , 86.186386929240] , [ 1317355200000 , 62.100425398325] , [ 1320033600000 , 78.680507428540] , [ 1322629200000 , 73.876351797642] , [ 1325307600000 , 70.866962301942] , [ 1327986000000 , 80.863709250982] , [ 1330491600000 , 86.946444823715]]\n                },\n                {\n                    key: \"Series 4\",\n                    values: [ [ 1025409600000 , -7.0674410638835] , [ 1028088000000 , -14.663359292964] , [ 1030766400000 , -14.104393060540] , [ 1033358400000 , -23.114477037218] , [ 1036040400000 , -16.774256687841] , [ 1038632400000 , -11.902028464000] , [ 1041310800000 , -16.883038668422] , [ 1043989200000 , -19.104223676831] , [ 1046408400000 , -20.420523282736] , [ 1049086800000 , -19.660555051587] , [ 1051675200000 , -13.106911231646] , [ 1054353600000 , -8.2448460302143] , [ 1056945600000 , -7.0313058730976] , [ 1059624000000 , -5.1485118700389] , [ 1062302400000 , -3.0011028761469] , [ 1064894400000 , -4.1367265281467] , [ 1067576400000 , 1.5425209565025] , [ 1070168400000 , 2.7673533607299] , [ 1072846800000 , 7.7077114755360] , [ 1075525200000 , 9.7565015112434] , [ 1078030800000 , 11.396888609473] , [ 1080709200000 , 10.013964745578] , [ 1083297600000 , 8.0558890950562] , [ 1085976000000 , 9.6081966657458] , [ 1088568000000 , 11.918590426432] , [ 1091246400000 , 7.9945345523982] , [ 1093924800000 , 8.3201276776796] , [ 1096516800000 , 9.8283954846342] , [ 1099195200000 , 11.527125859650] , [ 1101790800000 , 16.413657596527] , [ 1104469200000 , 20.393798297928] , [ 1107147600000 , 17.456308413907] , [ 1109566800000 , 20.087778400999] , [ 1112245200000 , 17.988336990817] , [ 1114833600000 , 15.378490151331] , [ 1117512000000 , 19.474322935730] , [ 1120104000000 , 20.013851070354] , [ 1122782400000 , 24.749943726975] , [ 1125460800000 , 23.558710274826] , [ 1128052800000 , 24.558915040889] , [ 1130734800000 , 22.355860488034] , [ 1133326800000 , 27.138026265756] , [ 1136005200000 , 27.202220808591] , [ 1138683600000 , 31.219437344964] , [ 1141102800000 , 31.392355525125] , [ 1143781200000 , 33.373099232542] , [ 1146369600000 , 35.095277582309] , [ 1149048000000 , 30.923356507615] , [ 1151640000000 , 31.083717332561] , [ 1154318400000 , 31.290690671561] , [ 1156996800000 , 34.247769216679] , [ 1159588800000 , 37.411073177620] , [ 1162270800000 , 42.079177096411] , [ 1164862800000 , 44.978191659648] , [ 1167541200000 , 46.713271025310] , [ 1170219600000 , 49.203892437699] , [ 1172638800000 , 46.684723471826] , [ 1175313600000 , 48.385458973500] , [ 1177905600000 , 54.660197840305] , [ 1180584000000 , 60.311838415602] , [ 1183176000000 , 57.583282204682] , [ 1185854400000 , 52.425398898751] , [ 1188532800000 , 54.663538086985] , [ 1191124800000 , 60.181844325224] , [ 1193803200000 , 62.877219773621] , [ 1196398800000 , 55.760611512951] , [ 1199077200000 , 54.735280367784] , [ 1201755600000 , 45.495912959474] , [ 1204261200000 , 40.934919015876] , [ 1206936000000 , 40.303777633187] , [ 1209528000000 , 47.403740368773] , [ 1212206400000 , 49.951960898839] , [ 1214798400000 , 37.534590035098] , [ 1217476800000 , 36.405758293321] , [ 1220155200000 , 38.545373001858] , [ 1222747200000 , 26.106358664455] , [ 1225425600000 , 4.2658006768744] , [ 1228021200000 , -3.5517839867557] , [ 1230699600000 , -2.0878920761513] , [ 1233378000000 , -10.408879093829] , [ 1235797200000 , -19.924242196038] , [ 1238472000000 , -12.906491912782] , [ 1241064000000 , -3.9774866468346] , [ 1243742400000 , 1.0319171601402] , [ 1246334400000 , 1.3109350357718] , [ 1249012800000 , 9.1668309061935] , [ 1251691200000 , 13.121178985954] , [ 1254283200000 , 17.578680237511] , [ 1256961600000 , 14.971294355085] , [ 1259557200000 , 21.551327027338] , [ 1262235600000 , 24.592328423819] , [ 1264914000000 , 20.158087829555] , [ 1267333200000 , 24.135661929185] , [ 1270008000000 , 31.815205405903] , [ 1272600000000 , 34.389524768466] , [ 1275278400000 , 23.785555857522] , [ 1277870400000 , 17.082756649072] , [ 1280548800000 , 25.248007727100] , [ 1283227200000 , 19.415179069165] , [ 1285819200000 , 30.413636349327] , [ 1288497600000 , 35.357952964550] , [ 1291093200000 , 35.886413535859] , [ 1293771600000 , 45.003601951959] , [ 1296450000000 , 48.274893564020] , [ 1298869200000 , 53.562864914648] , [ 1301544000000 , 54.108274337412] , [ 1304136000000 , 58.618190111927] , [ 1306814400000 , 56.806793965598] , [ 1309406400000 , 54.135477252994] , [ 1312084800000 , 50.735258942442] , [ 1314763200000 , 42.208170945813] , [ 1317355200000 , 31.617916826724] , [ 1320033600000 , 46.492005006737] , [ 1322629200000 , 46.203116922145] , [ 1325307600000 , 47.541427643137] , [ 1327986000000 , 54.518998440993] , [ 1330491600000 , 61.099720234693]]\n                }\n  ]\n                \n  /*\n  .map(function(line) {\n    line.values = line.values.map(function(d) { return {x: d[0], y: d[1]/100  }});\n    return line;\n  });\n  */\n}\n\n\n</script>\n"
  },
  {
    "path": "test/lineChartTest.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type=\"text/css\">\n<script src=\"../bower_components/d3/d3.js\" charset=\"utf-8\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n<style>\n#chart13, #chart14 {\n  overflow: scroll;\n  width: 500px;\n  height: 300px;\n}\n\n#chart13 svg, #chart14 svg {\n  width: 700px;\n  height: 400px;\n}\n</style>\n</head>\n<body>\n  <h3>Line chart test cases - feel free to add more tests</h3>\n  <div style='position:relative;'>\n      <div class='navigation'>\n          Tests:\n          <a href=\"lineChartTest.html\">Line Chart</a>\n          <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n          <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n          <a href=\"ScatterChartTest.html\">Scatter</a>\n          <a href=\"pieChartTest.html\">Pie chart</a>\n          <a href=\"multiBarCharttest.html\">Multi Bar Chart</a>\n          <a href=\"realTimeChartTest.html\">Real time test</a>\n          <a href=\"polylinearTest.html\">Polylinear test</a>\n      </div>\n      <div class='chart full' id='chart1'>\n        Example of chart with many series', and new interactive guideline plus tooltip. A chunk of data was purposely removed\n        to show how the chart handles it.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n      <div class='chart half with-transitions' id='chart2'>\n        Chart with old tooltip style (with-transitions).\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n      <div class='chart half' id='chart3'>\n        Chart with three data points.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n      <div class='chart third' id='chart4'>\n        Chart where two series have different number of points.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart5'>\n        Chart with one point.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart6'>\n        Chart with 1000 points.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart third' id='chart7'>\n        Chart with no data.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart8'>\n        All points random. No order.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart9'>\n        Points do not increase linearly.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart third' id='chart10'>\n        Chart with 15 series'\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart11'>\n        Data points go backwards\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n       <div class='chart third' id='chart12'>\n        Duplicate X coordinate points.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart third' id='chart16'>\n        Duplicate Y coordinate points.\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart third' id='chart13'>\n        Chart in a overflow div with scrolls (new tooltips)\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart third' id='chart14'>\n        Chart in a overflow div with scrolls (old tooltips)\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div style='clear:both;'></div>\n      <div class='chart third' id='chart15'>\n        What if there are null, Infinity and NaN values in points?\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n      <div class='chart third' id='chart17'>\n        Chart with very small, 1e-10, points (old tooltips)\n        <button>Select chart</button>\n        <svg></svg>\n      </div>\n\n      <div class='chart half' id='chart18'>\n        Chart with missing data (discontinuous lines). Check that all highlighted points\n        have the same x, matching the guideline. Check that \"N/A\" appears in tooltip for\n        points with undefined y.\n        <svg></svg>\n      </div>\n\n    </div>\n\n<script src=\"testScript.js\"></script>\n<script>\n\nd3.select(\"body\").on(\"keydown\",function() {\n  if (d3.event.ctrlKey && d3.event.which === 75) {\n     alert(\"keydowned\");\n  }\n});\n//------------ CHART 1\ndefaultChartConfig(\"chart1\", dummyStocks(),true, true, {forceY:false});\n\n//-------------- CHART 2  --- Chart without the interactive guideline.\nnv.addGraph(function() {\n  var chart;\n  chart = nv.models.lineChart().useInteractiveGuideline(false);\n\n  chart\n      .x(function(d,i) { return d.x });\n\n\n  chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n      .tickFormat(d3.format(',.1f'));\n\n  chart.yAxis\n      .axisLabel('Voltage (v)')\n      .tickFormat(d3.format(',.4f'));\n\n  chart.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90});\n\n  d3.select('#chart2 svg')\n      //.datum([]) //for testing noData\n      .datum(dummyStocks(50))\n      .transition().duration(500)\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\ndefaultChartConfig(\"chart3\", smallDataSet(3));\ndefaultChartConfig(\"chart4\", badDataSet());\ndefaultChartConfig(\"chart5\", smallDataSet(1));\ndefaultChartConfig(\"chart6\", normalDist());\n\ndefaultChartConfig(\"chart7\", smallDataSet(0));\ndefaultChartConfig(\"chart8\", allRandom(),false);\ndefaultChartConfig(\"chart9\", fibonacci());\n\ndefaultChartConfig(\"chart10\", lotsofSeries());\ndefaultChartConfig(\"chart11\", backwards(),false);\ndefaultChartConfig(\"chart12\", duplicateX(),false);\ndefaultChartConfig(\"chart13\",hyperbole(), true, false, {width: 700, height: 400});\ndefaultChartConfig(\"chart14\",hyperbole(), false, false, {width: 700, height: 400});\ndefaultChartConfig(\"chart15\", withNaNs());\ndefaultChartConfig(\"chart16\", duplicateY(), false);\ndefaultChartConfig(\"chart17\", tinyPoints(), false);\ndefaultChartConfig(\"chart18\", missingData(), true);\n\nfunction defaultChartConfig(containerid, data, guideline, useDates, auxOptions) {\n  if (auxOptions === undefined) auxOptions = {};\n  if (guideline === undefined) guideline = true;\n  nv.addGraph(function() {\n    var chart;\n    chart = nv.models.lineChart().useInteractiveGuideline(guideline);\n\n    chart\n        .x(function(d,i) {\n          return d.x;\n        });\n\n    if (auxOptions.width)\n      chart.width(auxOptions.width);\n\n    if (auxOptions.height)\n      chart.height(auxOptions.height);\n\n    if (auxOptions.forceY)\n      chart.forceY([0]);\n\n    var formatter;\n    if (useDates !== undefined) {\n        formatter = function(d,i) {\n                var now = (new Date()).getTime() - 86400 * 1000 * 365;\n                now = new Date(now + d * 86400 * 1000);\n                return d3.time.format('%b %d %Y')(now );\n        }\n    }\n    else {\n        formatter = d3.format(\",.1f\");\n    }\n    chart.margin({right: 40});\n    chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        .tickFormat(\n            formatter\n          );\n\n    chart.yAxis\n        .axisLabel('Voltage (v)')\n        .tickFormat(d3.format(',.2f'));\n\n\n    d3.select('#' + containerid + ' svg')\n        .datum(data)\n      .transition().duration(500)\n        .call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n    return chart;\n  });\n}\n\nfunction sinAndCos() {\n  var sin = [],\n      cos = [],\n      rand = [],\n      rand2 = []\n      ;\n\n  var now = (new Date()).getTime();\n  for (var i = 0; i < 100; i++) {\n    sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works\n    cos.push({x: i, y: .5 * Math.cos(i/10)});\n    rand.push({x:i, y: Math.random() / 10});\n    rand2.push({x: i, y: Math.cos(i/10) + Math.random() / 10 })\n  }\n\n  return [\n    {\n      area: true,\n      values: sin,\n      key: \"Sine Wave\",\n      color: \"#ff7f0e\"\n    },\n    {\n      values: cos,\n      key: \"Cosine Wave\",\n      color: \"#2ca02c\"\n    },\n    {\n      values: rand,\n      key: \"Random Points\",\n      color: \"#2222ff\"\n    }\n    ,\n    {\n      values: rand2,\n      key: \"Random Cosine\",\n      color: \"#667711\"\n    }\n  ];\n}\n\nfunction hyperbole() {\n  var series1 = [], series2 = [], series3 = [];\n  for(var i = 1; i < 100; i++) {\n      series1.push({x: i, y: 1 / i});\n      series2.push({x: i, y: 5 / i});\n      series3.push({x: i, y: -8 / i});\n  }\n\n  return [\n    {values: series1, key: \"Series 1\"},\n    {values: series2, key: \"Series 2\"},\n    {values: series3, key: \"Series 3\"}\n  ];\n}\n\nfunction smallDataSet(n) {\n  var series = [];\n  for(var i = 0; i < n; i++) {\n      series.push({x: i, y: i * 0.3 + 2})\n  }\n  return [\n    {values: series, key: \"Line 1\"}\n  ];\n}\n\nfunction badDataSet() {\n  var series1 = [], series2 = [];\n  for(var i =0; i < 30; i++) {\n    series1.push({x:i, y: i*0.3 + 12});\n  }\n  for(i = 0; i < 30; i += 5) {\n    series2.push({x:i, y: i*0.7 + 8});\n  }\n  return [\n      {values: series1, key:\"Series 1\"},\n      {values: series2, key:\"Series 2\"}\n  ];\n}\n\nfunction normalDist() {\n  var series1 = [], series2 = [];\n  for(var i = -500; i < 500; i += 1) {\n     var x = i / 100;\n     var y = 0.3989 * Math.pow(2.71, -0.5*x*x);\n     series1.push({x:i, y:y});\n     series2.push({x:i, y:y*2});\n  }\n  return [\n  {values: series1, key:\"Normal 1\", area:true},\n  {values: series2, key:\"Normal 2\"}];\n}\n\n\nfunction allRandom() {\n  var series = [];\n  for(var i = 0; i < 20; i++) {\n    series.push({x: Math.floor(Math.random()*20), y: Math.floor(Math.random()*20) });\n  }\n  return [{values: series,area:true, key: \"Total Chaos\"}];\n}\n\nfunction fibonacci() {\n  var series = [\n      {x:1, y:1},\n      {x:2, y:2.5},\n      {x:3, y:4},\n      {x:5, y:6.7},\n      {x:8, y:10.1},\n      {x:13, y:20.1},\n      {x:21, y:35.1},\n      {x:34, y:60.0},\n      {x:55, y:70.9},\n      {x:89, y:100.3}\n  ];\n\n  return [{values: series,area:true,color: \"#22fb88\", key: \"Fibonacci\"}];\n}\n\nfunction lotsofSeries() {\n  var rval = [];\n  for(var n = 0; n < 15; n++) {\n      var values = [];\n      var slope = Math.random() * 5;\n      for(var i =0; i < 30; i++) {\n          values.push(\n              {x: i,\n              y: i * slope + Math.random()*5}\n            );\n      }\n      var isArea = (Math.random() > 0.5);\n      rval.push({key: \"Series \" + n, area: isArea, values: values});\n  }\n  return rval;\n}\n\nfunction backwards() {\n  var series = [];\n  for(var i = 30; i >= 1; i--) {\n      series.push({x: i, y: Math.sqrt(i) });\n  }\n  return [{values: series, key: \"Backwards series\", area:true}];\n}\n\nfunction duplicateX() {\n  return [\n    {key: \"Duplicate X\",\n      area: true,\n      values: [\n        {x: 4, y: 10},\n        {x: 4, y: 11},\n        {x: 4, y: 12},\n        {x: 4, y: 13}\n      ]\n    }\n  ];\n}\n\nfunction duplicateY() {\n  return [\n    {key: \"Duplicate Y\",\n     values: [\n        {x: 0, y: 10}, {x:1, y:10},{x:2, y:10},{x:3, y:10}\n     ]\n    }\n  ];\n}\n\nfunction withNaNs() {\n  return [\n      {key: \"NaN Points\",\n        values: [\n            {x: 1, y: NaN},\n            {x: 2, y: undefined},\n            {x: 3, y: false},\n            {x: 4, y: null},\n            {x: 5, y: \"Hello\"},\n            {x: NaN, y: NaN},\n            {x: null, y: null},\n            {x: undefined, y: undefined},\n            {x: \"Hello\", y: \"World\"},\n            {x: Infinity, y: Infinity}\n        ]\n      }\n  ]\n}\n\nfunction tinyPoints() {\n  var rval = {key: \"Tiny points\", values: []};\n  for(var i =1; i < 20; i++) {\n    rval.values.push({\n       x: i,\n       y: Math.random() * 1e-10\n    });\n  }\n  return [rval];\n}\n\nfunction missingData() {\n  var sin = [],\n      sin2 = [],\n      cos = [],\n      rand = [],\n      rand2 = []\n      ;\n\n\n  for (var i = 0; i < 100; i++) {\n\n      sin.push(i % 17 === 0 ? {x: i, y: null} : {x: i, y: Math.sin(i/10) });\n      sin2.push(i % 19 === 0 ? {x: i, y: null} : {x: i, y: Math.sin(i/5) * 0.4 - 0.25});\n      cos.push(i % 7 === 0 ? {x: i, y:null} : {x: i, y:.5 * Math.cos(i/10)});\n      rand.push(i % 11 === 0 ? {x: i, y: null} : {x: i , y: Math.random() / 10});\n      rand2.push( i % 13 === 0 ? {x: i, y: null} : {x: i, y: Math.cos(i/10) + Math.random() / 10 });\n  }\n\n  return [\n      {\n          area: true,\n          values: sin,\n          key: \"Sine Wave\",\n          color: \"#ff7f0e\",\n          strokeWidth: 4,\n          classed: 'dashed'\n      },\n      {\n          values: cos,\n          key: \"Cosine Wave\",\n          color: \"#2ca02c\"\n      },\n      {\n          values: rand,\n          key: \"Random Points\",\n          color: \"#2222ff\"\n      },\n      {\n          values: rand2,\n          key: \"Random Cosine\",\n          color: \"#667711\",\n          strokeWidth: 3.5\n      },\n      {\n          area: true,\n          values: sin2,\n          key: \"Fill opacity\",\n          color: \"#EF9CFB\",\n          fillOpacity: .1\n      }\n  ];\n}\n\nfunction dummyStocks(numPoints) {\n  numPoints = numPoints || 200;\n  function volatileChart(key,startPrice, volatility, isArea) {\n     var rval = {key: key, values: []};\n     if (isArea) rval.area = true;\n     for(var i = 1; i < numPoints; i++) {\n\n        rval.values.push({x: i, y: (i > 110 && i < 130) ? null : startPrice});\n        var rnd = Math.random();\n        var changePct = 2 * volatility * rnd;\n        if ( changePct > volatility) {\n           changePct -= (2*volatility);\n        }\n\n        startPrice = startPrice + startPrice * changePct;\n\n     }\n     return rval;\n  }\n\n  var stocks = [];\n  stocks.push(volatileChart(\"APPL\",5.00, 0.02));\n  stocks.push(volatileChart(\"GOOG\", 6.01,0.024));\n  stocks.push(volatileChart(\"MSFT\", 2.01, 0.012));\n  stocks.push(volatileChart(\"IBM US\", 2.5, 0.08, true));\n  return stocks;\n}\n\n</script>\n\n</body></html>\n"
  },
  {
    "path": "test/linePlusBarChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n#chart1 svg {\n  height: 500px;\n  margin: 10px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n</style>\n<body>\n\n  <div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg> </svg>\n  </div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/line.js\"></script>\n<script src=\"../src/models/historicalBar.js\"></script>\n<script src=\"../src/models/linePlusBarChart.js\"></script>\n<script>\n\n\nvar testdata = [\n  {\n    \"key\" : \"Quantity\" ,\n    \"bar\": true,\n    \"values\" : [ [ 1136005200000 , 1271000.0] , [ 1138683600000 , 1271000.0] , [ 1141102800000 , 1271000.0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 3899486.0] , [ 1162270800000 , 3899486.0] , [ 1164862800000 , 3899486.0] , [ 1167541200000 , 3564700.0] , [ 1170219600000 , 3564700.0] , [ 1172638800000 , 3564700.0] , [ 1175313600000 , 2648493.0] , [ 1177905600000 , 2648493.0] , [ 1180584000000 , 2648493.0] , [ 1183176000000 , 2522993.0] , [ 1185854400000 , 2522993.0] , [ 1188532800000 , 2522993.0] , [ 1191124800000 , 2906501.0] , [ 1193803200000 , 2906501.0] , [ 1196398800000 , 2906501.0] , [ 1199077200000 , 2206761.0] , [ 1201755600000 , 2206761.0] , [ 1204261200000 , 2206761.0] , [ 1206936000000 , 2287726.0] , [ 1209528000000 , 2287726.0] , [ 1212206400000 , 2287726.0] , [ 1214798400000 , 2732646.0] , [ 1217476800000 , 2732646.0] , [ 1220155200000 , 2732646.0] , [ 1222747200000 , 2599196.0] , [ 1225425600000 , 2599196.0] , [ 1228021200000 , 2599196.0] , [ 1230699600000 , 1924387.0] , [ 1233378000000 , 1924387.0] , [ 1235797200000 , 1924387.0] , [ 1238472000000 , 1756311.0] , [ 1241064000000 , 1756311.0] , [ 1243742400000 , 1756311.0] , [ 1246334400000 , 1743470.0] , [ 1249012800000 , 1743470.0] , [ 1251691200000 , 1743470.0] , [ 1254283200000 , 1519010.0] , [ 1256961600000 , 1519010.0] , [ 1259557200000 , 1519010.0] , [ 1262235600000 , 1591444.0] , [ 1264914000000 , 1591444.0] , [ 1267333200000 , 1591444.0] , [ 1270008000000 , 1543784.0] , [ 1272600000000 , 1543784.0] , [ 1275278400000 , 1543784.0] , [ 1277870400000 , 1309915.0] , [ 1280548800000 , 1309915.0] , [ 1283227200000 , 1309915.0] , [ 1285819200000 , 1331875.0] , [ 1288497600000 , 1331875.0] , [ 1291093200000 , 1331875.0] , [ 1293771600000 , 1331875.0] , [ 1296450000000 , 1154695.0] , [ 1298869200000 , 1154695.0] , [ 1301544000000 , 1194025.0] , [ 1304136000000 , 1194025.0] , [ 1306814400000 , 1194025.0] , [ 1309406400000 , 1194025.0] , [ 1312084800000 , 1194025.0] , [ 1314763200000 , 1244525.0] , [ 1317355200000 , 475000.0] , [ 1320033600000 , 475000.0] , [ 1322629200000 , 475000.0] , [ 1325307600000 , 690033.0] , [ 1327986000000 , 690033.0] , [ 1330491600000 , 690033.0] , [ 1333166400000 , 514733.0] , [ 1335758400000 , 514733.0]]\n  },\n  {\n    \"key\" : \"Price\" ,\n    \"values\" : [ [ 1136005200000 , 71.89] , [ 1138683600000 , 75.51] , [ 1141102800000 , 68.49] , [ 1143781200000 , 62.72] , [ 1146369600000 , 70.39] , [ 1149048000000 , 59.77] , [ 1151640000000 , 57.27] , [ 1154318400000 , 67.96] , [ 1156996800000 , 67.85] , [ 1159588800000 , 76.98] , [ 1162270800000 , 81.08] , [ 1164862800000 , 91.66] , [ 1167541200000 , 84.84] , [ 1170219600000 , 85.73] , [ 1172638800000 , 84.61] , [ 1175313600000 , 92.91] , [ 1177905600000 , 99.8] , [ 1180584000000 , 121.191] , [ 1183176000000 , 122.04] , [ 1185854400000 , 131.76] , [ 1188532800000 , 138.48] , [ 1191124800000 , 153.47] , [ 1193803200000 , 189.95] , [ 1196398800000 , 182.22] , [ 1199077200000 , 198.08] , [ 1201755600000 , 135.36] , [ 1204261200000 , 125.02] , [ 1206936000000 , 143.5] , [ 1209528000000 , 173.95] , [ 1212206400000 , 188.75] , [ 1214798400000 , 167.44] , [ 1217476800000 , 158.95] , [ 1220155200000 , 169.53] , [ 1222747200000 , 113.66] , [ 1225425600000 , 107.59] , [ 1228021200000 , 92.67] , [ 1230699600000 , 85.35] , [ 1233378000000 , 90.13] , [ 1235797200000 , 89.31] , [ 1238472000000 , 105.12] , [ 1241064000000 , 125.83] , [ 1243742400000 , 135.81] , [ 1246334400000 , 142.43] , [ 1249012800000 , 163.39] , [ 1251691200000 , 168.21] , [ 1254283200000 , 185.35] , [ 1256961600000 , 188.5] , [ 1259557200000 , 199.91] , [ 1262235600000 , 210.732] , [ 1264914000000 , 192.063] , [ 1267333200000 , 204.62] , [ 1270008000000 , 235.0] , [ 1272600000000 , 261.09] , [ 1275278400000 , 256.88] , [ 1277870400000 , 251.53] , [ 1280548800000 , 257.25] , [ 1283227200000 , 243.1] , [ 1285819200000 , 283.75] , [ 1288497600000 , 300.98] , [ 1291093200000 , 311.15] , [ 1293771600000 , 322.56] , [ 1296450000000 , 339.32] , [ 1298869200000 , 353.21] , [ 1301544000000 , 348.5075] , [ 1304136000000 , 350.13] , [ 1306814400000 , 347.83] , [ 1309406400000 , 335.67] , [ 1312084800000 , 390.48] , [ 1314763200000 , 384.83] , [ 1317355200000 , 381.32] , [ 1320033600000 , 404.78] , [ 1322629200000 , 382.2] , [ 1325307600000 , 405.0] , [ 1327986000000 , 456.48] , [ 1330491600000 , 542.44] , [ 1333166400000 , 599.55] , [ 1335758400000 , 583.98] ]\n  }\n].map(function(series) {\n  series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });\n  return series;\n});\n\n/*\n//For testing single data point\nvar testdata = [\n  {\n    \"key\" : \"Quantity\" ,\n    \"bar\": true,\n    \"values\" : [ [ 1136005200000 , 1271000.0] ]\n  } ,\n  {\n    \"key\" : \"Price\" ,\n    \"values\" : [ [ 1136005200000 , 71.89] ]\n  }\n].map(function(series) {\n  series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });\n  return series;\n});\n*/\n\nvar chart;\n\nnv.addGraph(function() {\n    chart = nv.models.linePlusBarChart()\n        .margin({top: 30, right: 60, bottom: 50, left: 70})\n        .x(function(d,i) { return i })\n        .color(d3.scale.category10().range());\n\n    chart.xAxis.tickFormat(function(d) {\n      var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;\n      return dx ? d3.time.format('%x')(new Date(dx)) : '';\n      })\n      .showMaxMin(false);\n\n    chart.y1Axis\n        .tickFormat(d3.format(',f'));\n\n    chart.y2Axis\n        .tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });\n\n    chart.bars.forceY([0]).padData(false);\n    //chart.lines.forceY([0]);\n\n    d3.select('#chart1 svg')\n        .datum(testdata)\n      .transition().duration(500).call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n    return chart;\n});\n\n</script>\n"
  },
  {
    "path": "test/linePlusBarWithFocusChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n#chart1 svg {\n  height: 500px;\n  margin: 10px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n</style>\n<body>\n\n  <div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg> </svg>\n  </div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/line.js\"></script>\n<script src=\"../src/models/historicalBar.js\"></script>\n<script src=\"../src/models/linePlusBarWithFocusChart.js\"></script>\n<script>\n\n\nvar testdata = [\n  {\n    \"key\" : \"Quantity\" ,\n    \"bar\": true,\n    \"values\" : [ [ 1136005200000 , 1271000.0] , [ 1138683600000 , 1271000.0] , [ 1141102800000 , 1271000.0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 3899486.0] , [ 1162270800000 , 3899486.0] , [ 1164862800000 , 3899486.0] , [ 1167541200000 , 3564700.0] , [ 1170219600000 , 3564700.0] , [ 1172638800000 , 3564700.0] , [ 1175313600000 , 2648493.0] , [ 1177905600000 , 2648493.0] , [ 1180584000000 , 2648493.0] , [ 1183176000000 , 2522993.0] , [ 1185854400000 , 2522993.0] , [ 1188532800000 , 2522993.0] , [ 1191124800000 , 2906501.0] , [ 1193803200000 , 2906501.0] , [ 1196398800000 , 2906501.0] , [ 1199077200000 , 2206761.0] , [ 1201755600000 , 2206761.0] , [ 1204261200000 , 2206761.0] , [ 1206936000000 , 2287726.0] , [ 1209528000000 , 2287726.0] , [ 1212206400000 , 2287726.0] , [ 1214798400000 , 2732646.0] , [ 1217476800000 , 2732646.0] , [ 1220155200000 , 2732646.0] , [ 1222747200000 , 2599196.0] , [ 1225425600000 , 2599196.0] , [ 1228021200000 , 2599196.0] , [ 1230699600000 , 1924387.0] , [ 1233378000000 , 1924387.0] , [ 1235797200000 , 1924387.0] , [ 1238472000000 , 1756311.0] , [ 1241064000000 , 1756311.0] , [ 1243742400000 , 1756311.0] , [ 1246334400000 , 1743470.0] , [ 1249012800000 , 1743470.0] , [ 1251691200000 , 1743470.0] , [ 1254283200000 , 1519010.0] , [ 1256961600000 , 1519010.0] , [ 1259557200000 , 1519010.0] , [ 1262235600000 , 1591444.0] , [ 1264914000000 , 1591444.0] , [ 1267333200000 , 1591444.0] , [ 1270008000000 , 1543784.0] , [ 1272600000000 , 1543784.0] , [ 1275278400000 , 1543784.0] , [ 1277870400000 , 1309915.0] , [ 1280548800000 , 1309915.0] , [ 1283227200000 , 1309915.0] , [ 1285819200000 , 1331875.0] , [ 1288497600000 , 1331875.0] , [ 1291093200000 , 1331875.0] , [ 1293771600000 , 1331875.0] , [ 1296450000000 , 1154695.0] , [ 1298869200000 , 1154695.0] , [ 1301544000000 , 1194025.0] , [ 1304136000000 , 1194025.0] , [ 1306814400000 , 1194025.0] , [ 1309406400000 , 1194025.0] , [ 1312084800000 , 1194025.0] , [ 1314763200000 , 1244525.0] , [ 1317355200000 , 475000.0] , [ 1320033600000 , 475000.0] , [ 1322629200000 , 475000.0] , [ 1325307600000 , 690033.0] , [ 1327986000000 , 690033.0] , [ 1330491600000 , 690033.0] , [ 1333166400000 , 514733.0] , [ 1335758400000 , 514733.0]]\n  },\n  {\n    \"key\" : \"Price\" ,\n    \"values\" : [ [ 1136005200000 , 71.89] , [ 1138683600000 , 75.51] , [ 1141102800000 , 68.49] , [ 1143781200000 , 62.72] , [ 1146369600000 , 70.39] , [ 1149048000000 , 59.77] , [ 1151640000000 , 57.27] , [ 1154318400000 , 67.96] , [ 1156996800000 , 67.85] , [ 1159588800000 , 76.98] , [ 1162270800000 , 81.08] , [ 1164862800000 , 91.66] , [ 1167541200000 , 84.84] , [ 1170219600000 , 85.73] , [ 1172638800000 , 84.61] , [ 1175313600000 , 92.91] , [ 1177905600000 , 99.8] , [ 1180584000000 , 121.191] , [ 1183176000000 , 122.04] , [ 1185854400000 , 131.76] , [ 1188532800000 , 138.48] , [ 1191124800000 , 153.47] , [ 1193803200000 , 189.95] , [ 1196398800000 , 182.22] , [ 1199077200000 , 198.08] , [ 1201755600000 , 135.36] , [ 1204261200000 , 125.02] , [ 1206936000000 , 143.5] , [ 1209528000000 , 173.95] , [ 1212206400000 , 188.75] , [ 1214798400000 , 167.44] , [ 1217476800000 , 158.95] , [ 1220155200000 , 169.53] , [ 1222747200000 , 113.66] , [ 1225425600000 , 107.59] , [ 1228021200000 , 92.67] , [ 1230699600000 , 85.35] , [ 1233378000000 , 90.13] , [ 1235797200000 , 89.31] , [ 1238472000000 , 105.12] , [ 1241064000000 , 125.83] , [ 1243742400000 , 135.81] , [ 1246334400000 , 142.43] , [ 1249012800000 , 163.39] , [ 1251691200000 , 168.21] , [ 1254283200000 , 185.35] , [ 1256961600000 , 188.5] , [ 1259557200000 , 199.91] , [ 1262235600000 , 210.732] , [ 1264914000000 , 192.063] , [ 1267333200000 , 204.62] , [ 1270008000000 , 235.0] , [ 1272600000000 , 261.09] , [ 1275278400000 , 256.88] , [ 1277870400000 , 251.53] , [ 1280548800000 , 257.25] , [ 1283227200000 , 243.1] , [ 1285819200000 , 283.75] , [ 1288497600000 , 300.98] , [ 1291093200000 , 311.15] , [ 1293771600000 , 322.56] , [ 1296450000000 , 339.32] , [ 1298869200000 , 353.21] , [ 1301544000000 , 348.5075] , [ 1304136000000 , 350.13] , [ 1306814400000 , 347.83] , [ 1309406400000 , 335.67] , [ 1312084800000 , 390.48] , [ 1314763200000 , 384.83] , [ 1317355200000 , 381.32] , [ 1320033600000 , 404.78] , [ 1322629200000 , 382.2] , [ 1325307600000 , 405.0] , [ 1327986000000 , 456.48] , [ 1330491600000 , 542.44] , [ 1333166400000 , 599.55] , [ 1335758400000 , 583.98]]\n  }\n].map(function(series) {\n  series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });\n  return series;\n});\n\n\n/*\n//For testing single data point\nvar testdata = [\n  {\n    \"key\" : \"Quantity\" ,\n    \"bar\": true,\n    \"values\" : [ [ 1136005200000 , 1271000.0] ]\n  } ,\n  {\n    \"key\" : \"Price\" ,\n    \"values\" : [ [ 1136005200000 , 71.89] ]\n  }\n].map(function(series) {\n  series.values = series.values.map(function(d) { return {x: d[0], y: d[1] } });\n  return series;\n});\n*/\n\n\n\nnv.addGraph(function() {\n    var chart = nv.models.linePlusBarWithFocusChart()\n        .margin({top: 30, right: 60, bottom: 50, left: 70})\n        .x(function(d,i) { return i })\n        .color(d3.scale.category10().range());\n\n    chart.xAxis.tickFormat(function(d) {\n\n      var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;\n      if (dx > 0) {\n          return d3.time.format('%x')(new Date(dx))\n      }\n      return null;\n    });\n\n    chart.x2Axis.tickFormat(function(d) {\n      var dx = testdata[0].values[d] && testdata[0].values[d].x || 0;\n      return d3.time.format('%x')(new Date(dx))\n    });\n    \n    chart.y1Axis\n        .tickFormat(d3.format(',f'));\n\n    chart.y3Axis\n        .tickFormat(d3.format(',f'));\n        \n    chart.y2Axis\n        .tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });\n\n    chart.y4Axis\n        .tickFormat(function(d) { return '$' + d3.format(',.2f')(d) });\n        \n    chart.bars.forceY([0]);\n    chart.bars2.forceY([0]);\n    //chart.lines.forceY([0]);\n    nv.log(testdata);\n    d3.select('#chart1 svg')\n        .datum(testdata)\n        .call(chart);\n\n    // nv.utils.windowResize(chart.update);\n    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n    return chart;\n});\n\n</script>\n"
  },
  {
    "path": "test/lineWithFisheyeChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\nsvg {\n  display: block;\n}\n\n#chart1 svg {\n  height: 500px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  margin: 50px;\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n</style>\n<body>\n\n  <div id=\"chart1\" class='with-3d-shadow with-transitions'>\n    <svg style=\"height: 500px;\"></svg>\n  </div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../lib/fisheye.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/lineWithFisheye.js\"></script>\n<script src=\"../src/models/lineWithFisheyeChart.js\"></script>\n<script>\n\n\n// Wrapping in nv.addGraph allows for '0 timeout render', stors rendered charts in nv.graphs, and may do more in the future... it's NOT required\nnv.addGraph(function() {  \n  var chart = nv.models.lineChart();\n\n  chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n      .tickFormat(d3.format(',r'));\n\n  chart.yAxis\n      .axisLabel('Voltage (v)')\n      .tickFormat(d3.format(',.2f'));\n\n  d3.select('#chart1 svg')\n      .datum(sinAndCos())\n    .transition().duration(500)\n      .call(chart);\n\n  //TODO: Figure out a good way to do this automatically\n  nv.utils.windowResize(chart.update);\n  //nv.utils.windowResize(function() { d3.select('#chart1 svg').call(chart) });\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\n\n\nfunction sinAndCos() {\n  var sin = [],\n      cos = [];\n\n  for (var i = 0; i < 200; i++) {\n    sin.push({x: i, y: Math.sin(i/2)});\n    cos.push({x: i, y: .5 * Math.cos(i)});\n  }\n\n  return [\n    {\n      values: sin,\n      key: \"Sine Wave\",\n      color: \"#ff7f0e\"\n    },\n    {\n      values: cos,\n      key: \"Cosine Wave\",\n      color: \"#2ca02c\"\n    }\n  ];\n}\n\n\n</script>\n"
  },
  {
    "path": "test/lineWithFocusChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\nsvg {\n  display: block;\n}\n\n#chart1 svg {\n  height: 500px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  margin: 50px;\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n</style>\n<body>\n\n  <div id=\"chart\" class='with-3d-shadow with-transitions'>\n    <svg style=\"height: 500px;\"></svg>\n  </div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/line.js\"></script>\n<script src=\"../src/models/lineWithFocusChart.js\"></script>\n<script src=\"stream_layers.js\"></script>\n<script>\n\n\nnv.addGraph(function() {\n  var chart = nv.models.lineWithFocusChart();\n\n // chart.transitionDuration(500);\n  chart.xAxis\n      .tickFormat(d3.format(',f'));\n  chart.x2Axis\n      .tickFormat(d3.format(',f'));\n\n  chart.yAxis\n      .tickFormat(d3.format(',.2f'));\n  chart.y2Axis\n      .tickFormat(d3.format(',.2f'));\n\n  d3.select('#chart svg')\n      .datum(testData())\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); })\n\n  return chart;\n});\n\n\n\nfunction testData() {\n  return stream_layers(3,128,.1).map(function(data, i) {\n    return { \n      key: 'Stream' + i,\n      values: data\n    };\n  });\n}\n\n\n</script>\n"
  },
  {
    "path": "test/lineWithFocusChartMissingData.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <script src=\"../examples/lib/stream_layers.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, #chart, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body>\n\n<div id=\"chart\" class='with-3d-shadow with-transitions'>\n    <svg></svg>\n</div>\n\n<script>\n\n    nv.addGraph(function() {\n        var chart = nv.models.lineWithFocusChart();\n\n        chart.brushExtent([50,70]);\n\n        chart.xAxis.tickFormat(d3.format(',f'));\n        chart.x2Axis.tickFormat(d3.format(',f'));\n        chart.yAxis.tickFormat(d3.format(',.2f'));\n        chart.y2Axis.tickFormat(d3.format(',.2f'));\n        chart.useInteractiveGuideline(true);\n\n        d3.select('#chart svg')\n            .datum(testData())\n            .call(chart);\n\n        nv.utils.windowResize(chart.update);\n\n        return chart;\n    });\n\n    function testData() {\n        var data = stream_layers(3,128,.1).map(function(data, i) {\n            return {\n                key: 'Stream' + i,\n                area: i === 1,\n                values: data\n            };\n        });\n\n        // Set some y data to null\n        var i, j, d, o;\n        for(i = 0; i < data.length; i++) {\n            d = data[i];\n            for(j = 0; j < d.values.length; j++) {\n                o = d.values[j];\n                if (j % (i + 5) == 0) {\n                    o.y = null;\n                }\n            }\n        }\n        console.log(data);\n        return data;\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "test/mocha/axis.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Axis', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n        options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n\n        axisOptions =\n            margin:\n                top: 0\n                right: 0\n                bottom: 0\n                left: 0\n            width: 75\n            height: 60\n            axisLabel: 'Date'\n            showMaxMin: true\n            scale: d3.scale.linear()\n            rotateYLabel: true\n            rotateLabels: 0\n            staggerLabels: false\n            axisLabelDistance: 12\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.lineChart()\n            builder.build options, sampleData1\n\n            axis = builder.model.xAxis\n            for opt, val of axisOptions\n                axis[opt](val)\n\n            builder.model.update()\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            axis = builder.model.xAxis\n\n            for opt, val of axisOptions\n                should.exist axis[opt](), \"#{opt} can be called\"\n\n        it 'x axis structure', ->\n            axis = builder.$ '.nv-x.nv-axis'\n\n            should.exist axis[0], '.nv-axis exists'\n\n            maxMin = builder.$ '.nv-x.nv-axis .nv-axisMaxMin'\n\n            maxMin.should.have.length 2\n\n            maxMin[0].textContent.should.equal  '-1'\n            maxMin[1].textContent.should.equal '2'\n\n            ticks = builder.$ '.nv-x.nv-axis .tick'\n\n            ticks.should.have.length 2\n\n            expected = [\n                '0'\n                '1'\n            ]\n\n            for tick,i in ticks\n                tick.textContent.should.equal expected[i]\n\n            axisLabel = builder.$ '.nv-x.nv-axis .nv-axislabel'\n            should.exist axisLabel[0], 'axis label exists'\n            axisLabel[0].textContent.should.equal 'Date'\n\n        it 'y axis structure', ->\n            axis = builder.$ '.nv-y.nv-axis'\n\n            should.exist axis[0], '.nv-axis exists'\n\n            maxMin = builder.$ '.nv-y.nv-axis .nv-axisMaxMin'\n\n            maxMin.should.have.length 2\n\n            maxMin[0].textContent.should.equal  '-1'\n            maxMin[1].textContent.should.equal '2'\n\n            ticks = builder.$ '.nv-y.nv-axis .tick'\n\n            ticks.should.have.length 4\n\n            expected = [\n                '-1'\n                '0'\n                '1'\n                '2'\n            ]\n\n            for tick,i in ticks\n                tick.textContent.should.equal expected[i]\n\n        it 'axis rotate labels', ->\n            axis = builder.model.xAxis\n            axis.rotateLabels 30\n            builder.model.update()\n\n            ticks = builder.$ '.nv-x.nv-axis .tick text'\n\n            for tick in ticks\n                transform = tick.getAttribute 'transform'\n                transform.should.match /rotate\\(30 0,\\d+?.*?\\)/\n\n            maxMin = builder.$ '.nv-x.nv-axis .nv-axisMaxMin text'\n\n            for tick in maxMin\n                transform = tick.getAttribute 'transform'\n                transform.should.match /rotate\\(30 0,\\d+?.*?\\)/\n\n        it 'axis stagger labels', ->\n            axis = builder.model.xAxis\n            axis.staggerLabels true\n            builder.model.update()\n\n            ticks = builder.$ '.nv-x.nv-axis .tick text'\n\n            prevTransform = ''\n            for tick, i in ticks\n                transform = tick.getAttribute 'transform'\n\n                transform.should.not.equal prevTransform\n                transform.should.match /translate\\(0,(12|0)\\)/\n                prevTransform = transform\n\n        it 'axis orientation', (done)->\n            axis = builder.model.xAxis\n            axis.orient 'top'\n            builder.model.update()\n\n            axis.orient 'right'\n            builder.model.update()\n\n            done()\n\n        it 'has CSS class \"zero\" to mark zero tick', ->\n            tick = builder.$ '.nv-x.nv-axis .tick.zero'\n            tick.length.should.equal 1, 'x axis zero'\n\n            tick = builder.$ '.nv-y.nv-axis .tick.zero'\n            tick.length.should.equal 1, 'y axis zero'\n\n        it 'default tick format for max/min should be integer based', ->\n            axis = builder.model.xAxis\n            builder.model.update()\n            minAxisText = builder.$('.nv-axisMaxMin.nv-axisMaxMin-x.nv-axisMin-x text')[0].textContent\n\n            minAxisText.should.equal('-1')\n\n        it 'tickFormatMaxMin should change tick format of max/min', ->\n            axis = builder.model.xAxis\n            axis.tickFormatMaxMin(d3.format(',.2f'))\n            builder.model.update()\n            minAxisText = builder.$('.nv-axisMaxMin.nv-axisMaxMin-x.nv-axisMin-x text')[0].textContent\n\n            minAxisText.should.equal('-1.00')\n"
  },
  {
    "path": "test/mocha/boxplot.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Box Plot', ->\n        sampleData1 = [\n            label: 'Sample A',\n            values:  \n                Q1: 120,\n                Q2: 150,\n                Q3: 200,\n                whisker_low: 115,\n                whisker_high: 210,\n                outliers: [50, 100, 225]\n        ]\n\n        sampleData2 = [\n            label: 'Sample A',\n            values:  \n                Q1: 120,\n                Q2: 150,\n                Q3: 200,\n                whisker_low: 115,\n                whisker_high: 210,\n                outliers: []\n        ]\n\n        sampleData3 = [ \n            { \n              label: 'Sample A', \n              values: { Q1: 120, Q2: 150, Q3: 200, whisker_low: 115, whisker_high: 210, outliers: [50, 100, 225] } \n            },\n            { \n              label: 'Sample B', \n              values: { Q1: 300, Q2: 350, Q3: 400, whisker_low: 2255, whisker_high: 400, outliers: [175] } \n            }\n        ]\n\n        sampleData4 = [\n            label: 'Sample A',\n            values:  \n                Q1: -3,\n                Q2: -2,\n                Q3: -1,\n                whisker_low: -5,\n                whisker_high: 0,\n                outliers: [-10, 10]\n        ]\n        \n        options =\n            x: (d)-> d.label\n            y: (d)-> d.values.Q3\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            color: nv.utils.defaultColor()\n            height: 400\n            width: 800\n            showXAxis: true\n            showYAxis: true\n            noData: 'No Data Available'\n            duration: 0\n            maxBoxWidth: 75\n            \n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n            builder.model.update()\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-boxPlotWithAxes'\n            should.exist wrap[0]\n\n        it 'no data text', ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.build options, []\n\n            noData = builder.$ '.nv-noData'\n            noData[0].textContent.should.equal 'No Data Available'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-barsWrap'\n            '.nv-wrap'\n            '.nv-boxplot'\n            '.nv-boxplot-median'\n            '.nv-boxplot-tick.nv-boxplot-low'\n            '.nv-boxplot-whisker.nv-boxplot-low'\n            '.nv-boxplot-tick.nv-boxplot-high'\n            '.nv-boxplot-whisker.nv-boxplot-high'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-boxPlotWithAxes #{cssClass}\")[0]\n\n        it 'Has boxplots', ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.buildover options, sampleData3, []\n\n            boxes = builder.$ '.nv-boxplot-box'\n            boxes.length.should.equal 2, 'boxplots exist'\n\n        it 'Has outliers', ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.buildover options, sampleData1, []\n\n            outliers = builder.$ '.nv-boxplot .nv-boxplot-outlier'\n            outliers.length.should.equal 3, 'outliers exist'\n\n        it 'Has no outliers', ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.buildover options, sampleData2, []\n\n            outliers = builder.$ '.nv-boxplot-outlier'\n            outliers.length.should.equal 0, 'empty outliers'\n\n        it 'Displays whiskers whose value are <= 0', ->\n            builder = new ChartBuilder nv.models.boxPlotChart()\n            builder.buildover options, sampleData4, []\n\n            whiskers = builder.$ '.nv-boxplot-whisker'\n            whiskers.length.should.equal 2, 'zero whiskers'\n"
  },
  {
    "path": "test/mocha/bullet.coffee",
    "content": "describe 'NVD3', ->\n\n    describe 'Bullet Chart', ->\n        sampleData1 =\n            title: 'Revenue'\n            subtitle: 'US$ in thousands'\n            ranges: [10,20,30]\n            measures: [40]\n            markers: [50, 100]\n\n        options =\n            orient: 'left'\n            margin:\n                top: 60\n                right: 70\n                bottom: 80\n                left: 90\n            color: nv.utils.defaultColor()\n            ranges: (d)-> d.ranges\n            markers: (d)-> d.markers\n            measures: (d)-> d.measures\n            width: 100\n            height: 110\n            tickFormat: (d)-> d.toFixed 2\n            noData: 'No Data Available'\n\n        builder1 = null\n        beforeEach ->\n            builder1 = new ChartBuilder nv.models.bulletChart()\n            builder1.build options, sampleData1\n\n        afterEach ->\n            builder1.teardown()\n\n        it 'api check', ->\n          should.exist builder1.model.options, 'options exposed'\n          for opt of options\n              should.exist builder1.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder1.$ 'g.nvd3.nv-bulletChart'\n            should.exist wrap[0]\n\n        it 'displays multiple markers', ->\n          markers = document.querySelectorAll '.nv-markerTriangle'\n          markers.length.should.equal 2\n\n        it 'has correct g.nvd3.nv-bulletChart position', ->\n          chart = builder1.$ 'g.nvd3.nv-bulletChart'\n          chart[0].getAttribute('transform').should.be.equal 'translate(90,60)'\n\n        it \"has correct structure\", ->\n          cssClasses = [\n              '.nv-bulletWrap'\n              '.nv-bullet'\n              '.nv-rangeMax'\n              '.nv-rangeAvg'\n              '.nv-rangeMin'\n              '.nv-measure'\n              '.nv-markerTriangle'\n              '.nv-titles'\n              '.nv-title'\n              '.nv-subtitle'\n            ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder1.$(\"g.nvd3 #{cssClass}\")[0]\n\n        describe \"no markers\", ->\n          builder = null\n          sampleData = null\n\n          beforeEach ->\n            builder = new ChartBuilder nv.models.bulletChart()\n            noMarkerOptions =\n              margin:\n                top: 0\n                right: 0\n                bottom: 0\n                left: 0\n              width: 300\n            sampleData =\n              title: 'Revenue'\n              subtitle: 'US$ in thousands'\n              ranges: [10,20,30]\n              measures: [40]\n              markers: []\n            builder.build noMarkerOptions, sampleData\n          afterEach ->\n            builder.teardown()\n\n          it \"does not show marker if no marker provided\", ->\n            markers = builder.$ '.nv-markerTriangle'\n            markers.length.should.equal 0\n\n          it \"renders xAxis if empty markers\", ->\n            ticks = builder.$ '.nv-tick'\n            ticks.length.should.equal 5\n\n        describe \"applies correctly option\", ->\n\n          builder = null\n          sampleData = null\n\n          beforeEach ->\n            builder = new ChartBuilder nv.models.bulletChart()\n            sampleData =\n              title: 'Revenue'\n              subtitle: 'US$ in thousands'\n              ranges: [10,20,30]\n              measures: [40]\n              markers: [50]\n          afterEach ->\n            builder.teardown()\n\n          describe \"orient\", ->\n\n            it 'left', ->\n              options =\n                orient: 'left'\n              builder.build options, sampleData\n              ticks = builder.$(\".nv-tick\")\n              offsetPrevious = 0\n              offsetCurrent = 0\n              pattern = ///\n                  translate\\((.*),0\\)\n              ///\n              for tick, i in ticks\n                offsetPrevious = offsetCurrent\n                offsetCurrent = parseInt ticks[i].getAttribute('transform').match(pattern)[1]\n                window.setTimeout ->\n                    expect(offsetPrevious).to.be.below(offsetCurrent) if i > 0\n                , 1500\n\n            it 'right', ->\n              options =\n                orient: 'right'\n              builder.build options, sampleData\n              ticks = builder.$(\".nv-tick\")\n              offsetPrevious = 0\n              offsetCurrent = 0\n              pattern = ///\n                  translate\\((.*),0\\)\n              ///\n              for tick, i in ticks\n                offsetPrevious = offsetCurrent\n                offsetCurrent = parseInt ticks[i].getAttribute('transform').match(pattern)[1]\n                window.setTimeout ->\n                    expect(offsetPrevious).to.be.above(offsetCurrent) if i > 0\n                , 1500\n\n          it \"noData\", ->\n            options =\n              noData: 'No Data Available'\n            builder.build options, {}\n            builder.svg.textContent.should.be.equal 'No Data Available'\n\n\n          it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.bulletChart()\n            builder.buildover options, sampleData, []\n\n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n\n          it 'margin', ->\n            options =\n              margin:\n                top: 10\n                right: 20\n                bottom: 30\n                left: 40\n            builder.build options, sampleData\n            builder.$(\".nv-bulletChart\")[0].getAttribute('transform').should.be.equal \"translate(40,10)\"\n\n          it \"color\", ->\n            options =\n              color: -> \"#000000\"\n            builder.build options, sampleData\n            expect(builder.$(\".nv-measure\")[0].getAttribute(\"style\")).to.contain \"fill: rgb(0, 0, 0)\"\n\n          it 'width', ->\n            options =\n              margin:\n                top: 0\n                right: 0\n                bottom: 0\n                left: 0\n              width: 300\n            builder.build options, sampleData\n            parseInt( builder.$(\".nv-rangeMax\")[0].getAttribute('width') ).should.be.equal 300\n\n          it 'height', ->\n            options =\n              margin:\n                top: 0\n                right: 0\n                bottom: 0\n                left: 0\n              height: 300\n            builder.build options, sampleData\n            parseInt( builder.$(\".nv-rangeMax\")[0].getAttribute('height') ).should.be.equal 300\n\n"
  },
  {
    "path": "test/mocha/core.coffee",
    "content": "describe 'NVD3', ->\n\n  describe 'Core', ->\n\n    objects = [\n      'window.nv'\n      'd3_time_range'\n      'nv.utils'\n      'nv.models'\n      'nv.charts'\n      'nv.graphs'\n      'nv.logs'\n      'nv.dispatch'\n      'nv.log'\n      'nv.deprecated'\n      'nv.render'\n      'nv.addGraph'\n    ]\n\n    describe 'has', ->\n      for obj in objects\n        it \" #{obj} object\", ->\n          should.exist eval obj\n\n    describe 'has nv.dispatch with default', ->\n      dispatchDefaults = ['render_start', 'render_end']\n      for event in dispatchDefaults\n        do (event) ->\n          it \"#{event} event\", -> assert.isFunction nv.dispatch[event]\n"
  },
  {
    "path": "test/mocha/cumulative-line.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Cumulative Line Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [0.000001, 0.000001]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n            average: 1.3\n        ]\n\n        sampleData2 = [\n            key: 'Series 1'\n            values: [\n                [-1,-3]\n                [0,6]\n                [1,12]\n                [2,18]\n            ]\n            average: 12.3\n        ,\n            key: 'Series 2'\n            values: [\n                [-1,-4]\n                [0,7]\n                [1,13]\n                [2,14]\n            ]\n        ]\n\n        eventTooltipData = {mouseX: 1250, mouseY: 363, pointXValue: 1271774227712.8547}\n\n        options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n            margin:\n                right: 20\n                bottom: 30\n                left: 40\n            color: nv.utils.defaultColor()\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            useInteractiveGuideline: true\n            noData: 'No Data Available'\n            average: (d)-> d.average\n            duration: 0\n            noErrorCheck: false\n\n        builder1 = null\n        beforeEach ->\n            builder1 = new ChartBuilder nv.models.cumulativeLineChart()\n            builder1.build options, sampleData1\n\n            # remove all tooltips\n            elements = document.getElementsByClassName('nvtooltip')\n            while(elements[0])\n              elements[0].parentNode.removeChild(elements[0])\n\n        afterEach ->\n            builder1.teardown()\n\n        it 'api check', ->\n          should.exist builder1.model.options, 'options exposed'\n          for opt of options\n              should.exist builder1.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder1.$ 'g.nvd3.nv-cumulativeLine'\n            should.exist wrap[0]\n\n        it 'has the element with .nv-cumulativeLine class right positioned', ->\n          cumulativeLine = builder1.$ 'g.nvd3.nv-cumulativeLine'\n          cumulativeLine[0].getAttribute('transform').should.be.equal \"translate(40,30)\"\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.cumulativeLineChart()\n            builder.buildover options, sampleData1, []\n\n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-interactive'\n            '.nv-interactiveLineLayer'\n            '.nv-interactiveGuideLine'\n            '.nv-y.nv-axis'\n            '.nv-x.nv-axis'\n            '.nv-background'\n            '.nv-linesWrap'\n            '.nv-line'\n            '.nv-scatterWrap'\n            '.nv-scatter'\n            '.nv-indexLine'\n            '.nv-avgLinesWrap'\n            '.nv-legendWrap'\n            '.nv-controlsWrap'\n            '.tempDisabled'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder1.$(\"g.nvd3 #{cssClass}\")[0]\n\n        describe \"applies correctly option\", ->\n\n          builder = null\n          sampleData = sampleData1\n\n          beforeEach ->\n            builder = new ChartBuilder nv.models.cumulativeLineChart()\n\n          afterEach ->\n            builder.teardown()\n\n          # todo: ideally it should work, but...\n          xit 'margin', ->\n            options =\n              margin:\n                top: 10\n                right: 20\n                bottom: 30\n                left: 40\n            builder.build options, sampleData\n            builder.$(\".nv-cumulativeLine\")[0].getAttribute('transform').should.be.equal \"translate(40,10)\"\n\n          it \"color\", ->\n            options.color = -> \"#000000\"\n            builder.build options, sampleData\n            legendSymbol = builder.$(\".nv-cumulativeLine .nv-legend-symbol\")\n            expect(legendSymbol[0].getAttribute(\"style\")).to.contain \"fill: rgb(0, 0, 0)\"\n            expect(legendSymbol[0].getAttribute(\"style\")).to.contain \"stroke: rgb(0, 0, 0)\"\n\n          describe \"showLegend\", ->\n            it 'true', ->\n              options.showLegend = true\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-legendWrap *\").length.should.not.be.equal 0\n            it 'false', ->\n              options =\n                showLegend : false\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-legendWrap *\").length.should.be.equal 0\n\n          describe 'showXAxis', ->\n            it 'true', ->\n              options.showXAxis = true\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-axis.nv-x *\").length.should.not.be.equal 0\n            it 'false', ->\n              options.showXAxis = false\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-axis.nv-x *\").length.should.be.equal 0\n\n            it 'can override axis ticks', ->\n              builder.build options, sampleData\n              builder.model.xAxis.ticks(34)\n              builder.model.yAxis.ticks(56)\n              builder.model.update()\n              builder.model.xAxis.ticks().should.equal 34\n              builder.model.yAxis.ticks().should.equal 56\n\n          describe 'showYAxis', ->\n            it 'true', ->\n              options.showYAxis = true\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-axis.nv-y *\").length.should.not.be.equal 0\n            it 'false', ->\n              options.showYAxis = false\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-axis.nv-y *\").length.should.be.equal 0\n\n          describe 'rightAlignYAxis', ->\n            it 'true', ->\n              options.rightAlignYAxis = true\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-axis.nv-y\")[0].getAttribute('transform').should.be.equal \"translate(870,0)\"\n            it 'false', ->\n              options.rightAlignYAxis = false\n              builder.build options, sampleData\n              assert.isNull builder.$(\".nv-cumulativeLine .nv-axis.nv-y\")[0].getAttribute('transform')\n\n          describe \"useInteractiveGuideline\", ->\n            it \"true\", ->\n              options.useInteractiveGuideline = true\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-interactiveLineLayer\").should.have.length 1\n            it \"false\", ->\n              options.useInteractiveGuideline = false\n              builder.build options, sampleData\n              builder.$(\".nv-cumulativeLine .nv-interactiveLineLayer\").should.have.length 0\n\n          # todo: pass this\n          describe \"noErrorCheck\", ->\n            xit \"true\", ->\n              options.noErrorCheck = true\n              builder.build options, sampleData\n            xit \"false\", ->\n              options.noErrorCheck = false\n              builder.build options, sampleData\n\n          it \"noData\", ->\n            options.noData = \"error error\"\n            builder.build options, []\n            builder.svg.textContent.should.be.equal 'error error'\n\n          it \"x\", ->\n            options.x = (d) -> d[1]\n            builder.build options, sampleData\n            builder.model.x()([1,2]).should.be.equal 2\n\n          it \"y\", ->\n            options.y = (d) -> d[0]\n            builder.build options, sampleData\n            builder.model.y()({display: {y: 1}}).should.be.equal 1\n\n          it \"average\", ->\n            options.average = (d)-> d.avg\n            builder.build options, sampleData\n            builder.model.average()({avg: 1}).should.be.equal 1\n\n          it \"duration\", ->\n            options.duration = 100\n            builder.build options, sampleData\n            builder.model.duration().should.be.equal 100\n"
  },
  {
    "path": "test/mocha/differenceChart.js",
    "content": "(function () {\n  'use strict';\n\n  var clean = void 0,\n      benv = void 0,\n      _sinon = void 0,\n      ChartFactory = void 0,\n      snapshot = void 0,\n      _should = void 0,\n      moment = void 0;\n  if (typeof require !== 'undefined') {\n    clean = require('clean-html').clean;\n    benv = require('benv');\n    _sinon = require('sinon');\n    _should = require('chai').should();\n    require('coffee-script/register');\n    ChartFactory = require('./test-utils.coffee');\n    snapshot = require('snap-shot');\n    moment = require('moment');\n  } else {\n    ChartFactory = window.ChartBuilder;\n    _sinon = window.sinon;\n    _should = window.should;\n    moment = window.moment;\n  }\n\n  describe('NVD3', function () {\n    return describe('Difference Chart', function () {\n      var options = {\n        x: function x(d) {\n          return d.x;\n        },\n        y: function y(d) {\n          return d.y;\n        },\n\n        focusMargin: { top: 0, right: 60, bottom: 0, left: 20 },\n        margin: { top: 30, right: 20, bottom: 50, left: 75 },\n        noData: 'No Data Available',\n        duration: 0\n      };\n      // Predicted > Actual\n      var testData = [{\n        key: 'Actual Data',\n        type: 'actual',\n        values: [{ x: 123, y: 10 }, { x: 124, y: 20 }]\n      }, {\n        key: 'Predicted Data',\n        type: 'expected',\n        values: [{ x: 123, y: 15 }, { x: 124, y: 25 }]\n      }];\n\n      var sampleDataWithDates = [{\n        key: 'Actual Data',\n        type: 'actual',\n        values: [{ x: new Date('2016-01-01T02:00:00+1100'), y: 10 }, { x: new Date('2016-01-01T02:15:00+1100'), y: 30 }, { x: new Date('2016-01-01T02:20:00+1100'), y: 40 }, { x: new Date('2016-01-01T02:30:00+1100'), y: 20 }, { x: new Date('2016-01-01T02:45:00+1100'), y: 50 }, { x: new Date('2016-01-01T03:00:00+1100'), y: 60 }]\n      }, {\n        key: 'Predicted Data',\n        type: 'expected',\n        values: [{ x: new Date('2016-01-01T02:00:00+1100'), y: 15 }, { x: new Date('2016-01-01T02:15:00+1100'), y: 35 }, { x: new Date('2016-01-01T02:20:00+1100'), y: 45 }, { x: new Date('2016-01-01T02:30:00+1100'), y: 25 }, { x: new Date('2016-01-01T02:45:00+1100'), y: 75 }, { x: new Date('2016-01-01T03:00:00+1100'), y: 65 }]\n      }];\n\n      var builder = null;\n      var sandbox = void 0;\n\n      function setupBenv(done) {\n        if (typeof require === 'undefined') {\n          done();\n          return;\n        }\n        benv.setup(function () {\n          benv.expose({\n            $: benv.require('zepto'),\n            d3: benv.require('d3'),\n            nv: benv.require('../../src/core.js')\n          });\n          benv.require('../../src/dom.js');\n          benv.require('../../src/utils.js');\n          benv.require('../../src/interactiveLayer.js');\n          benv.require('../../src/tooltip.js');\n          benv.require('../../src/models/differenceChart.js');\n          benv.require('../../src/models/line.js');\n          benv.require('../../src/models/scatter.js');\n          benv.require('../../src/models/axis.js');\n          benv.require('../../src/models/legend.js');\n          benv.require('../../src/models/focus.js');\n          benv.require('../../src/models/historicalBar.js');\n          benv.require('../../src/models/multiChart.js');\n          benv.require('../../src/models/multiBar.js');\n          benv.require('../../src/models/stackedArea.js');\n          done();\n        });\n      }\n\n      before(function (done) {\n        sandbox = _sinon.sandbox.create();\n        setupBenv(done);\n      });\n\n      beforeEach(function () {\n        options.color = nv.utils.defaultColor();\n        builder = new ChartFactory(nv.models.differenceChart());\n        builder.build(options, testData);\n      });\n\n      afterEach(function () {\n        builder.teardown();\n        sandbox.restore();\n      });\n\n      after(function () {\n        if (typeof benv === 'undefined') {\n          return;\n        }\n        benv.teardown(true);\n      });\n\n      it('y-domain should be the maximum and minimum y values on the graph', function () {\n        var someData = [{\n          key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n          type: 'area',\n          values: [{ x: 123, y0: 10, y1: 15 }, { x: 124, y0: 20, y1: 25 }],\n          yAxis: 1,\n          color: 'rgba(44,160,44,.9)',\n          processed: true\n        }, {\n          key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n          type: 'area',\n          values: [{ x: 123, y0: 10, y1: 10 }, { x: 124, y0: 20, y1: 20 }],\n          yAxis: 1,\n          color: 'rgba(234,39,40,.9)',\n          processed: true\n        }, {\n          key: 'Actual Data',\n          type: 'line',\n          values: [{ x: 123, y: 10 }, { x: 124, y: 20 }],\n          yAxis: 1,\n          color: '#666666',\n          processed: true,\n          strokeWidth: 1\n        }, {\n          key: 'Predicted Data',\n          type: 'line',\n          values: [{ x: 123, y: 15 }, { x: 124, y: 25 }],\n          yAxis: 1,\n          color: '#aec7e8',\n          processed: true,\n          strokeWidth: 1\n        }];\n        builder.model.processData(someData);\n        builder.model.multiChart.yDomain1().should.deep.equal([10, 25]);\n      });\n\n      describe('should be able to handle empty date', function () {\n        it('clears chart objects for empty data', function () {\n          builder.updateData([]);\n\n          var groups = builder.$('g');\n          groups.length.should.equal(0, 'removes chart components');\n          builder.$('.nv-noData').length.should.equal(1);\n        });\n\n        it('clears chart objects if all of the datasets are disabled', function () {\n          var disabledData = testData.map(function (dataset) {\n            var processedData = Object.assign({}, dataset);\n            processedData.disabled = true;\n            return processedData;\n          });\n\n          builder.updateData(disabledData);\n\n          var groups = builder.$('g');\n          groups.length.should.equal(0, 'removes chart components');\n          builder.$('.nv-noData').length.should.equal(1);\n        });\n\n        it('clears chart objects for undefined data', function () {\n          builder.updateData(null);\n\n          var groups = builder.$('g');\n          groups.length.should.equal(0, 'removes chart components');\n          builder.$('.nv-noData').length.should.equal(1);\n        });\n\n        it('clears chart components if chart has no values', function () {\n          var dataWithNoValues = testData.map(function (dataset) {\n            var modifiedDataset = Object.assign({}, dataset);\n            modifiedDataset.values = [];\n            return modifiedDataset;\n          });\n\n          builder.updateData(dataWithNoValues);\n          var groups = builder.$('g');\n          groups.length.should.equal(0, 'removes chart components');\n          builder.$('.nv-noData').length.should.equal(1);\n        });\n\n        it('should clear no data artefacts if data is supplied', function () {\n          // set up no data\n          builder.updateData([]);\n          builder.updateData(testData);\n          builder.$('.nv-noData').length.should.equal(0);\n        });\n      });\n\n      it('api check', function () {\n        _should.exist(builder.model.options, 'options exposed');\n        return function () {\n          var result = [];\n          for (var opt in options) {\n            result.push(_should.exist(builder.model[opt](), opt + ' can be called'));\n          }\n          return result;\n        }();\n      });\n\n      describe('Processing Data', function () {\n        it('should does not process data if series toggled off', function () {\n          builder.model.showPredictedLine(false);\n<<<<<<< HEAD\n          var expectedData = [{\n            key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n            type: 'area',\n            values: [{ x: 123, y0: 10, y1: 15 }, { x: 124, y0: 20, y1: 25 }],\n            yAxis: 1,\n            color: 'rgba(44,160,44,.9)',\n            processed: true,\n            noHighlightSeries: true\n          },\n          {\n            key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n            type: 'area',\n            values: [{ x: 123, y0: 10, y1: 10 }, { x: 124, y0: 20, y1: 20 }],\n            yAxis: 1,\n            color: 'rgba(234,39,40,.9)',\n            processed: true,\n            noHighlightSeries: true\n          },\n          {\n            key: 'Actual Data',\n            type: 'line',\n            values: [{ x: 123, y: 10 }, { x: 124, y: 20 }],\n            yAxis: 1,\n            color: '#666666',\n            processed: true,\n            strokeWidth: 1\n          }];\n=======\n          var expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 10, y1: 15 }, { x: '124', y0: 20, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 10, y1: 10 }, { x: '124', y0: 20, y1: 20 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: '123', y: 10 }, { x: '124', y: 20 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n          var actualData = builder.model.processData(testData);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n\n        it('correctly processes data when Predicted > Actual', () => {\n          var expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 10, y1: 15 }, { x: '124', y0: 20, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 10, y1: 10 }, { x: '124', y0: 20, y1: 20 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: '123', y: 10 }, { x: '124', y: 20 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            },\n            {\n              key: 'Predicted Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }],\n              yAxis: 1,\n              color: '#aec7e8',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n          var actualData = builder.model.processData(testData);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n\n        it('correctly processes data when Predicted < Actual', function () {\n          //Predicted < Actual\n          var testData2 = [\n            {\n              key: 'Actual Data',\n              type: 'actual',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }]\n            },\n            {\n              key: 'Predicted Data',\n              type: 'expected',\n              values: [{ x: '123', y: 10 }, { x: '124', y: 20 }]\n            }\n          ];\n          var expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 15 }, { x: '124', y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 10 }, { x: '124', y0: 25, y1: 20 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            },\n            {\n              key: 'Predicted Data',\n              type: 'line',\n              values: [{ x: '123', y: 10 }, { x: '124', y: 20 }],\n              yAxis: 1,\n              color: '#aec7e8',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n          var actualData = builder.model.processData(testData2);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n\n        it('correctly processes data when Predicted = Actual', () => {\n          var equalTestData = [\n            {\n              key: 'Actual Data',\n              type: 'actual',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }]\n            },\n            {\n              key: 'Predicted Data',\n              type: 'expected',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }]\n            }\n          ];\n\n          var expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 15 }, { x: '124', y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 15 }, { x: '124', y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            },\n            {\n              key: 'Predicted Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }],\n              yAxis: 1,\n              color: '#aec7e8',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n          var actualData = builder.model.processData(equalTestData);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n\n        it('removes any predicted data points that are not found in predicted data', () => {\n          const unevenTestData = [\n            {\n              key: 'Actual Data',\n              type: 'actual',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }]\n            },\n            {\n              key: 'Predicted Data',\n              type: 'expected',\n              values: [{ x: '123', y: 15 }, { x: 125, y: 25 }]\n            }\n          ];\n          const expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 15 }, { x: '124', y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: '123', y0: 15, y1: 15 }, { x: '124', y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            },\n            {\n              key: 'Predicted Data',\n              type: 'line',\n              values: [{ x: '123', y: 15 }, { x: '124' }],\n              yAxis: 1,\n              color: '#aec7e8',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n\n          const actualData = builder.model.processData(unevenTestData);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n\n        it('respects any processing done in x accessor', () => {\n          const unevenTestData = [\n            {\n              key: 'Actual Data',\n              type: 'actual',\n              values: [{ x: '123', y: 15 }, { x: '124', y: 25 }]\n            },\n            {\n              key: 'Predicted Data',\n              type: 'expected',\n              values: [{ x: '123', y: 15 }, { x: 125, y: 25 }]\n            }\n          ];\n          builder.model.x((d) => parseInt(d.x));\n          const expectedData = [\n            {\n              key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n              type: 'area',\n              values: [{ x: 123, y0: 15, y1: 15 }, { x: 124, y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(44,160,44,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n              type: 'area',\n              values: [{ x: 123, y0: 15, y1: 15 }, { x: 124, y0: 25, y1: 25 }],\n              yAxis: 1,\n              color: 'rgba(234,39,40,.9)',\n              processed: true,\n              noHighlightSeries: true\n            },\n            {\n              key: 'Actual Data',\n              type: 'line',\n              values: [{ x: 123, y: 15 }, { x: 124, y: 25 }],\n              yAxis: 1,\n              color: '#666666',\n              processed: true,\n              strokeWidth: 1\n            },\n            {\n              key: 'Predicted Data',\n              type: 'line',\n              values: [{ x: 123, y: 15 }, { x: 124 }],\n              yAxis: 1,\n              color: '#aec7e8',\n              processed: true,\n              strokeWidth: 1\n            }\n          ];\n\n          const actualData = builder.model.processData(unevenTestData);\n          JSON.stringify(actualData).should.equal(JSON.stringify(expectedData));\n        });\n      });\n\n      it('should render the chart', function () {\n        var wrap = builder.$('.multiChart');\n        return _should.exist(wrap[0]);\n      });\n\n      it('should clear chart objects for no data', function () {\n        builder = new ChartFactory(nv.models.differenceChart());\n        builder.buildover(options, testData, []);\n\n        var groups = builder.$('g');\n        groups.length.should.equal(0, 'removes chart components');\n      });\n\n      it('has correct structure', function () {\n        var cssClasses = ['.multiChart', '.multiChart .nv-interactive', '.multiChart .nv-x.nv-axis', '.nv-focus'];\n        cssClasses.forEach(function (cssClass) {\n          _should.exist(builder.$('' + cssClass)[0]);\n        });\n      });\n\n      describe('default values', function () {\n        it('default chart width should be null', function () {\n          var defaultWidth = builder.model.width();\n          _should.equal(defaultWidth, null);\n        });\n\n        it('default chart height should be null', function () {\n          var defaultHeight = builder.model.height();\n          _should.equal(defaultHeight, null);\n        });\n\n        it('default value for showPredictedLine should be true', function () {\n          var defaultValue = builder.model.showPredictedLine();\n          defaultValue.should.be.true;\n        });\n      });\n\n      describe('setters', function () {\n        it('can override chart focusMargin', function () {\n          builder.model.focusMargin({ right: 75 });\n          builder.model.focusMargin().right.should.equal(75);\n\n          builder.model.focusMargin({ bottom: 7 });\n          builder.model.focusMargin().bottom.should.equal(7);\n        });\n\n        it('can override chart Margin', function () {\n          builder.model.margin({ right: 75 });\n          builder.model.margin().right.should.equal(75);\n\n          builder.model.margin({ bottom: 7 });\n          builder.model.margin().bottom.should.equal(7);\n        });\n\n        it('can override chart interpolation', function () {\n          builder.model.interpolate('basis');\n\n          return builder.model.interpolate().should.equal('basis');\n        });\n\n        it('can override chart strokeWidth', function () {\n          builder.model.strokeWidth(3);\n\n          return builder.model.strokeWidth().should.equal(3);\n        });\n\n        it('can override chart keyForActualLessThanPredicted', function () {\n          builder.model.keyForActualLessThanPredicted('blah');\n\n          return builder.model.keyForActualLessThanPredicted().should.equal('blah');\n        });\n\n        it('can override chart keyForActualGreaterThanPredicted', function () {\n          builder.model.keyForActualGreaterThanPredicted('yoo');\n\n          return builder.model.keyForActualGreaterThanPredicted().should.equal('yoo');\n        });\n\n        it('can override axis ticks', function () {\n          builder.model.xAxis.ticks(34);\n          builder.model.yAxis.ticks(56);\n          builder.model.xAxis.ticks().should.equal(34);\n          return builder.model.yAxis.ticks().should.equal(56);\n        });\n\n        it('can override chart height', function () {\n          builder.model.height(340);\n          builder.model.update();\n          var xAxis = builder.$('.multiChart .nv-x.nv-axis');\n          xAxis[0].getAttribute('transform').should.equal('translate(0,110)');\n        });\n\n        it('can override chart width', function () {\n          builder.model.width(340);\n          builder.model.update();\n\n          var legendWrap = builder.$('.legendWrap');\n          legendWrap[0].getAttribute('transform').should.equal('translate(122.5,-30)');\n        });\n\n        it('can override xAccessor', function () {\n          builder.model.x(888);\n          builder.model.x().should.equal(888);\n        });\n\n        it('can override yAccessor', function () {\n          builder.model.y(999);\n          builder.model.y().should.equal(999);\n        });\n\n        describe('xScale', function () {\n          it('defaults to d3.time.scale()', function () {\n            var defaultXScale = builder.model.multiChart.xAxis.scale();\n            defaultXScale.domain.toString().indexOf('Date').should.not.equal(-1);\n          });\n\n          it('can override xScale', function () {\n            builder.model.xScale(999);\n            builder.model.xScale().should.equal(999);\n          });\n        });\n\n        describe('tickFormat', function () {\n          it('can override tickFormat', function () {\n            builder.model.tickFormat(999);\n            builder.model.tickFormat().should.equal(999);\n          });\n        });\n      });\n\n      describe('tooltip - ', function () {\n        var testCases = [{\n          name: 'If no point data supplied, should use value (first param) ',\n          payloadForPointData: { key: 'blah' },\n          expectedResult: '10'\n        }, {\n          name: 'If equal point data supplied, should use value (first param) ',\n          payloadForPointData: {\n            key: 'keyForActualLessThanPredicted',\n            data: { y0: '5', y1: '5' }\n          },\n          expectedResult: '-'\n        }, {\n          name: 'If different point data supplied, should use value (first param) ',\n          payloadForPointData: {\n            key: 'keyForActualLessThanPredicted',\n            data: { y0: '25', y1: '20' }\n          },\n          expectedResult: 5\n        }];\n\n        testCases.forEach(function (testCase) {\n          it(testCase.name, function () {\n            builder.model.keyForActualLessThanPredicted('keyForActualLessThanPredicted');\n            var valueFormatter = builder.model.multiChart.interactiveLayer.tooltip.valueFormatter();\n            valueFormatter('10', '3', testCase.payloadForPointData).should.deep.equal(testCase.expectedResult);\n          });\n        });\n      });\n\n      describe('yAxis', function () {\n        var yForMultiChartFunc = void 0;\n        beforeEach(function () {\n          var yForMultiChartSpy = sandbox.spy(builder.model.multiChart, 'y');\n          builder.model.update();\n\n          yForMultiChartFunc = yForMultiChartSpy.args[0][0];\n        });\n\n        it('yAxis for multi chart should return y0 if y0 is defined', function () {\n          yForMultiChartFunc({\n            y0: 'blah'\n          }).should.equal('blah');\n        });\n\n        it('yAxis for multi chart should return y if y0 is not defined', function () {\n          yForMultiChartFunc({\n            y: 'boo'\n          }).should.equal('boo');\n        });\n      });\n\n      describe('areaY1', function () {\n        it('should use the scatter yScale to calculate the value using d.display.y', function () {\n          var fakeYScale = sandbox.spy(d3.scale.linear());\n          builder.model.multiChart.stack1.scatter.yScale(fakeYScale);\n          builder.model.update();\n\n          builder.model.multiChart.stack1.areaY1()({\n            display: {\n              y: 'jabbathehutt'\n            }\n          });\n          fakeYScale.args[fakeYScale.args.length - 1][0].should.equal('jabbathehutt');\n        });\n      });\n\n      describe('x axis', function () {\n        it('should use a multi time formatter to format x axis ticks by default', function () {\n          var testDataForXAxis = [{\n            testDatum: new Date('2017-01-03T09:15:00'),\n            expectedValue: '09:15'\n          }, {\n            testDatum: new Date('2017-01-03T09:00:00'),\n            expectedValue: '09 AM'\n          }, {\n            testDatum: new Date('2017-01-03T00:00:00'),\n            expectedValue: 'Tue 03'\n          }, {\n            testDatum: new Date('2017-04-02T00:00:00'),\n            expectedValue: 'Apr 02'\n          }, {\n            testDatum: new Date('2000-05-01T00:00:00'),\n            expectedValue: 'May'\n          }, {\n            testDatum: new Date('2000-01-01T00:00:00'),\n            expectedValue: '2000'\n          }];\n\n          testDataForXAxis.forEach(function (testDataset) {\n            builder.model.multiChart.xAxis.tickFormat()(testDataset.testDatum).should.equal(testDataset.expectedValue);\n          });\n        });\n\n        it('has default range value', function () {\n          builder.model.multiChart.xAxis.range()[1].should.be.above(0);\n        });\n\n        it('sets up x domain based on the extent of the dataset x values', function () {\n          var processedData = [{\n            key: 'Predicted Data minus Actual Data (Predicted > Actual)',\n            type: 'area',\n            values: [{ x: new Date('2016-01-03T09:00'), y0: 10, y1: 15 }, { x: new Date('2016-01-03T09:30'), y0: 20, y1: 25 }],\n            yAxis: 1,\n            color: 'rgba(44,160,44,.9)',\n            processed: true\n          }, {\n            key: 'Predicted Data minus Actual Data (Predicted < Actual)',\n            type: 'area',\n            values: [{ x: new Date('2016-01-03T09:00'), y0: 10, y1: 10 }, { x: new Date('2016-01-03T09:30'), y0: 20, y1: 20 }],\n            yAxis: 1,\n            color: 'rgba(234,39,40,.9)',\n            processed: true\n          }, {\n            key: 'Actual Data',\n            type: 'line',\n            values: [{ x: new Date('2016-01-03T09:00'), y: 10 }, { x: new Date('2016-01-03T09:30'), y: 20 }],\n            yAxis: 1,\n            color: '#666666',\n            processed: true,\n            strokeWidth: 1\n          }, {\n            key: 'Predicted Data',\n            type: 'line',\n            values: [{ x: new Date('2016-01-03T09:00'), y: 15 }, { x: new Date('2016-01-03T09:30'), y: 25 }],\n            yAxis: 1,\n            color: '#aec7e8',\n            processed: true,\n            strokeWidth: 1\n          }];\n          builder.updateData(processedData);\n          var expectedDomain = [new Date('2016-01-03T09:00'), new Date('2016-01-03T09:30')];\n          builder.model.multiChart.xAxis.domain().should.be.deep.equal(expectedDomain);\n        });\n      });\n\n      describe('margin', function () {\n        it('by default, should be { top: 30, right: 20, bottom: 50, left: 75 }', function () {\n          var defaultMargin = builder.model.margin();\n          var expectedMargin = { top: 30, right: 20, bottom: 50, left: 75 };\n          defaultMargin.should.deep.equal(expectedMargin);\n        });\n\n        describe('if not all margin components passed, should use previous config', function () {\n          var testCases = [{\n            testData: { top: 10 },\n            expectedMargin: { top: 10, right: 20, bottom: 50, left: 75 }\n          }, {\n            testData: {},\n            expectedMargin: { top: 30, right: 20, bottom: 50, left: 75 }\n          }, {\n            testData: { left: 10 },\n            expectedMargin: { top: 30, right: 20, bottom: 50, left: 10 }\n          }, {\n            testData: { right: 10 },\n            expectedMargin: { top: 30, right: 10, bottom: 50, left: 75 }\n          }, {\n            testData: { bottom: 10 },\n            expectedMargin: { top: 30, right: 20, bottom: 10, left: 75 }\n          }, {\n            testData: { left: 10 },\n            expectedMargin: { top: 30, right: 20, bottom: 50, left: 10 }\n          }, {\n            testData: { top: 10, left: 20 },\n            expectedMargin: { top: 10, right: 20, bottom: 50, left: 20 }\n          }];\n\n          testCases.forEach(function (testCase) {\n            it('updating margin with ' + JSON.stringify(testCase.testData) + ' should result in margin of ' + JSON.stringify(testCase.expectedMargin), function () {\n              builder.model.margin(testCase.testData);\n              builder.model.margin().should.deep.equal(testCase.expectedMargin);\n            });\n          });\n        });\n\n        it('updating the margin should change the chart', function () {\n          builder.model.margin({ top: 150 });\n          builder.model.update();\n\n          var yAxisTransform = builder.$('.nv-axisMaxMin-y')[0].getAttribute('transform');\n          yAxisTransform.should.equal('translate(0,400)');\n        });\n      });\n\n      it('x-axis labels should rotate as specified', function () {\n        builder.model.focus.xAxis.rotateLabels(60);\n        builder.model.focus.xAxis.rotateLabels().should.be.equal(60);\n      });\n\n      it('after the user brushes, the x axis domain should be equal to the brush extent', function () {\n        var expectedDomain = [new Date('2016-01-01T01:00:00+1100'), new Date('2016-01-01T03:30:00+1100')];\n        builder.model.focus.dispatch.onBrush(expectedDomain);\n        var newDomain = builder.model.multiChart.xAxis.domain();\n        newDomain.should.be.deep.equal(expectedDomain);\n      });\n\n      it('after the user brushes, the chart should only contain values within the brush extent', () => {\n        builder.model.x((d) => new Date(d.x));\n        builder.updateData(sampleDataWithDates);\n        var newBrushExtent = [new Date('2016-01-01T02:15:00+1100'), new Date('2016-01-01T02:45:00+1100')];\n\n        builder.model.focus.dispatch.onBrush(newBrushExtent);\n\n        var dataFromChart = d3.select(builder.model.container).datum();\n        dataFromChart[0].values.forEach(function (value) {\n          value.x.should.be.at.least(newBrushExtent[0]).and.be.at.most(newBrushExtent[1]);\n        });\n      });\n\n      describe('focusMargin', function () {\n        it('by default, should be { left: 0, right: 0, top: 10, bottom: 20 }', function () {\n          var defaultMargin = builder.model.focusMargin();\n          var expectedMargin = {\n            left: 20,\n            right: 60,\n            top: 0,\n            bottom: 0\n          };\n          defaultMargin.should.deep.equal(expectedMargin);\n        });\n\n        describe('if not all margin components passed, should use previous config', function () {\n          var testCases = [{\n            testData: { top: 20 },\n            expectedMargin: { top: 20, right: 60, bottom: 0, left: 20 }\n          }, {\n            testData: {},\n            expectedMargin: { top: 0, right: 60, bottom: 0, left: 20 }\n          }, {\n            testData: { left: 10 },\n            expectedMargin: { top: 0, right: 60, bottom: 0, left: 10 }\n          }, {\n            testData: { right: 10 },\n            expectedMargin: { top: 0, right: 10, bottom: 0, left: 20 }\n          }, {\n            testData: { bottom: 10 },\n            expectedMargin: { top: 0, right: 60, bottom: 10, left: 20 }\n          }, {\n            testData: { top: 10, left: 20 },\n            expectedMargin: { top: 10, right: 60, bottom: 0, left: 20 }\n          }];\n\n          testCases.forEach(function (testCase) {\n            it('updating focus margin with ' + JSON.stringify(testCase.testData) + ' should result in margin of ' + JSON.stringify(testCase.expectedMargin), function () {\n              builder.model.focusMargin(testCase.testData);\n              builder.model.focusMargin().should.deep.equal(testCase.expectedMargin);\n            });\n          });\n        });\n\n        it('updating the focus margin should change the chart', function () {\n          builder.model.focusMargin({ bottom: 10 });\n          builder.model.update();\n          var xAxisTransform = builder.$('.nv-focus .nv-axis')[0].getAttribute('transform');\n          xAxisTransform.should.equal('translate(0,60)');\n        });\n      });\n\n      if (typeof require !== 'undefined') {\n        var pretty = function pretty(html) {\n          var result = void 0;\n          clean(html, function (out) {\n            result = out;\n          });\n\n          return result.replace(/nv-edge-clip-[\\d]*/g, '').replace(/nv-chart-[\\d]*/g, '').replace(/id=\"[^\"]*\"/g, '').replace(/clip-path=\"[^\"]*\"/g, '').replace(/d=\"[^\"]*\"/g, '').replace(/class=\"[^\"]*\"/g, '').replace(/transform=\"[^\"]*\"/g, '');\n        };\n\n        describe('Snapshot', function () {\n          it('should match expected snapshot', function () {\n            builder.updateData(sampleDataWithDates);\n            var svgData = pretty(builder.svg.innerHTML);\n            snapshot(svgData);\n          });\n        });\n      }\n    });\n  });\n})();\n"
  },
  {
    "path": "test/mocha/discretebar.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Discrete Bar Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                {label: 'America', value: 100}\n                {label: 'Europe', value: 200}\n                {label: 'Asia', value: 50}\n                {label: 'Africa', value: 70}\n            ]\n        ]\n\n        options =\n            x: (d)-> d.label\n            y: (d)-> d.value\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            color: nv.utils.defaultColor()\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            staggerLabels: true\n            showValues: true\n            valueFormat: (d)-> d.toFixed 2\n            noData: 'No Data Available'\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.discreteBarChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-discreteBarWithAxes'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.discreteBarChart()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-barsWrap'\n            '.nv-discretebar'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-discreteBarWithAxes #{cssClass}\")[0]\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n\n"
  },
  {
    "path": "test/mocha/distrochart.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Distrochart', ->\n        data = [\n            {subject: 3, weight: 19, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 4, weight: 19.36, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 5, weight: 17.96, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 8, weight: 18.5, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 12, weight: 18.6, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 1, weight: 20.53, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 3, weight: 19.63, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 6, weight: 17.45, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 11, weight: 18.67, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 14, weight: 18.18, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 2, weight: 17.81, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 5, weight: 19.07, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 7, weight: 18.33, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 10, weight: 18.31, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 13, weight: 17.1, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 6, weight: 17.69, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 9, weight: 18.08, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 10, weight: 18.07, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 16, weight: 18.6, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 17, weight: 19.45, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 3, weight: 16.7, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 5, weight: 18.3, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 6, weight: 17.5, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 10, weight: 18.5, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 16, weight: 18.6, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 16.96, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 4, weight: 17.79, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 7, weight: 17.28, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 8, weight: 17.28, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 11, weight: 16.46, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 18.7, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 2, weight: 16.2, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 9, weight: 21.2, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 11, weight: 18.8, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 14, weight: 17.9, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 4, weight: 17.8, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 8, weight: 19.3, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 12, weight: 18.8, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 15, weight: 18.8, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 5, weight: 20.1, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 6, weight: 18.1, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 8, weight: 20.8, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 17, weight: 17.7, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 19, weight: 16.9, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 2, weight: 16.9, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 9, weight: 18.33, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 12, weight: 17.86, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 13, weight: 16.64, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 15, weight: 18.1, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 1, weight: 19, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 2, weight: 19.5, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 10, weight: 20.9, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 11, weight: 20, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 14, weight: 18.3, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 4, weight: 18.3, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 7, weight: 17, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 12, weight: 17.8, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 13, weight: 17.8, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 16, weight: 15.7, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 15, weight: 17.4, isolator: 'E', study: 'II', treatment: 'delta', donor: 'two'},\n            {subject: 16, weight: 18.8, isolator: 'E', study: 'II', treatment: 'delta', donor: 'two'},\n            {subject: 18, weight: 18, isolator: 'E', study: 'II', treatment: 'delta', donor: 'two'},\n            {subject: 6, weight: 18.9, isolator: 'E', study: 'II', treatment: 'delta', donor: 'two'},\n            {subject: 7, weight: 16.9, isolator: 'E', study: 'II', treatment: 'delta', donor: 'two'},\n            {subject: 2, weight: 18.9, isolator: 'C', study: 'IV', treatment: 'delta', donor: 'two'},\n            {subject: 3, weight: 18.7, isolator: 'C', study: 'IV', treatment: 'delta', donor: 'two'},\n            {subject: 14, weight: 18.3, isolator: 'C', study: 'IV', treatment: 'delta', donor: 'two'},\n            {subject: 16, weight: 18, isolator: 'C', study: 'IV', treatment: 'delta', donor: 'two'},\n            {subject: 18, weight: 19.4, isolator: 'C', study: 'IV', treatment: 'delta', donor: 'two'},\n            {subject: 3, weight: 18.4, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 4, weight: 18.6, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 5, weight: 18.3, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 8, weight: 18.3, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 12, weight: 18.6, isolator: 'C', study: 'V', treatment: 'delta', donor: 'two'},\n            {subject: 14, weight: 19.9, isolator: 'D', study: 'II', treatment: 'delta', donor: 'nine'},\n            {subject: 2, weight: 18.4, isolator: 'D', study: 'II', treatment: 'delta', donor: 'nine'},\n            {subject: 3, weight: 17.4, isolator: 'D', study: 'II', treatment: 'delta', donor: 'nine'},\n            {subject: 4, weight: 17.9, isolator: 'D', study: 'II', treatment: 'delta', donor: 'nine'},\n            {subject: 8, weight: 17.6, isolator: 'D', study: 'II', treatment: 'delta', donor: 'nine'},\n            {subject: 1, weight: 20.1, isolator: 'E', study: 'IV', treatment: 'gamma', donor: 'two'},\n            {subject: 5, weight: 17.4, isolator: 'E', study: 'IV', treatment: 'gamma', donor: 'two'},\n            {subject: 7, weight: 17.8, isolator: 'E', study: 'IV', treatment: 'gamma', donor: 'two'},\n            {subject: 10, weight: 17.5, isolator: 'E', study: 'IV', treatment: 'gamma', donor: 'two'},\n            {subject: 15, weight: 16.3, isolator: 'E', study: 'IV', treatment: 'gamma', donor: 'two'},\n            {subject: 1, weight: 19.9, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 3, weight: 19.3, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 6, weight: 16.8, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 11, weight: 18.8, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 14, weight: 17.5, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 2, weight: 17, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 5, weight: 19.5, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 7, weight: 18.2, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 10, weight: 18.5, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 13, weight: 17.2, isolator: 'E', study: 'V', treatment: 'beta', donor: 'two'},\n            {subject: 2, weight: 15.3, isolator: 'D', study: 'IV', treatment: 'alpha', donor: 'two'},\n            {subject: 4, weight: 18.9, isolator: 'D', study: 'IV', treatment: 'alpha', donor: 'two'},\n            {subject: 6, weight: 19.4, isolator: 'D', study: 'IV', treatment: 'alpha', donor: 'two'},\n            {subject: 8, weight: 17.8, isolator: 'D', study: 'IV', treatment: 'alpha', donor: 'two'},\n            {subject: 11, weight: 17.7, isolator: 'D', study: 'IV', treatment: 'alpha', donor: 'two'},\n            {subject: 6, weight: 18, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 9, weight: 18.7, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 10, weight: 18.1, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 16, weight: 18.9, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 17, weight: 19.4, isolator: 'D', study: 'V', treatment: 'alpha', donor: 'two'},\n            {subject: 10, weight: 18.9, isolator: 'D', study: 'III', treatment: 'control', donor: 'one'},\n            {subject: 13, weight: 17.5, isolator: 'D', study: 'III', treatment: 'control', donor: 'one'},\n            {subject: 16, weight: 17.9, isolator: 'D', study: 'III', treatment: 'control', donor: 'one'},\n            {subject: 4, weight: 18.7, isolator: 'D', study: 'III', treatment: 'control', donor: 'one'},\n            {subject: 6, weight: 17.5, isolator: 'D', study: 'III', treatment: 'control', donor: 'one'},\n            {subject: 3, weight: 16.5, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 5, weight: 18, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 6, weight: 17.1, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 10, weight: 17.6, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 16, weight: 18, isolator: 'F', study: 'I', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 17.7, isolator: 'C', study: 'II', treatment: 'control', donor: 'two'},\n            {subject: 13, weight: 19.1, isolator: 'C', study: 'II', treatment: 'control', donor: 'two'},\n            {subject: 15, weight: 17.7, isolator: 'C', study: 'II', treatment: 'control', donor: 'two'},\n            {subject: 17, weight: 17.5, isolator: 'C', study: 'II', treatment: 'control', donor: 'two'},\n            {subject: 6, weight: 18.1, isolator: 'C', study: 'II', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 19.3, isolator: 'B', study: 'IV', treatment: 'control', donor: 'two'},\n            {subject: 3, weight: 17.6, isolator: 'B', study: 'IV', treatment: 'control', donor: 'two'},\n            {subject: 6, weight: 17.4, isolator: 'B', study: 'IV', treatment: 'control', donor: 'two'},\n            {subject: 7, weight: 17.5, isolator: 'B', study: 'IV', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 16.7, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 4, weight: 18.2, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 7, weight: 16.8, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 8, weight: 16.9, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 11, weight: 16, isolator: 'A', study: 'V', treatment: 'control', donor: 'two'},\n            {subject: 1, weight: 18.8, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 2, weight: 15.8, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 9, weight: 21, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 11, weight: 18.5, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 14, weight: 17.3, isolator: 'E', study: 'I', treatment: 'control', donor: 'three'},\n            {subject: 4, weight: 18, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 8, weight: 19.4, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 12, weight: 18.8, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 15, weight: 18.8, isolator: 'D', study: 'I', treatment: 'control', donor: 'four'},\n            {subject: 1, weight: 18.3, isolator: 'C', study: 'III', treatment: 'control', donor: 'five'},\n            {subject: 17, weight: 19.8, isolator: 'C', study: 'III', treatment: 'control', donor: 'five'},\n            {subject: 18, weight: 18.5, isolator: 'C', study: 'III', treatment: 'control', donor: 'five'},\n            {subject: 2, weight: 18.2, isolator: 'C', study: 'III', treatment: 'control', donor: 'five'},\n            {subject: 8, weight: 17.4, isolator: 'C', study: 'III', treatment: 'control', donor: 'five'},\n            {subject: 5, weight: 20, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 6, weight: 17.2, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 8, weight: 20.7, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 17, weight: 17.8, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 19, weight: 17.5, isolator: 'C', study: 'I', treatment: 'control', donor: 'six'},\n            {subject: 10, weight: 19.3, isolator: 'B', study: 'III', treatment: 'control', donor: 'seven'},\n            {subject: 11, weight: 18.7, isolator: 'B', study: 'III', treatment: 'control', donor: 'seven'},\n            {subject: 4, weight: 18.9, isolator: 'B', study: 'III', treatment: 'control', donor: 'seven'},\n            {subject: 6, weight: 20.8, isolator: 'B', study: 'III', treatment: 'control', donor: 'seven'},\n            {subject: 7, weight: 19, isolator: 'B', study: 'III', treatment: 'control', donor: 'seven'},\n            {subject: 2, weight: 16.5, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 9, weight: 18.4, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 12, weight: 18.8, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 13, weight: 17.1, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 15, weight: 18.4, isolator: 'B', study: 'V', treatment: 'control', donor: 'seven'},\n            {subject: 1, weight: 18.5, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 2, weight: 18.9, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 10, weight: 20.1, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 11, weight: 19.3, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 14, weight: 18.6, isolator: 'B', study: 'I', treatment: 'control', donor: 'eight'},\n            {subject: 11, weight: 19.4, isolator: 'A', study: 'II', treatment: 'control', donor: 'eight'},\n            {subject: 14, weight: 19.3, isolator: 'A', study: 'II', treatment: 'control', donor: 'eight'},\n            {subject: 2, weight: 17.9, isolator: 'A', study: 'II', treatment: 'control', donor: 'eight'},\n            {subject: 3, weight: 18.1, isolator: 'A', study: 'II', treatment: 'control', donor: 'eight'},\n            {subject: 4, weight: 17.4, isolator: 'A', study: 'II', treatment: 'control', donor: 'eight'},\n            {subject: 4, weight: 17.8, isolator: 'A', study: 'IV', treatment: 'control', donor: 'eight'},\n            {subject: 9, weight: 17.2, isolator: 'A', study: 'IV', treatment: 'control', donor: 'eight'},\n            {subject: 12, weight: 16.4, isolator: 'A', study: 'IV', treatment: 'control', donor: 'eight'},\n            {subject: 13, weight: 17.9, isolator: 'A', study: 'IV', treatment: 'control', donor: 'eight'},\n            {subject: 17, weight: 19.9, isolator: 'A', study: 'IV', treatment: 'control', donor: 'eight'},\n            {subject: 12, weight: 18, isolator: 'A', study: 'III', treatment: 'control', donor: 'eight'},\n            {subject: 15, weight: 18.7, isolator: 'A', study: 'III', treatment: 'control', donor: 'eight'},\n            {subject: 2, weight: 19.6, isolator: 'A', study: 'III', treatment: 'control', donor: 'eight'},\n            {subject: 3, weight: 17.8, isolator: 'A', study: 'III', treatment: 'control', donor: 'eight'},\n            {subject: 9, weight: 18.3, isolator: 'A', study: 'III', treatment: 'control', donor: 'eight'},\n            {subject: 4, weight: 18.2, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 7, weight: 16.9, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 12, weight: 18.2, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 13, weight: 17.6, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 16, weight: 15.5, isolator: 'A', study: 'I', treatment: 'control', donor: 'nine'},\n            {subject: 1, weight: 17, isolator: 'B', study: 'II', treatment: 'control', donor: 'nine'},\n            {subject: 16, weight: 18.1, isolator: 'B', study: 'II', treatment: 'control', donor: 'nine'},\n            {subject: 17, weight: 18.3, isolator: 'B', study: 'II', treatment: 'control', donor: 'nine'},\n            {subject: 18, weight: 19.5, isolator: 'B', study: 'II', treatment: 'control', donor: 'nine'},\n            {subject: 5, weight: 18.3, isolator: 'B', study: 'II', treatment: 'control', donor: 'nine'},\n        ]\n\n        options =\n            x: (d)-> d.study\n            y: (d)-> d.weight\n            colorGroup: (d)-> d.donor\n            maxBoxWidth: false\n            plotType: 'box'\n            observationType: 'random'\n            whiskerDef: 'iqr'\n            notchBox: false\n            hideWhiskers: false\n            centralTendency: 'mean'\n            bandwidth: 'scott'\n            clampViolin: true\n            resolution: 50\n            showOnlyOutliers: true\n            jitter: 0.7\n            squash: false\n            pointSize: 4\n            margin:\n                top: 30\n                right: 60\n                bottom: 80\n                left: 10\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.distroPlotChart()\n            builder.build options, data\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n            builder.model.update()\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-distroPlot'\n            should.exist wrap[0]\n\n        it 'no data text', ->\n            builder = new ChartBuilder nv.models.distroPlotChart()\n            builder.build options, []\n\n            noData = builder.$ '.nv-noData'\n            noData[0].textContent.should.equal 'No Data Available.'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-wrap'\n            '.nv-distroWrap'\n            '.nv-distroplot-x-group'\n            '.nv-distroplot-whisker'\n            '.nv-distroplot-low'\n            '.nv-distroplot-tick'\n            '.nv-distroplot-high'\n            '.nv-distribution-area'\n            '.nv-distribution-left'\n            '.nv-distribution-right'\n            '.nv-distribution-line'\n            '.nv-distroplot-observation'\n            '.nv-distroplot-outlier'\n            '.nv-distroplot-non-outlier'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-distroPlot #{cssClass}\")[0]\n\n        it 'has all x groups', ->\n            groups = builder.$ '.nv-distroplot-x-group'\n            groups.should.have.length 17, 'groups exist'\n\n        it 'has all outliers', ->\n            groups = builder.$ '.nv-distroplot-outlier'\n            groups.should.have.length 11, 'outliers exist'\n"
  },
  {
    "path": "test/mocha/heatmap.coffee",
    "content": "describe 'NVD3', ->\n    describe 'heatMapChart', ->\n        data = [\n            {day: 'Mo', hour: 1, value: 16, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 2, value: 20, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 3, value: 0, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 4, value: 0, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 5, value: 0, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 6, value: 2, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 7, value: 0, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 8, value: 9, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 9, value: 25, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 10, value: 49, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 11, value: 57, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 12, value: 61, group: 84, category: 1, level: 1},\n            {day: 'Mo', hour: 13, value: 37, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 14, value: 66, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 15, value: 70, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 16, value: 55, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 17, value: 51, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 18, value: 55, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 19, value: 17, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 20, value: 20, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 21, value: 9, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 22, value: 4, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 23, value: 0, group: 84, category: 2, level: 1},\n            {day: 'Mo', hour: 24, value: 12, group: 84, category: 2, level: 1},\n            {day: 'Tu', hour: 1, value: 6, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 2, value: 2, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 3, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 4, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 5, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 6, value: 2, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 7, value: 4, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 8, value: 11, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 9, value: 28, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 10, value: 49, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 11, value: 51, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 12, value: 47, group: 13, category: 1, level: 1},\n            {day: 'Tu', hour: 13, value: 38, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 14, value: 65, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 15, value: 60, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 16, value: 50, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 17, value: 65, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 18, value: 50, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 19, value: 22, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 20, value: 11, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 21, value: 12, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 22, value: 9, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 23, value: 0, group: 13, category: 2, level: 1},\n            {day: 'Tu', hour: 24, value: 13, group: 13, category: 2, level: 1},\n            {day: 'We', hour: 1, value: 5, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 2, value: 8, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 3, value: 8, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 4, value: 0, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 5, value: 0, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 6, value: 2, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 7, value: 5, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 8, value: 12, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 9, value: 34, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 10, value: 43, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 11, value: 54, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 12, value: 44, group: 84, category: 1, level: 1},\n            {day: 'We', hour: 13, value: 40, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 14, value: 48, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 15, value: 54, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 16, value: 59, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 17, value: 60, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 18, value: 51, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 19, value: 21, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 20, value: 16, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 21, value: 9, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 22, value: 5, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 23, value: 4, group: 84, category: 2, level: 1},\n            {day: 'We', hour: 24, value: 7, group: 84, category: 2, level: 1},\n            {day: 'Th', hour: 1, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 2, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 3, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 4, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 5, value: 0, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 6, value: 2, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 7, value: 4, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 8, value: 13, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 9, value: 26, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 10, value: 58, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 11, value: 61, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 12, value: 59, group: 13, category: 1, level: 1},\n            {day: 'Th', hour: 13, value: 53, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 14, value: 54, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 15, value: 64, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 16, value: 55, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 17, value: 52, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 18, value: 53, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 19, value: 18, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 20, value: 3, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 21, value: 9, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 22, value: 12, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 23, value: 2, group: 13, category: 2, level: 1},\n            {day: 'Th', hour: 24, value: 8, group: 13, category: 2, level: 1},\n            {day: 'Fr', hour: 1, value: 2, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 2, value: 0, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 3, value: 8, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 4, value: 2, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 5, value: 0, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 6, value: 2, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 7, value: 4, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 8, value: 14, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 9, value: 31, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 10, value: 48, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 11, value: 46, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 12, value: 50, group: 53, category: 1, level: 1},\n            {day: 'Fr', hour: 13, value: 66, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 14, value: 54, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 15, value: 56, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 16, value: 67, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 17, value: 54, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 18, value: 23, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 19, value: 14, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 20, value: 6, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 21, value: 8, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 22, value: 7, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 23, value: 0, group: 53, category: 2, level: 1},\n            {day: 'Fr', hour: 24, value: 8, group: 53, category: 2, level: 1},\n            {day: 'Sa', hour: 1, value: 2, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 2, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 3, value: 2, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 4, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 5, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 6, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 7, value: 4, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 8, value: 8, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 9, value: 8, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 10, value: 6, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 11, value: 14, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 12, value: 12, group: 53, category: 1, level: 2},\n            {day: 'Sa', hour: 13, value: 9, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 14, value: 14, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 15, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 16, value: 4, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 17, value: 7, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 18, value: 6, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 19, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 20, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 21, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 22, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 23, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Sa', hour: 24, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 1, value: 7, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 2, value: 6, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 3, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 4, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 5, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 6, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 7, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 8, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 9, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 10, value: 0, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 11, value: 2, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 12, value: 2, group: 53, category: 1, level: 2},\n            {day: 'Su', hour: 13, value: 5, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 14, value: 6, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 15, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 16, value: 4, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 17, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 18, value: 2, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 19, value: 10, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 20, value: 7, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 21, value: 0, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 22, value: 19, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 23, value: 9, group: 53, category: 2, level: 2},\n            {day: 'Su', hour: 24, value: 4, group: 53, category: 2, level: 2},\n        ]\n\n\n        options =\n            x: (d)-> d.hour\n            y: (d)-> d.day\n            cellAspectRatio: 1\n            normalize: false\n            highContrastText: true\n            showXAxis: true\n            showYAxis: true\n            showLegend: true\n            showCellValues: true\n            alignXAxis: 'top'\n            alignYAxis: 'left'\n            cellValueFormat: d3.format(',.0f')\n            cellBorderWidth: 4\n            xMeta: (d)-> d.category\n            yMeta: (d)-> d.group\n            margin:\n                top: 30\n                right: 60\n                bottom: 80\n                left: 10\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.heatMapChart()\n            builder.build options, data\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n            builder.model.update()\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3-svg.nv-heatMap'\n            should.exist wrap[0]\n\n        it 'no data text', ->\n            builder = new ChartBuilder nv.models.heatMapChart()\n            builder.build options, []\n\n            noData = builder.$ '.nv-noData'\n            noData[0].textContent.should.equal 'No Data Available.'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-wrap'\n            '.nv-heatMap'\n            '.nv-heatMapWrap'\n            '.xMetaWrap'\n            '.nv-cell'\n            '.yMetaWrap'\n            '.meta'\n            '.x-meta'\n            '.y-meta'\n            '.nv-legendWrap'\n            '.nv-legend'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3 #{cssClass}\")[0]\n\n        it 'has all cells', ->\n            groups = builder.$ '.nv-cell'\n            groups.should.have.length 168, 'cells exist'\n\n        it 'has all x-meta', ->\n            groups = builder.$ '.x-meta'\n            groups.should.have.length 24, 'rects exist'\n\n        it 'has all y-meta', ->\n            groups = builder.$ '.y-meta'\n            groups.should.have.length 7, 'rects exist'\n"
  },
  {
    "path": "test/mocha/historical-bar.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Historical Bar Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n        options =\n            x: (d,i)-> i\n            y: (d)-> d[1]\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: nv.utils.defaultColor()\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            noData: 'No Data Available'\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.historicalBarChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-historicalBarChart'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.historicalBarChart()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-barsWrap'\n            '.nv-bars'\n            '.nv-legendWrap'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-historicalBarChart #{cssClass}\")[0]\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n"
  },
  {
    "path": "test/mocha/legend.coffee",
    "content": "describe 'NVD3', ->\n  describe 'Legend', ->\n    sampleData1 = [\n      {\"values\":[{\"x\":1,\"y\":2},{\"x\":3,\"y\":4},{\"x\":5,\"y\":6}],\"key\":\"key 1\"}\n      {\"values\":[{\"x\":7,\"y\":8},{\"x\":9,\"y\":10},{\"x\":11,\"y\":12}],\"key\":\"key 2\"}\n      {\"values\":[{\"x\":13,\"y\":14},{\"x\":15,\"y\":16},{\"x\":17,\"y\":18}],\"key\":\"key 3\"}\n    ]\n\n    sampleData2 = [\n      key: 'series 1'\n    ,\n      key: 'series 2'\n    ,\n      key: 'series 3'\n    ,\n      key: 'series 4'\n    ]\n\n    legendOptions =\n      margin:\n        top: 0\n        right: 0\n        bottom: 0\n        left: 0\n      width: 100\n      height: 100\n      key: (d) -> d.key\n      color: nv.utils.defaultColor()\n      align: true\n      rightAlign: false\n      updateState: true\n      radioButtonMode: false\n\n    builder = null\n    beforeEach ->\n      builder = new ChartBuilder nv.models.legend()\n      builder.build legendOptions, sampleData1\n\n      legend = builder.model\n      for opt, val of legendOptions\n        legend[opt](val)\n\n    afterEach ->\n      builder.teardown()\n\n    it 'api check', ->\n      legend = builder.model\n      for opt, val of legendOptions\n        should.exist legend[opt](), \"#{opt} can be called\"\n\n    it 'exists', ->\n      legend = builder.$('.nvd3.nv-legend')\n      should.exist legend[0], '.nvd3.nv-legend'\n\n    describe 'appends items correctly', ->\n      for item, i in sampleData1\n        do (item, i) ->\n          key = item.key\n          it \"'#{key}' text, position and structure\", ->\n\n            nvSeries = builder.$(\".nvd3.nv-legend .nv-series\")[i]\n            transformCalculated = \"translate(0,#{i*20+5})\"\n            transform = nvSeries.getAttribute 'transform'\n            transform.should.be.equal transformCalculated\n\n            nvLegendSymbol = nvSeries.querySelector('.nv-legend-symbol')\n            nvLegendText = nvSeries.querySelector('.nv-legend-text')\n\n            should.exist nvLegendSymbol\n            should.exist nvLegendText\n            nvLegendText.textContent.should.be.equal key\n\n    describe 'clicking and double clicking', ->\n      it 'clicking one legend turns it off', ->\n        legendItems = builder.$ '.nv-legend .nv-series'\n        legendItems.length.should.equal 3\n\n        clickFn = d3.select(legendItems[0]).on 'click'\n        clickFn(sampleData1[0])\n        sampleData1[0].disabled.should.equal true\n        clickFn(sampleData1[1])\n        sampleData1[1].disabled.should.equal true \n\n        clickFn(sampleData1[2])\n        sampleData1[0].disabled.should.equal false\n        sampleData1[1].disabled.should.equal false\n        sampleData1[2].disabled.should.equal false\n\n      it 'double clicking legend keeps only one on', ->\n        legendItems = builder.$ '.nv-legend .nv-series'\n\n        clickFn = d3.select(legendItems[0]).on 'dblclick'\n        clickFn(sampleData1[0])\n        sampleData1[0].disabled.should.equal false\n\n        sampleData1[1].disabled.should.equal true\n        sampleData1[2].disabled.should.equal true\n\n      it 'updating legend data does not break double click (issue 784)', ->\n        builder.updateData sampleData2\n\n        legendItems = builder.$ '.nv-legend .nv-series'\n\n        clickFn = d3.select(legendItems[0]).on 'dblclick'\n        clickFn(sampleData2[0])\n        sampleData2[0].disabled.should.equal false \n\n        sampleData2[1].disabled.should.equal true\n        sampleData2[2].disabled.should.equal true\n        sampleData2[3].disabled.should.equal true\n\n    it 'legend padding', ->\n      builder = new ChartBuilder nv.models.legend()\n      builder.build {padding: 40}, sampleData1\n\n      legendItems = builder.$ '.nv-legend .nv-series'\n      xSpacing = [0, 80, 160]\n      for legend,i in legendItems\n        transform = legend.getAttribute 'transform'\n        transform.should.equal \"translate(#{xSpacing[i]},5)\"\n"
  },
  {
    "path": "test/mocha/line.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Line Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n        sampleData2 = [\n            key: 'Series 1'\n            classed: 'dashed'\n            values: [\n                [-1,-3]\n                [0,6]\n                [1,12]\n                [2,18]\n            ]\n        ,\n            key: 'Series 2'\n            values: [\n                [-1,-4]\n                [0,7]\n                [1,13]\n                [2,14]\n            ]\n        ,\n            key: 'Series 3'\n            values: [\n                [-1,-5]\n                [0,7.2]\n                [1,11]\n                [2,18.5]\n            ]\n        ]\n\n        options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            color: nv.utils.defaultColor()\n            height: 400\n            width: 800\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: true\n            useInteractiveGuideline: true\n            noData: 'No Data Available'\n            duration: 0\n            clipEdge: false\n            isArea: (d)-> d.area\n            defined: (d)-> true\n            interpolate: 'linear'\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.lineChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n            builder.model.update()\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-lineChart'\n            should.exist wrap[0]\n\n        it 'no data text', ->\n            builder = new ChartBuilder nv.models.lineChart()\n            builder.build options, []\n\n            noData = builder.$ '.nv-noData'\n            noData[0].textContent.should.equal 'No Data Available'\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.lineChart()\n            builder.buildover options, sampleData1, []\n\n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-linesWrap'\n            '.nv-legendWrap'\n            '.nv-line'\n            '.nv-scatter'\n            '.nv-legend'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-lineChart #{cssClass}\")[0]\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n\n        it 'can add custom CSS class to series', ->\n            builder.updateData sampleData2\n\n            classed = builder.$ '.nv-linesWrap .nv-groups .nv-group.dashed'\n            \n            # Since classing has been implemented at the data-level for\n            # scatter points, there will actually be 2 elements matching\n            # the above selector, one for the scatter g element,\n            # and one for the line.\n            \n            classed.length.should.equal 2, 'dashed class exists'\n\n            scatter = builder.$ '.nv-scatterWrap .nv-groups .nv-group.dashed'\n            scatter.length.should.equal 1, 'one classed element is from scatter'\n\n        it 'shows focus chart when focusEnable is set to true', ->\n            builder.model.focusEnable(true).update();\n            focus = builder.$ '.nv-focusWrap .nv-focus'\n            should.exist focus[0]\n\n        it 'hides focus chart when focusEnable is set to false', ->\n            builder.model.focusEnable(true).update();\n            builder.model.focusEnable(false).update();\n            focusWrap = builder.$ '.nv-focusWrap'\n            focusWrap[0].style.display.should.equal 'none'\n\n        it 'does not reset selected focus range when focusEnable is set to false', ->\n            builder.model.focusEnable(true).update();\n            builder.model.brushExtent([0, 1]).update();\n            builder.model.focusEnable(false).update();\n            builder.model.brushExtent()[0].should.equal 0\n            builder.model.brushExtent()[1].should.equal 1\n\n"
  },
  {
    "path": "test/mocha/multibar-horizontal.coffee",
    "content": "describe 'NVD3', ->\n    describe 'MultiBar Horizontal Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                {label: 'America', value: 100}\n                {label: 'Europe', value: 200}\n                {label: 'Asia', value: 50}\n                {label: 'Africa', value: 70}\n            ]\n        ,\n            key: 'Series 2'\n            values: [\n                {label: 'America', value: 110}\n                {label: 'Europe', value: 230}\n                {label: 'Asia', value: 51}\n                {label: 'Africa', value: 78}\n            ]\n        ,\n            key: 'Series 3'\n            values: [\n                {label: 'America', value: 230}\n                {label: 'Europe', value: 280}\n                {label: 'Asia', value: 31}\n                {label: 'Africa', value: 13}\n            ]\n        ]\n\n        options =\n            x: (d)-> d.label\n            y: (d)-> d.value\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: nv.utils.defaultColor()\n            stacked: false\n            showControls: true\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            noData: 'No Data Available'\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.multiBarHorizontalChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-multiBarHorizontalChart'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.multiBarHorizontalChart()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n            cssClasses = [\n                '.nv-x.nv-axis'\n                '.nv-y.nv-axis'\n                '.nv-barsWrap'\n                '.nv-multibarHorizontal'\n                '.nv-legendWrap'\n                '.nv-controlsWrap'\n            ]\n            for cssClass in cssClasses\n                do (cssClass) ->\n                  should.exist builder.$(\"g.nvd3.nv-multiBarHorizontalChart #{cssClass}\")[0]\n\n        it 'renders bars', ->\n            bars = builder.$('g.nvd3.nv-multiBarHorizontalChart .nv-multibarHorizontal .nv-bar')\n            bars.should.have.length 12\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n"
  },
  {
    "path": "test/mocha/multibar.coffee",
    "content": "describe 'NVD3', ->\n    describe 'MultiBar Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                {label: 'America', value: 100}\n                {label: 'Europe', value: 200}\n                {label: 'Asia', value: 50}\n                {label: 'Africa', value: 70}\n            ]\n        ,\n            key: 'Series 2'\n            values: [\n                {label: 'America', value: 110}\n                {label: 'Europe', value: 230}\n                {label: 'Asia', value: 51}\n                {label: 'Africa', value: 78}\n            ]\n        ,\n            key: 'Series 3'\n            values: [\n                {label: 'America', value: 230}\n                {label: 'Europe', value: 280}\n                {label: 'Asia', value: 31}\n                {label: 'Africa', value: 13}\n            ]\n        ]\n\n        options =\n            x: (d)-> d.label\n            y: (d)-> d.value\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: nv.utils.defaultColor()\n            showControls: true\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            reduceXTicks: true\n            staggerLabels: true\n            rotateLabels: 0\n            noData: 'No Data Available'\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.multiBarChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-multiBarWithLegend'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.multiBarChart()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-barsWrap'\n            '.nv-multibar'\n            '.nv-legendWrap'\n            '.nv-controlsWrap'\n          ]\n\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-multiBarWithLegend #{cssClass}\")[0]\n\n        it 'renders bars', ->\n          bars = builder.$(\"g.nvd3.nv-multiBarWithLegend .nv-multibar .nv-bar\")\n          bars.should.have.length 12\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n\n        describe \"useInteractiveGuideline\", ->\n            it \"true\", ->\n              options.useInteractiveGuideline = true\n              builder.build options, sampleData1\n              builder.$(\".nv-multiBarWithLegend .nv-interactiveLineLayer\").should.have.length 1\n            it \"false\", ->\n              options.useInteractiveGuideline = false\n              builder.build options, sampleData1\n              builder.$(\".nv-multiBarWithLegend .nv-interactiveLineLayer\").should.have.length 0\n\n"
  },
  {
    "path": "test/mocha/pie.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Pie Chart', ->\n        sampleData1 = [\n            {label: 'America', value: 100}\n            {label: 'Europe', value: 200}\n            {label: 'Asia', value: 50}\n            {label: 'Africa', value: 70}\n        ]\n\n        options =\n            x: (d)-> d.label\n            y: (d)-> d.value\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: nv.utils.defaultColor()\n            showLegend: true\n            valueFormat: (d)-> d.toFixed 2\n            showLabels: true\n            labelsOutside: true\n            donut: false\n            donutRatio: 0.5\n            labelThreshold: 0.02\n            labelType: 'key'\n            noData: 'No Data Available'\n            duration: 0\n            startAngle: false\n            endAngle: false\n            padAngle: false\n            cornerRadius: 0\n            labelSunbeamLayout: false\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.pieChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        describe 'renders', ->\n\n            wrap = null\n            labels = null\n\n            beforeEach ->\n              wrap = builder.$ 'g.nvd3.nv-pieChart'\n              labels = wrap[0].querySelectorAll('.nv-label text')\n\n            it '.nv-pieChart', ->\n              should.exist wrap[0]\n\n            it 'can access margin', ->\n              builder.model.margin\n                top: 31\n                right: 21\n                bottom: 51\n                left: 76\n\n              m = builder.model.margin()\n              m.should.deep.equal \n                top: 31\n                right: 21\n                bottom: 51\n                left: 76\n\n            describe 'labels correctly', ->\n              it \"[#{sampleData1.length}] labels\", ->\n                wrap[0].querySelectorAll('.nv-label').should.have.length sampleData1.length\n\n              for item, i in sampleData1\n                do (item, i) ->\n                  it \"label '#{item.label}'\", ->\n                    item.label.should.be.equal labels[i].textContent\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.pieChart()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-pieWrap'\n            '.nv-pie'\n            '.nv-pieLabels'\n            '.nv-legendWrap'\n          ]\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-pieChart #{cssClass}\")[0]\n\n        it 'can handle donut mode and options', (done)->\n            builder.teardown()\n            options.donut = true\n            options.labelSunbeamLayout = true\n            options.startAngle = (d)-> d.startAngle/2 - Math.PI/2\n            options.endAngle = (d)-> d.endAngle/2 - Math.PI/2\n\n            builder.build options, sampleData1\n\n            done()\n\n        it 'can handle cornerRadius and padAngle options', (done)->\n            builder.teardown()\n            options.padAngle = 5\n            options.cornerRadius = 5\n\n            builder.build options, sampleData1\n            done() \n\n        it 'can render pie labels in other formats', ->\n            opts =\n                x: (d)-> d.label\n                y: (d)-> d.value\n                labelType: 'value'\n                valueFormat: d3.format('.2f')\n            builder2 = new ChartBuilder nv.models.pie()\n            builder2.build opts, [sampleData1]\n\n            labels = builder2.$ '.nv-pieLabels .nv-label text'\n            labels.length.should.equal 4\n\n            expected = ['100.00','200.00','50.00','70.00']\n            for label,i in labels \n                label.textContent.should.equal expected[i]\n\n            # Test labelType = 'percent'\n            builder2.teardown()\n\n            opts.labelType = 'percent'\n            opts.valueFormat = d3.format('%')\n            builder2.build opts, [sampleData1]\n\n            labels = builder2.$ '.nv-pieLabels .nv-label text'\n            labels.length.should.equal 4\n\n            expected = ['24%','48%','12%','17%']\n            for label,i in labels \n                label.textContent.should.equal expected[i]\n"
  },
  {
    "path": "test/mocha/sankey.coffee",
    "content": "describe 'NVD3', ->\n  describe 'Sankey Chart', ->\n    sampleData1 =\n      nodes:\n        [\n          {'node': 1, 'name': 'Test 1'}\n          {'node': 2, 'name': 'Test 2'}\n          {'node': 3, 'name': 'Test 3'}\n          {'node': 4, 'name': 'Test 4'}\n          {'node': 5, 'name': 'Test 5'}\n          {'node': 6, 'name': 'Test 6'}\n        ]\n      links:\n        [\n          {'source': 0, 'target': 1, 'value': 2295}\n          {'source': 0, 'target': 5, 'value': 1199}\n          {'source': 1, 'target': 2, 'value': 1119}\n          {'source': 1, 'target': 5, 'value': 1176}\n          {'source': 2, 'target': 3, 'value': 487}\n          {'source': 2, 'target': 5, 'value': 632}\n          {'source': 3, 'target': 4, 'value': 301}\n          {'source': 3, 'target': 5, 'value': 186}\n        ]\n\n\n    options =\n      margin:\n        top: 30\n        right: 20\n        bottom: 50\n        left: 75\n      width: 200\n      height: 200\n      units: 'test'\n      format: ->\n      linkTitle: -> 'link title test'\n      nodeWidth: 77\n      nodePadding: 10\n      nodeStyle:\n        nodeFillColor: -> '#f00'\n        nodeStrokeColor: -> '#00f'\n        nodeTitle: -> 'testing the title'\n\n    builder = null\n    beforeEach ->\n      builder = new ChartBuilder nv.models.sankeyChart()\n      builder.build options, sampleData1\n\n    afterEach ->\n      builder.teardown()\n\n    it 'api check', ->\n      should.exist builder.model.options, 'options exposed'\n      for opt of options\n        should.exist builder.model[opt](), \"#{opt} can be called\"\n\n    it 'renders', ->\n      wrap = builder.$ 'g.nvd3.nv-sankeyChart'\n      should.exist wrap[0]\n\n    it 'has correct structure', ->\n      cssClasses = [\n        '.node'\n        '.link'\n      ]\n\n      for cssClass in cssClasses\n        do (cssClass) ->\n          should.exist builder.$(\"g.nvd3.nv-sankeyChart #{cssClass}\")[0]\n\n    it 'renders nodes', ->\n      nodes = builder.$(\"g.nvd3.nv-sankeyChart .node\")\n      nodes.should.have.length 6\n\n    it 'nodes has the right width', ->\n      should.exist builder.$(\"g.nvd3.nv-sankeyChart .node rect[width]\")[0]\n      builder.$(\"g.nvd3.nv-sankeyChart .node rect[width]\")[0].width.animVal.value.should.equal 77\n\n    it 'renders links', ->\n      links = builder.$(\"g.nvd3.nv-sankeyChart .link\")\n      links.should.have.length 8\n\n    it 'link titles has the test text', ->\n      link = builder.$(\"g.nvd3.nv-sankeyChart .link title\")\n      link[0].textContent.should.equal 'link title test'\n"
  },
  {
    "path": "test/mocha/scatter.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Scatter Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            slope: 0.5\n            intercept: 0.2\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n        sampleData2 = [\n            key: 'Series 1'\n            values: [\n                [-1,-3]\n                [0,6]\n                [1,12]\n                [2,18]\n            ]\n        ,\n            key: 'Series 2'\n            values: [\n                [-1,-4]\n                [0,7]\n                [1,13]\n                [2,14]\n            ]\n        ]\n\n        options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n            margin:\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: nv.utils.defaultColor()\n            showDistX: true\n            showDistY: true\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            noData: 'No Data Available'\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.scatterChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt], \"#{opt} exists\"\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-scatterChart'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.scatterChart()\n            builder.buildover options, sampleData1, []\n\n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-background'\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-scatterWrap'\n            '.nv-distWrap'\n            '.nv-legendWrap'\n          ]\n\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-scatterChart #{cssClass}\")[0]\n\n        it 'has data points', ->\n            points = builder.$ '.nv-groups .nv-series-0 .nv-point'\n            points.should.have.length 4\n\n        it 'has a legend', ->\n            legend = builder.$ '.nv-legendWrap'\n            should.exist legend, 'legend exists'\n\n        it 'shows no data message', ->\n            builder.teardown()\n            builder.build options, []\n\n            noData = builder.$ 'text.nv-noData'\n            should.exist noData[0]\n            noData[0].textContent.should.equal 'No Data Available'\n\n        it 'can update with new data', ->\n            d3.select(builder.svg).datum(sampleData2)\n            builder.model.update()\n\n            points1 = builder.$ '.nv-groups .nv-series-0 .nv-point'\n            points1.should.have.length 4\n\n            points2 = builder.$ '.nv-groups .nv-series-1 .nv-point'\n            points2.should.have.length 4\n\n        it 'scatterPlusLineChart', ->\n            builder.teardown()\n            sampleData3 = [\n                key: 'Series 1'\n                values: [\n                    [-1,-3]\n                    [0,6]\n                    [1,12]\n                    [2,18]\n                ]\n                slope: 0.1\n                inercept: 5\n            ]\n\n            builder.build options, sampleData3\n\n            wrap = builder.$ 'g.nvd3.nv-scatterChart'\n            should.exist wrap[0]\n\n            lines = builder.$ 'g.nvd3 .nv-regressionLinesWrap .nv-regLines'\n            should.exist lines[0], 'regression lines exist'\n\n        it 'sets legend.width same as availableWidth', ->\n            builder.model.legend.width()\n            .should.equal builder.model.scatter.width()\n\n        it 'translates nv-wrap after legend height calculated', ->\n            builder.teardown()\n            sampleData4 = []\n            for i in [0..40]\n                sampleData4.push\n                    key: \"Series #{i}\"\n                    values: [\n                        [Math.random(),Math.random()]\n                    ]\n\n            builder.build options, sampleData4\n\n            transform = builder.$('.nv-wrap')[0].getAttribute('transform')\n            transform.should.equal 'translate(75,830)'\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n\n        it 'only appends one nv-point-clips group', (done)->\n            builder2 = new ChartBuilder nv.models.scatterChart()\n\n            builder2.build options, sampleData1\n\n            window.setTimeout ->\n                builder2.model.update()\n                window.setTimeout((->\n                    pointClips = builder2.svg.querySelector '.nv-point-clips'\n                    should.exist pointClips, 'nv-point-clips exists'\n\n                    builder2.svg.querySelector('.nv-wrap.nv-scatter')\n                    .childElementCount.should.equal 3\n\n                    builder2.teardown()\n                    done()\n                ), 500)\n\n            , 500\n\n        it 'sets nv-single-point class if only one data point', ->\n            builder.teardown()\n\n            singleData = [\n                key: 'Series1'\n                values: [\n                    [1,1]\n                ]\n            ]\n\n            builder.build options, singleData\n\n            builder.svg.querySelector('.nv-wrap.nv-scatter')\n            .className.should.contain 'nv-single-point'\n\n            builder.updateData sampleData1\n\n            builder.svg.querySelector('.nv-wrap.nv-scatter')\n            .className.should.not.contain 'nv-single-point'\n\n            builder.updateData singleData\n\n            builder.svg.querySelector('.nv-wrap.nv-scatter')\n            .className.should.contain 'nv-single-point'\n\n        it 'should set color property if not specified', ->\n            builder.teardown()\n\n            singleData = [\n                key: 'Series1'\n                values: [\n                  [1,1]\n                ]\n            ]\n\n            builder.build options, singleData\n\n            should.exist singleData[0].color\n"
  },
  {
    "path": "test/mocha/sparkline.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Sparkline Chart', ->\n        sampleData1 = [\n            {x: 1, y: 100}\n            {x: 2, y: 101}\n            {x: 3, y: 99}\n            {x: 4, y: 56}\n            {x: 5, y: 87}\n        ]\n\n        options =\n            x: (d)-> d.x\n            y: (d)-> d.y\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 50\n            xTickFormat: (d)-> d\n            yTickFormat: (d)-> d.toFixed 2\n            showLastValue: true\n            alignValue: true\n            rightAlignValue: false\n            noData: 'No Data Available'\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.sparklinePlus()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.sparklinePlus()\n            builder.buildover options, sampleData1, []\n            \n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-sparklineplus'\n            should.exist wrap[0]\n\n\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-sparklineWrap'\n            '.nv-sparkline'\n            '.nv-minValue'\n            '.nv-maxValue'\n            '.nv-currentValue'\n            '.nv-valueWrap'\n          ]\n          for cssClass in cssClasses\n            do(cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-sparklineplus #{cssClass}\")[0]"
  },
  {
    "path": "test/mocha/stacked.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Stacked Area Chart', ->\n        sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n        sampleData2 = [\n            key: 'Series 1'\n            values: [\n                [-1,-3]\n                [0,6]\n                [1,12]\n                [2,18]\n            ]\n        ,\n            key: 'Series 2'\n            values: [\n                [-1,-4]\n                [0,7]\n                [1,13]\n                [2,14]\n            ]\n        ]\n\n        options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            color: nv.utils.defaultColor()\n            showLegend: true\n            showControls: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: false\n            useInteractiveGuideline: true\n            noData: 'No Data Available'\n            duration: 0\n            controlLabels:\n                stacked: 'Stacked'\n                stream: 'Stream'\n                expanded: 'Expanded'\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.stackedAreaChart()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        it 'renders', ->\n            wrap = builder.$ 'g.nvd3.nv-stackedAreaChart'\n            should.exist wrap[0]\n\n        it 'clears chart objects for no data', ->\n            builder = new ChartBuilder nv.models.stackedAreaChart()\n            builder.buildover options, sampleData1, []\n\n            groups = builder.$ 'g'\n            groups.length.should.equal 0, 'removes chart components'\n\n        it 'has correct structure', ->\n          cssClasses = [\n            '.nv-x.nv-axis'\n            '.nv-y.nv-axis'\n            '.nv-stackedWrap'\n            '.nv-legendWrap'\n            '.nv-controlsWrap'\n            '.nv-interactive'\n          ]\n\n          for cssClass in cssClasses\n            do (cssClass) ->\n              should.exist builder.$(\"g.nvd3.nv-stackedAreaChart #{cssClass}\")[0]\n\n        it 'formats y-Axis correctly depending on stacked style', ->\n            chart = nv.models.stackedAreaChart()\n            chart.yAxis.tickFormat (d)-> \"<#{d}>\"\n\n            builder = new ChartBuilder chart\n            builder.build options, sampleData1\n\n            yTicks = builder.$ '.nv-y.nv-axis .tick text'\n            yTicks.should.have.length.greaterThan 2\n\n            for tick in yTicks\n                tick.textContent.should.match /<.*?>/\n\n            # Update chart to 'Expand' mode\n            chart.dispatch.changeState\n                style: 'expand'\n\n            chart.stacked.style().should.equal 'expand'\n            newTickFormat = chart.yAxis.tickFormat()\n            newTickFormat(1).should.equal '100%'\n\n            chart.dispatch.changeState\n                style: 'stacked'\n\n            chart.stacked.style().should.equal 'stacked'\n            newTickFormat = chart.yAxis.tickFormat()\n            newTickFormat(1).should.equal '<1>'\n\n        it 'can override axis ticks', ->\n            builder.model.xAxis.ticks(34)\n            builder.model.yAxis.ticks(56)\n            builder.model.update()\n            builder.model.xAxis.ticks().should.equal 34\n            builder.model.yAxis.ticks().should.equal 56\n\n        it 'if stacked.offset is \"wiggle\", y ticks is zero', ->\n            builder.model.stacked.offset 'wiggle'\n            builder.model.update()\n            builder.model.yAxis.ticks().should.equal 0\n\n        it 'should allow stream-center to be used', ->\n            builder.model.controlOptions(['Stream_Center'])\n            builder.model.update()\n            builder.model.controls.dispatch.legendClick({\n              style: 'stream-center',\n              disabled: true\n            })\n            builder.model.style().should.equal 'stream-center'\n\n        it 'should set color property if not specified', ->\n            sampleData3 = [\n              key: 'Series 1'\n              values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n              ]\n            ]\n            builder.build options, sampleData3\n            should.exist sampleData3[0].color\n"
  },
  {
    "path": "test/mocha/sunburst.coffee",
    "content": "describe 'NVD3', ->\n    describe 'Sunburst', ->\n        sampleData1 = [{\n            \"name\": \"flare\",\n            \"children\": [\n                {\n                    \"name\": \"analytics\",\n                    \"children\": [\n                        {\n                            \"name\": \"cluster\",\n                            \"children\": [\n                                {\"name\": \"AgglomerativeCluster\", \"size\": 3938},\n                                {\"name\": \"CommunityStructure\", \"size\": 3812},\n                                {\"name\": \"HierarchicalCluster\", \"size\": 6714},\n                                {\"name\": \"MergeEdge\", \"size\": 743}\n                            ]\n                        },\n                        {\n                            \"name\": \"graph\",\n                            \"children\": [\n                                {\"name\": \"BetweennessCentrality\", \"size\": 3534},\n                                {\"name\": \"LinkDistance\", \"size\": 5731},\n                                {\"name\": \"MaxFlowMinCut\", \"size\": 7840},\n                                {\"name\": \"ShortestPaths\", \"size\": 5914},\n                                {\"name\": \"SpanningTree\", \"size\": 3416}\n                            ]\n                        },\n                        {\n                            \"name\": \"optimization\",\n                            \"children\": [\n                                {\"name\": \"AspectRatioBanker\", \"size\": 7074}\n                            ]\n                        }\n                    ]\n                },\n                {\n                    \"name\": \"physics\",\n                    \"children\": [\n                        {\"name\": \"DragForce\", \"size\": 1082},\n                        {\"name\": \"GravityForce\", \"size\": 1336},\n                        {\"name\": \"IForce\", \"size\": 319},\n                        {\"name\": \"NBodyForce\", \"size\": 10498},\n                        {\"name\": \"Particle\", \"size\": 2822},\n                        {\"name\": \"Simulation\", \"size\": 9983},\n                        {\"name\": \"Spring\", \"size\": 2213},\n                        {\"name\": \"SpringForce\", \"size\": 1681}\n                    ]\n                },\n                {\n                    \"name\": \"vis\",\n                    \"children\": [\n                        {\n                            \"name\": \"data\",\n                            \"children\": [\n                                {\"name\": \"Data\", \"size\": 20544},\n                                {\"name\": \"DataList\", \"size\": 19788},\n                                {\"name\": \"DataSprite\", \"size\": 10349},\n                                {\"name\": \"EdgeSprite\", \"size\": 3301},\n                                {\"name\": \"NodeSprite\", \"size\": 19382},\n                                {\n                                    \"name\": \"render\",\n                                    \"children\": [\n                                        {\"name\": \"ArrowType\", \"size\": 698},\n                                        {\"name\": \"EdgeRenderer\", \"size\": 5569},\n                                        {\"name\": \"IRenderer\", \"size\": 353},\n                                        {\"name\": \"ShapeRenderer\", \"size\": 2247}\n                                    ]\n                                },\n                                {\"name\": \"ScaleBinding\", \"size\": 11275},\n                                {\"name\": \"Tree\", \"size\": 7147},\n                                {\"name\": \"TreeBuilder\", \"size\": 9930}\n                            ]\n                        },\n                        {\n                            \"name\": \"operator\",\n                            \"children\": [\n                                {\n                                    \"name\": \"distortion\",\n                                    \"children\": [\n                                        {\"name\": \"BifocalDistortion\", \"size\": 4461},\n                                        {\"name\": \"Distortion\", \"size\": 6314},\n                                        {\"name\": \"FisheyeDistortion\", \"size\": 3444}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"encoder\",\n                                    \"children\": [\n                                        {\"name\": \"ColorEncoder\", \"size\": 3179},\n                                        {\"name\": \"Encoder\", \"size\": 4060},\n                                        {\"name\": \"PropertyEncoder\", \"size\": 4138},\n                                        {\"name\": \"ShapeEncoder\", \"size\": 1690},\n                                        {\"name\": \"SizeEncoder\", \"size\": 1830}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"filter\",\n                                    \"children\": [\n                                        {\"name\": \"FisheyeTreeFilter\", \"size\": 5219},\n                                        {\"name\": \"GraphDistanceFilter\", \"size\": 3165},\n                                        {\"name\": \"VisibilityFilter\", \"size\": 3509}\n                                    ]\n                                },\n                                {\"name\": \"IOperator\", \"size\": 1286},\n                                {\n                                    \"name\": \"label\",\n                                    \"children\": [\n                                        {\"name\": \"Labeler\", \"size\": 9956},\n                                        {\"name\": \"RadialLabeler\", \"size\": 3899},\n                                        {\"name\": \"StackedAreaLabeler\", \"size\": 3202}\n                                    ]\n                                },\n                                {\n                                    \"name\": \"layout\",\n                                    \"children\": [\n                                        {\"name\": \"AxisLayout\", \"size\": 6725},\n                                        {\"name\": \"BundledEdgeRouter\", \"size\": 3727},\n                                        {\"name\": \"CircleLayout\", \"size\": 9317},\n                                        {\"name\": \"CirclePackingLayout\", \"size\": 12003},\n                                        {\"name\": \"DendrogramLayout\", \"size\": 4853},\n                                        {\"name\": \"ForceDirectedLayout\", \"size\": 8411},\n                                        {\"name\": \"IcicleTreeLayout\", \"size\": 4864},\n                                        {\"name\": \"IndentedTreeLayout\", \"size\": 3174},\n                                        {\"name\": \"Layout\", \"size\": 7881},\n                                        {\"name\": \"NodeLinkTreeLayout\", \"size\": 12870},\n                                        {\"name\": \"PieLayout\", \"size\": 2728},\n                                        {\"name\": \"RadialTreeLayout\", \"size\": 12348},\n                                        {\"name\": \"RandomLayout\", \"size\": 870},\n                                        {\"name\": \"StackedAreaLayout\", \"size\": 9121},\n                                        {\"name\": \"TreeMapLayout\", \"size\": 9191}\n                                    ]\n                                },\n                                {\"name\": \"Operator\", \"size\": 2490},\n                                {\"name\": \"OperatorList\", \"size\": 5248},\n                                {\"name\": \"OperatorSequence\", \"size\": 4190},\n                                {\"name\": \"OperatorSwitch\", \"size\": 2581},\n                                {\"name\": \"SortOperator\", \"size\": 2023}\n                            ]\n                        },\n                        {\"name\": \"Visualization\", \"size\": 16540}\n                    ]\n                }\n            ]\n        }]\n\n        options =\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            width: 200\n            height: 200\n            color: d3.scale.category20c()\n            duration: 0\n\n        builder = null\n        beforeEach ->\n            builder = new ChartBuilder nv.models.sunburst()\n            builder.build options, sampleData1\n\n        afterEach ->\n            builder.teardown()\n\n        it 'api check', ->\n            should.exist builder.model.options, 'options exposed'\n            for opt of options\n                should.exist builder.model[opt](), \"#{opt} can be called\"\n\n        describe 'renders', ->\n\n            wrap = null\n\n            beforeEach ->\n              wrap = builder.$ 'g.nvd3.nv-sunburst'\n\n            it '.nv-pieChart', ->\n              should.exist wrap[0]\n\n            it 'can access margin', ->\n              builder.model.margin\n                top: 31\n                right: 21\n                bottom: 51\n                left: 76\n\n              m = builder.model.margin()\n              m.should.deep.equal \n                top: 31\n                right: 21\n                bottom: 51\n                left: 76\n"
  },
  {
    "path": "test/mocha/test-utils.coffee",
    "content": "###\nUtility to build an NVD3 chart.\n###\nclass ChartBuilder\n    # @model should be something like nv.models.scatterChart()\n    constructor: (@model)->\n\n    ###\n    options: an object hash of chart options.\n    data: sample data to pass in to chart.\n\n    This method builds a chart and puts it on the <body> element.\n    ###\n    build: (options, data)->\n        @svg = document.createElement 'svg'\n        document.querySelector('body').appendChild @svg\n\n        for opt, val of options\n            unless @model[opt]?\n                console.warn \"#{opt} not property of model.\"\n            else\n                @model[opt](val)\n\n        @updateData data\n\n    ###\n    Update the data while preserving the chart model.\n    ###\n    updateData: (data)->\n        d3.select(@svg).datum(data).call(@model)\n\n    ###\n    options: an object hash of chart options.\n    data: sample data to pass in to initial chart render chart\n    data2: sample data to pass to second chart render\n\n    This method builds a chart, puts it on the <body> element, and then rebuilds using the second set of data\n    Useful for testing the results of transitioning and the 'noData' state after a chart has had data\n    ###\n    buildover: (options, data, data2)->\n        @svg = document.createElement 'svg'\n        document.querySelector('body').appendChild @svg\n\n        for opt, val of options\n            unless @model[opt]?\n                console.warn \"#{opt} not property of model.\"\n            else\n                @model[opt](val)\n\n        #Set initial data\n        chart = d3.select(@svg)\n        chart.datum(data)\n            .call(@model)\n\n        #Reset the data\n        chart.datum(data2)\n            .call(@model)\n\n\n\n    # Removes chart from <body> element.\n    teardown: ->\n        if @svg?\n            document.querySelector('body').removeChild @svg\n\n    # Runs a simple CSS selector to retrieve elements\n    $: (cssSelector)->\n        @svg.querySelectorAll cssSelector\n"
  },
  {
    "path": "test/mocha/utils.coffee",
    "content": "describe 'NVD3', ->\n  describe 'Utils', ->\n    objects = [\n      'nv.utils.windowSize'\n      'nv.utils.windowResize'\n      'nv.utils.getColor'\n      'nv.utils.defaultColor'\n      'nv.utils.customTheme'\n      'nv.utils.pjax'\n      'nv.utils.calcApproxTextWidth'\n      'nv.utils.NaNtoZero'\n      'nv.utils.renderWatch'\n      'nv.utils.deepExtend'\n      'nv.utils.state'\n      'nv.utils.optionsFunc'\n      'nv.utils.sanitizeHeight'\n      'nv.utils.sanitizeWidth'\n      'nv.utils.availableHeight'\n      'nv.utils.availableWidth'\n      'nv.utils.noData'\n    ]\n\n    describe 'has ', ->\n      for obj in objects\n        it \" #{obj} object\", ->\n          should.exist eval obj\n\n    it 'has working nv.utils.NaNtoZero function', ->\n      nv.utils.NaNtoZero().should.be.equal 0\n      nv.utils.NaNtoZero(undefined ).should.be.equal 0\n      nv.utils.NaNtoZero(NaN).should.be.equal 0\n      nv.utils.NaNtoZero(null).should.be.equal 0\n      nv.utils.NaNtoZero(Infinity).should.be.equal 0\n      nv.utils.NaNtoZero(-Infinity).should.be.equal 0\n      nv.utils.NaNtoZero(1).should.be.equal 1\n      nv.utils.NaNtoZero(0).should.be.equal 0\n      nv.utils.NaNtoZero(-1).should.be.equal -1\n\n    it 'should return a function if passing a function into nv.utils.getColor', ->\n      uno = (d,i) -> 1\n      nv.utils.getColor(uno).should.be.equal uno\n\n    it 'should return a function wrapping an array if passing an array into nv.utils.getColor', ->\n      arr = ['#fff', '#ccc', '#aaa', '#000']\n      returnedFunction = nv.utils.getColor(arr)\n\n      returnedFunction({},0).should.be.equal '#fff'\n      returnedFunction({},1).should.be.equal '#ccc'\n      returnedFunction({},2).should.be.equal '#aaa'\n      returnedFunction({},3).should.be.equal '#000'\n\n  createCont = (wh = false)->\n    obj = document.createElement('div')\n    obj.style.cssText = 'width:964px;height:404px' if wh\n    d3.select(obj)\n\n  describe 'Sanitize Height and Width for a Container', ->\n    it 'provides default height and width', ->\n      cont = createCont()\n      expect(nv.utils.sanitizeHeight(null, cont)).to.equal 400\n      expect(nv.utils.sanitizeWidth(null, cont)).to.equal 960\n      expect(nv.utils.sanitizeHeight(undefined, cont)).to.equal 400\n      expect(nv.utils.sanitizeWidth(undefined, cont)).to.equal 960\n      expect(nv.utils.sanitizeHeight(0, cont)).to.equal 400\n      expect(nv.utils.sanitizeWidth(0, cont)).to.equal 960\n    it 'uses container width and height', ->\n      cont = createCont(true)\n      expect(nv.utils.sanitizeHeight(null, cont)).to.equal 404\n      expect(nv.utils.sanitizeWidth(null, cont)).to.equal 964\n    it 'uses given width and height', ->\n      cont = createCont(true)\n      expect(nv.utils.sanitizeHeight(408, cont)).to.equal 408\n      expect(nv.utils.sanitizeWidth(968, cont)).to.equal 968\n\n  describe 'Available Container Height and Width', ->\n    it 'calculates height and width properly', ->\n      cont = createCont(true)\n      m = { left: 5, right: 6, top: 7, bottom: 8 }\n      expect(nv.utils.availableHeight(300, cont, m)).to.equal 285\n      expect(nv.utils.availableWidth(300, cont, m)).to.equal 289\n      expect(nv.utils.availableHeight(0, cont, m)).to.equal 389\n      expect(nv.utils.availableWidth(0, cont, m)).to.equal 953\n\n  describe 'Interactive Bisect', ->\n    it 'works with no accessor', ->\n      list = [{ x:0 },{ x:1 },{ x:1 },{ x:2 },{ x:3 },{ x:5 },{ x:8 },{ x:13 },{ x:21 },{ x:34 }]\n      expect(nv.interactiveBisect(list,7)).to.equal 6\n\n    runTest = (list, searchVal, accessor = null)->\n      xAcc = unless accessor?\n        (d)-> d\n      else\n        accessor\n\n      nv.interactiveBisect list, searchVal, xAcc\n\n    it 'exists', ->\n      expect(nv.interactiveBisect).to.exist\n\n    it 'returns null when no array', ->\n      expect(nv.interactiveBisect('bad', 'a')).to.equal null\n\n    it 'basic test', ->\n      expect(runTest([0,1,2,3,4,5], 3)).to.equal 3\n\n    it 'zero bound', ->\n      expect(runTest([0,1,2,3,4,5], 0)).to.equal 0\n\n    it 'length bound', ->\n      expect(runTest([0,1,2,3,4,5], 5)).to.equal 5\n\n    it 'negative number', ->\n      expect(runTest([0,1,2,3,4,5], -4)).to.equal 0\n\n    it 'past the end', ->\n      expect(runTest([0,1,2,3,4,5], 10)).to.equal 5\n\n    it 'floating point number 1', ->\n      expect(runTest([0,1,2,3,4,5], 0.34)).to.equal 0\n\n    it 'floating point number 2', ->\n      expect(runTest([0,1,2,3,4,5], 1.50001)).to.equal 2\n\n    it 'fibonacci - existing', ->\n      list = [0,1,1,2,3,5,8,13,21,34]\n      expect(runTest(list,8)).to.equal 6\n\n    it 'fibonacci - inbetween item (left)', ->\n      list = [0,1,1,2,3,5,8,13,21,34]\n      expect(runTest(list,15)).to.equal 7\n\n    it 'fibonacci - inbetween item (right)', ->\n      list = [0,1,1,2,3,5,8,13,21,34]\n      expect(runTest(list,20)).to.equal 8\n\n    it 'empty array', ->\n      expect(runTest([],4)).to.equal 0\n\n    it 'single element array', ->\n      expect(runTest([0],0)).to.equal 0\n\n    it 'single element array - negative bound', ->\n      expect(runTest([0],-4)).to.equal 0\n\n    it 'single element array - past the end', ->\n      expect(runTest([0],1)).to.equal 0\n\n  describe 'NoData Chart Clearing', ->\n    sampleData1 = [\n            key: 'Series 1'\n            values: [\n                [-1,-1]\n                [0,0]\n                [1,1]\n                [2,2]\n            ]\n        ]\n\n    options =\n            x: (d)-> d[0]\n            y: (d)-> d[1]\n            margin:\n                top: 30\n                right: 20\n                bottom: 50\n                left: 75\n            color: nv.utils.defaultColor()\n            height: 400\n            width: 800\n            showLegend: true\n            showXAxis: true\n            showYAxis: true\n            rightAlignYAxis: true\n            useInteractiveGuideline: true\n            noData: 'No Data Available'\n            duration: 0\n            clipEdge: false\n            isArea: (d)-> d.area\n            defined: (d)-> true\n            interpolate: 'linear'\n\n    it 'shows no data text', ->\n            builder = new ChartBuilder nv.models.lineChart()\n            builder.build options, []\n\n            noData = builder.$ '.nv-noData'\n            noData[0].textContent.should.equal 'No Data Available'\n\n    it 'clears chart objects for no data', ->\n        builder = new ChartBuilder nv.models.lineChart()\n        builder.buildover options, sampleData1, []\n        \n        groups = builder.$ 'g'\n        groups.length.should.equal 0, 'removes chart components'\n"
  },
  {
    "path": "test/multiBarChartTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n<body class='with-3d-shadow with-transitions'>\n  <h3>Multibar chart test cases - feel free to add more tests</h3>\n  <div class='chart third' id=\"chart1\">\n    Transition delay 1200ms, 0 non-stackable series and bar color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart2\">\n    No transitionDuration or delay, 0 non-stackable series and no bar color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart2-2\">\n    No transitionDuration or delay, 1 non-stackable series and no bar color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart3\">\n    TransitionDuration or delay 500ms, 1 non-stackable series(first) and color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart3-2\">\n    TransitionDuration or delay 500ms, 1 non-stackable series(mid) and color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart3-3\">\n    TransitionDuration or delay 500ms, 1 non-stackable series(last) and color set.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart4\">\n    Chart with single series, no group spacing.\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart5\">\n    Chart with 1 data point\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart6\">\n    Chart with 2 data points\n    <svg></svg>\n  </div>\n\n  <div class='chart full' id=\"chart7\">\n    Chart with 18 series, 7 data points per series and no non-stackable series.\n    <svg></svg>\n  </div>\n  \n  <div class='chart third' id=\"chart8\">\n    Chart with no stackable series -> same as grouped graphs\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart9\">\n    Chart with multi stackable series\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart9-1\">\n    Chart with multi more non stackable series\n    <svg></svg>\n  </div>\n  <div class='chart third' id=\"chart10\">\n    Chart with 0 data points\n    <svg></svg>\n  </div>\n\n<script>\n\n\nvar negative_test_data = new d3.range(0,4).map(function(d,i) { \n  var series = {};\n  return {\n    key: 'Stream ' + i,\n    values: new d3.range(0,11).map( function(f,j) {\n      return {\n         y: 10 + Math.random()*100 * (Math.floor(Math.random()*100)%2 ? 1 : -1),\n         x: j\n       }\n    })\n  };\n});\n\nfunction dataFactory(seriesNum, perSeries, color) {\n  return new d3.range(0,seriesNum).map(function(d,i) { \n    return {\n      key: 'Stream Data ' + i,\n      color: color||null,\n      values: new d3.range(0,perSeries).map( function(f,j) {\n        return {\n           y: 10 + Math.random()*100,\n           x: j\n         }\n      })\n    };\n  });\n}\n\nfunction dataFactoryNoStackable(seriesNum, perSeries, color) {\n   return new d3.range(0,seriesNum).map(function(d,i) { \n    var series = {\n      key: 'Non-stackable Stream Data ' + i,\n      nonStackable: true,\n      values: new d3.range(0,perSeries).map( function(f,j) {\n        return {\n           y: 10 + Math.random()*100,\n           x: j\n         }\n      })\n    };\n    return series;\n  });\n}\n\nfunction dataFactoryWithStackable(seriesNum, perSeries, color, nonStackableCount) {\n return new d3.range(0,seriesNum).map(function(d,i) { \n    var series = {};\n    if (i < (seriesNum - nonStackableCount)) {\n      series = {\n        key: 'Stream ' + i,\n        nonStackable: false\n      };\n    } else {\n      series = {\n        color: color||null,\n        key: 'Non-stackable Stream Data ' + i,\n        nonStackable: true\n      };\n    }\n    series.values = new d3.range(0,perSeries).map( function(f,j) {\n      return {\n         y: 10 + Math.random()*100,\n         x: j\n       }\n    });\n    return series;\n  });\n}\nfunction dataFactoryWithCustomNonStackablePosition(seriesNum, perSeries, color,\n  nonStackablePosition) {\n  var colors = ['red', 'green', 'blue'];\n  nonStackablePosition = nonStackablePosition ? nonStackablePosition: 0;\n  return new d3.range(0,seriesNum).map(function(d,i) { \n    var series = {\n      key: nonStackablePosition === i ? 'Non-stackable Stream ' + i: 'Stream ' + i,\n      nonStackable: nonStackablePosition === i,\n      color: nonStackablePosition === i ? color: colors[i]\n    };\n    series.values = new d3.range(0,perSeries).map( function(f,j) {\n      return {\n         y: 10 + Math.random()*100,\n         x: j\n       }\n    });\n    return series;\n  });\n}\n\n\ndefaultChartConfig(\"chart1\", negative_test_data, {\n  barColor: d3.scale.category20().range(),\n  delay: 1200,\n  groupSpacing: 0.1,\n  reduceXTicks: false,\n  staggerLabels: true\n});\n\ndefaultChartConfig(\"chart2\", dataFactory(3,11), {\n  delay: 0,\n  duration:0,\n  groupSpacing: 0.2\n});\n\ndefaultChartConfig(\"chart2-2\", dataFactoryWithStackable(3,11,null,1), {\n  delay: 0,\n  duration:0,\n  groupSpacing: 0.2\n});\n\ndefaultChartConfig(\"chart3\", dataFactoryWithCustomNonStackablePosition(3,11,'gray', 0), {\n  delay: 500,\n  groupSpacing: 0.2\n});\n\ndefaultChartConfig(\"chart3-2\", dataFactoryWithCustomNonStackablePosition(3,11,'gray', 1), {\n  delay: 500,\n  groupSpacing: 0.2\n});\n\ndefaultChartConfig(\"chart3-3\", dataFactoryWithCustomNonStackablePosition(3,11,'gray', 2), {\n  delay: 500,\n  groupSpacing: 0.2\n});\n\ndefaultChartConfig(\"chart4\",dataFactoryWithStackable(1,15),{\n  groupSpacing: 0,\n  delay:0\n});\n\ndefaultChartConfig(\"chart5\",dataFactory(1,1),{\n  delay:0\n});\n\ndefaultChartConfig(\"chart6\",dataFactory(1,2),{\n  delay:0\n});\n\ndefaultChartConfig(\"chart7\",dataFactory(18,7),{\n  delay:800\n});\n\ndefaultChartConfig(\"chart8\",dataFactoryNoStackable(3,11),{\n  delay:0\n});\n\ndefaultChartConfig(\"chart9\",dataFactoryWithStackable(5,8,null,2),{\n  delay:0\n});\ndefaultChartConfig(\"chart9-1\",dataFactoryWithStackable(5,8,null,3),{\n  delay:0\n});\n\ndefaultChartConfig(\"chart10\",dataFactory(0,0),{\n  delay:0\n});\n\ndefaultChartConfig(\"chart11\",dataFactoryWithStackable(5,8,null,3),{\n  delay:0,\n  useInteractiveGuideline: true\n});\n\nfunction defaultChartConfig(containerId, data, chartOptions) {\n  nv.addGraph(function() {\n      var chart;\n      chart = nv.models.multiBarChart()\n        .margin({bottom: 100})\n        ;\n\n      chart.options(chartOptions);\n      chart.multibar\n        .hideable(true);\n\n      chart.xAxis\n          .axisLabel(\"Current Index\")\n          .showMaxMin(true)\n          .tickFormat(d3.format(',0f'));\n\n      chart.yAxis\n          .tickFormat(d3.format(',.1f'));\n\n      d3.select('#' + containerId + ' svg')\n          .datum(data)\n         .call(chart);\n\n      nv.utils.windowResize(chart.update);\n\n      chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n      return chart;\n  });\n}\n\n\n\n\n</script>\n"
  },
  {
    "path": "test/multiBarHorizontalChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n.chart {\n  margin: 10px;\n  min-width: 100px;\n  min-height: 100px;\n/*\n  Minimum height and width is a good idea to prevent negative SVG dimensions...\n  For example width should be =< margin.left + margin.right + 1,\n  of course 1 pixel for the entire chart would not be very useful, BUT should not have errors\n*/\n}\n\n#chart1 svg {\n  height: 500px;\n}\n\n</style>\n<body>\n\n  <div id=\"chart1\" class='chart with-3d-shadow with-transitions'>\n    <svg></svg>\n  </div>\n\n  <div id=\"chart2\" class='chart'>\n    Chart with forceY([10])\n    <svg></svg>\n  </div>\n\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/multiBarHorizontal.js\"></script>\n<script src=\"../src/models/multiBarHorizontalChart.js\"></script>\n<script src=\"stream_layers.js\"></script>\n<script>\n\nlong_short_data = [ \n  {\n    key: 'Series1',\n    color: '#d62728',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : -1.8746444827653\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : -8.0961543492239\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : -0.57072943117674\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : -2.4174010336624\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : -0.72009071426284\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : -0.77154485523777\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : -0.90152097798131\n      } , \n      {\n        \"label\" : \"Group H\" ,\n        \"value\" : -0.91445417330854\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : -0.055746319141851\n      }\n    ]\n  },\n  {\n    key: 'Series2',\n    color: '#1f77b4',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : 25.307646510375\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : 16.756779544553\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : 18.451534877007\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : 8.6142352811805\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : 7.8082472075876\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : 5.259101026956\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : 0.30947953487127\n      } , \n      { \n        \"label\" : \"Group H\" ,\n        \"value\" : 0\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : 0 \n      }\n    ]\n  },\n  {\n    key: 'Series3',\n    color: '#2ca02c',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : -25.307646510375\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : 16.756779544553\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : -18.451534877007\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : 8.6142352811805\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : -7.8082472075876\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : 5.259101026956\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : -0.30947953487127\n      } , \n      { \n        \"label\" : \"Group H\" ,\n        \"value\" : 0\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : 0 \n      }\n    ]\n  }\n];\n\nlong_short_pos_data = [ \n  {\n    key: 'Series1',\n    color: '#d62728',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : 1.8746444827653\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : 8.0961543492239\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : 0.57072943117674\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : 2.4174010336624\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : 0.72009071426284\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : 0.77154485523777\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : 0.90152097798131\n      } , \n      {\n        \"label\" : \"Group H\" ,\n        \"value\" : 0.91445417330854\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : 0.055746319141851\n      }\n    ]\n  },\n  {\n    key: 'Series2',\n    color: '#1f77b4',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : 25.307646510375\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : 16.756779544553\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : 18.451534877007\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : 8.6142352811805\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : 7.8082472075876\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : 5.259101026956\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : 0.30947953487127\n      } , \n      { \n        \"label\" : \"Group H\" ,\n        \"value\" : 0\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : 0 \n      }\n    ]\n  }\n];\n\nlong_short_neg_data = [ \n  {\n    key: 'Series1',\n    color: '#d62728',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : -1.8746444827653\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : -8.0961543492239\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : -0.57072943117674\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : -2.4174010336624\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : -0.72009071426284\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : -0.77154485523777\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : -0.90152097798131\n      } , \n      {\n        \"label\" : \"Group H\" ,\n        \"value\" : -0.91445417330854\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : -0.055746319141851\n      }\n    ]\n  },\n  {\n    key: 'Series2',\n    color: '#1f77b4',\n    values: [\n      { \n        \"label\" : \"Group A\" ,\n        \"value\" : -25.307646510375\n      } , \n      { \n        \"label\" : \"Group B\" ,\n        \"value\" : -16.756779544553\n      } , \n      { \n        \"label\" : \"Group C\" ,\n        \"value\" : -18.451534877007\n      } , \n      { \n        \"label\" : \"Group D\" ,\n        \"value\" : -8.6142352811805\n      } , \n      {\n        \"label\" : \"Group E\" ,\n        \"value\" : -7.8082472075876\n      } , \n      { \n        \"label\" : \"Group F\" ,\n        \"value\" : -5.259101026956\n      } , \n      { \n        \"label\" : \"Group G\" ,\n        \"value\" : -0.30947953487127\n      } , \n      { \n        \"label\" : \"Group H\" ,\n        \"value\" : 0\n      } , \n      { \n        \"label\" : \"Group I\" ,\n        \"value\" : 0 \n      }\n    ]\n  }\n];\n\nnv.addGraph(function() {\n  var chart = nv.models.multiBarHorizontalChart()\n      .x(function(d) { return d.label })\n      .y(function(d) { return d.value })\n      .margin({top: 30, right: 20, bottom: 50, left: 175})\n      //.showValues(true)\n      //.tooltips(false)\n      .barColor(d3.scale.category20().range())\n      .stacked(true)\n      //.showControls(false);\n\n  chart.yAxis\n      .tickFormat(d3.format(',.2f'));\n\n  d3.select('#chart1 svg')\n      .datum(long_short_data)\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\nvar forceY_test_data = [\n  {\n    \"key\": \"Series 1\",\n    \"color\": \"#d67777\",\n    \"values\": [\n      {\"label\": \"Group A\", \"value\": 10},\n      {\"label\": \"Group B\", \"value\": 20},\n      {\"label\": \"Group C\", \"value\": 30}\n    ]\n  }\n];\n\nnv.addGraph(function() {\n  var chart = nv.models.multiBarHorizontalChart()\n      .x(function(d) { return d.label })\n      .y(function(d) { return d.value })\n      .forceY([10])// To make 10 to be starting point.\n      .margin({top: 30, right: 20, bottom: 50, left: 175})\n      .showValues(true)           //Show bar value next to each bar.\n      .showControls(true);        //Allow user to switch between \"Grouped\" and \"Stacked\" mode.\n  chart.yAxis\n      .tickFormat(d3.format(',.2f'));\n  //chart.yScale().clamp(true);\n  d3.select('#chart2 svg')\n      .datum(forceY_test_data)\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  return chart;\n});\n\n</script>\n"
  },
  {
    "path": "test/node/GruntFile.js",
    "content": "module.exports = function(grunt) {\n  grunt.initConfig({\n    browserify: {\n      js: {\n        src: './nodeTest.js', dest: './build/nodeTest.js',\n      },\n    },\n    copy: {\n      all: {\n        src: ['../../build/nv.d3.css'], dest: './build/nv.d3.css',\n      },\n    },\n  });\n  grunt.loadNpmTasks('grunt-browserify');\n  grunt.loadNpmTasks('grunt-contrib-copy');\n  grunt.registerTask('default', ['browserify', 'copy']);\n};\n"
  },
  {
    "path": "test/node/README.md",
    "content": "Build steps:\n\n- Build `nvd3`.\n- Build the example.\n- Start an HTTP server.\n\n    nvd3 $ grunt production\n    nvd3 $ cd test/node\n    nvd3/test/node $ npm install .\n    nvd3/test/node $ grunt\n    nvd3/test/node $ python -m SimpleHTTPServer 8000\n\nBrowse to `http://localhost:8000/nodeTest.html`\n"
  },
  {
    "path": "test/node/nodeTest.html",
    "content": "<!doctype html>\n<html>\n<head>\n  <title>Node Test</title>\n  <meta charset=\"utf-8\">\n  <link rel=\"stylesheet\" href=\"./build/nv.d3.css\">\n  <script src=\"./build/nodeTest.js\"></script>\n</head>\n<body>\n  <div id=\"chart\">\n    <svg/>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "test/node/nodeTest.js",
    "content": "window.d3 = require('d3');\nvar nv = require('../../build/nv.d3');\nvar invariant = require('invariant');\n\nwindow.addEventListener(\"load\", function load(event) {\n  window.removeEventListener(\"load\", load, false);\n  invariant(typeof(nv) !== 'undefined', \"Cannot resolve NVD3 via CommonJS\");\n  nv.addGraph(function() {\n    var chart = nv.models.bulletChart();\n    d3.select('#chart svg')\n        .datum(exampleData())\n        .transition().duration(1000)\n        .call(chart);\n    return chart;\n  });\n}, false);\n\nfunction exampleData() {\n  return {\n    \"title\":\"Revenue\",\n    \"subtitle\":\"US$, in thousands\",\n    \"ranges\":[150,225,300],\n    \"measures\":[220],\n    \"markers\":[250]\n  }\n}\n"
  },
  {
    "path": "test/node/package.json",
    "content": "{\n  \"name\": \"node-test\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"d3\": \"<=3.4.4\",\n    \"invariant\": \"1.0.2\"\n  },\n  \"devDependencies\": {\n    \"grunt-browserify\": \"3.3.0\",\n    \"grunt-contrib-copy\": \"~0.4.1\"\n  }\n}\n"
  },
  {
    "path": "test/pieChartTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n<style>\n\nbody {\n  overflow-y:scroll;\n  font-family: Arial;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n</style>\n<body class='with-transitions'>\n<div class='navigation'>\n          Tests:\n          <a href=\"lineChartTest.html\">Line Chart</a>\n          <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n          <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n          <a href=\"ScatterChartTest.html\">Scatter</a>\n          <a href=\"realTimeChartTest.html\">Real time test</a>\n  </div>\n<div class='chart third' id=\"test1\">\n  <h2>Standard Pie Chart</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test2\">\n  <h2>Donut pie chart</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test3\">\n  <h2>Pie chart with 30 series'</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id='test7'>\n  <h2>Pie chart with percent label type</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test4\">\n  <h2>Empty array passed in</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test5\">\n  <h2>Series' have only zero values</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test6\">\n  <h2>NaN, null, undefined values passed in</h2>\n  <svg></svg>\n</div>\n\n<div class='chart third' id=\"test8\">\n  <h2>Half donut pie chart with outside label</h2>\n  <svg></svg>\n</div>\n\n<script>\n\nvar testdata = [\n    {\n      key: \"One\",\n      y: 5\n    },\n    {\n      key: \"Two\",\n      y: 2\n    },\n    {\n      key: \"Three\",\n      y: 9\n    },\n    {\n      key: \"Four\",\n      y: 7\n    },\n    {\n      key: \"Five\",\n      y: 4\n    },\n    {\n      key: \"Six\",\n      y: 3\n    },\n    {\n      key: \"Seven\",\n      y: .5\n    }\n  ];\n\nfunction thirtySeries() {\n  var data = [];\n  for(var i =0; i < 30; i++) {\n    data.push({\n      key: \"Series-\" + i,\n      y: Math.floor(Math.random() * 100)\n    });\n  }\n  return data;\n}\n\nfunction defaultChart(containerId, data, labelType) {\n  nv.addGraph(function() {\n      var width = 500,\n          height = 500;\n\n      var chart = nv.models.pieChart()\n          .x(function(d) { return d.key })\n          .y(function(d) { return d.y })\n          .color(d3.scale.category10().range())\n          .width(width)\n          .height(height)\n          .labelType(labelType)\n          ;\n\n        d3.select(\"#\" + containerId + \" svg\")\n            .datum(data)\n          .transition().duration(1200)\n            .attr('width', width)\n            .attr('height', height)\n            .call(chart);\n\n      nv.utils.windowResize(chart.update);\n      return chart;\n  });\n}\n\n//Adds donut pie chart.\nfunction defaultDonutChart(containerId, data, options) {\n    options = options || {};\n\n    nv.addGraph(function () {\n\n        var width = 500,\n                height = 500;\n\n        var chart = nv.models.pieChart()\n                .x(function (d) {\n                    return d.key\n                })\n                .color(d3.scale.category10().range())\n                .width(width)\n                .height(height)\n                .donut(true);\n\n        if (options.half){\n            chart.pie\n                    .startAngle(function (d) {\n                        return d.startAngle / 2 - Math.PI / 2\n                    })\n                    .endAngle(function (d) {\n                        return d.endAngle / 2 - Math.PI / 2\n                    });\n        }\n\n        if (options.donutLabelsOutside){\n            chart.pie.donutLabelsOutside(true);\n        }\n\n        d3.select(\"#\" + containerId + \" svg\")\n                .datum(data)\n                .transition().duration(1200)\n                .attr('width', width)\n                .attr('height', height)\n                .call(chart);\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n}\n\ndefaultChart(\"test1\", testdata);\ndefaultDonutChart(\"test2\", testdata, true);\ndefaultChart(\"test3\", thirtySeries());\ndefaultChart(\"test4\",[]);\ndefaultChart(\"test5\",[{key: \"Zero series\", y: 0}, {key: \"Zero series 2\", y: 0}]);\ndefaultChart(\"test6\", [\n      {key: \"Undefined\", y: undefined},\n      {key: \"Nan\", y: NaN},\n      {key: \"null\", y: null},\n      {key: \"zero\", y: 0}\n  ]);\n\ndefaultChart(\"test7\",testdata, \"percent\");\ndefaultDonutChart(\"test8\", testdata, {half: true, donutLabelsOutside: true});\n</script>\n"
  },
  {
    "path": "test/polylinearTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n<style>\n\n</style>\n<body>\n  <h3>Test cases for Domain and Range overrides - Example of a polylinear scale</h3>\n  <div style='position:relative;'>\n      <div class='navigation'>\n          Tests:\n          <a href=\"lineChartTest.html\">Line Chart</a>\n          <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n          <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n          <a href=\"ScatterChartTest.html\">Scatter</a>\n          <a href=\"pieChartTest.html\">Pie chart</a>\n      </div>\n      <div class='chart full' id='chart1'>\n        Line chart: yDomain = [0,2,200], yRange = [500,50,0]\n        <svg></svg>\n      </div>\n      <div class='chart half with-transitions' id='chart2'>\n        Historical bar chart: yDomain = [0,2,130], yRange = [500,50,0]\n        <svg></svg>\n      </div>\n\n      <div class='half'>\n        Notes:\n        The chart.yRange() and chart.xRange() properties are an advanced feature.  They are useful\n        in situations where your data has wild extremes: ie, you have lots of smaller numbers, and lots of really big numbers.<br/><br/>\n\n        Without a polylinear scale, those really big data points will overwhelm the small points.<br/><br/>\n\n        Please look at the examples to understand how polylinear scales work.  Comment/uncomment the lines that alter yDomain and yRange\n        to see the effect it has on the charts.\n      </div>\n  </div>\n\n<script>\n\n//------------ CHART 1\nlineChartConfig(\"chart1\", sinAndCos(),true, false);\nbarChartConfig(dataWithSpikes());\n\n\nfunction lineChartConfig(containerid, data, guideline, useDates, auxOptions) {\n  if (auxOptions === undefined) auxOptions = {};\n  if (guideline === undefined) guideline = true;\n  nv.addGraph(function() {\n    var chart;\n    chart = nv.models.lineChart().useInteractiveGuideline(guideline);\n\n    var fullChartHeight = 500 - chart.margin().top - chart.margin().bottom;\n    chart\n        .x(function(d,i) {\n          return d.x;\n        })\n       .yDomain([0,2,200])   //Using a polylinear scale\n        .yRange([fullChartHeight,50,0])\n        ;\n\n    if (auxOptions.width)\n      chart.width(auxOptions.width);\n\n    if (auxOptions.height)\n      chart.height(auxOptions.height);\n\n    var formatter;\n    if (useDates) {\n        formatter = function(d,i) {\n                var now = (new Date()).getTime() - 86400 * 1000 * 365;\n                now = new Date(now + d * 86400 * 1000);\n                return d3.time.format('%b %d %Y')(now );\n        }\n    }\n    else {\n        formatter = d3.format(\",.1f\");\n    }\n\n    chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n        .tickFormat(\n            formatter\n          );\n\n    chart.yAxis\n        .axisLabel('Voltage (v)')\n        .tickFormat(d3.format(',.2f'));\n\n    d3.select('#' + containerid + ' svg')\n        .datum(data)\n      .transition().duration(500)\n        .call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    return chart;\n  });\n}\n\nfunction barChartConfig(data) {\n    nv.addGraph(function() {\n      var chart = nv.models.historicalBarChart();\n      var fullChartHeight = 500 - chart.margin().top - chart.margin().bottom;\n      chart.color([\"#ff7f0e\"])\n      .yDomain([0,2,130])\n      .yRange([fullChartHeight,50,0])\n      ;\n\n      chart.xAxis\n      .tickFormat(d3.format(',.1f'))\n      .axisLabel(\"Time\")\n      ;\n\n       chart.yAxis\n      .axisLabel('Random Number')\n      .tickFormat(d3.format(',.4f'));\n      d3.select(\"#chart2 svg\")\n        .datum(data)\n        .transition().duration(500)\n        .call(chart);\n\n      nv.utils.windowResize(chart.update);\n      return chart;\n    });\n}\n\nfunction sinAndCos() {\n  var sin = [],\n      cos = [],\n      higherOrder = []\n      ;\n\n  var now = (new Date()).getTime();\n  for (var i = 0; i < 100; i++) {\n    sin.push({x: i, y:  Math.abs(Math.sin(i/10)) }); //the nulls are to show how defined works\n    cos.push({x: i, y: Math.abs(.5 * Math.cos(i/10)) });\n\n    higherOrder.push({x: i, y: Math.cos(i) * 100 + 100});\n  }\n\n  return [\n    {\n      values: sin,\n      key: \"Sine Wave\",\n      color: \"#ff7f0e\"\n    },\n    {\n      values: cos,\n      key: \"Cosine Wave\",\n      color: \"#2ca02c\"\n    },\n    {\n      values: higherOrder,\n      key: \"Higher Order\",\n      color: \"#fc34ff\"\n    }\n  ];\n}\n\nfunction dataWithSpikes() {\n   var rval = [];\n   for(var i =0; i < 100; i++) {\n\n      var spike = (Math.random() > 0.9);\n      rval.push({\n        x: i,\n        y: (spike) ? Math.random() * 100 + 30 : Math.random()\n      });\n   }\n   return [\n      {key: \"Series 1\",\n      color : \"orange\",\n      values: rval}\n   ];\n}\n\n</script>\n"
  },
  {
    "path": "test/realTimeChartTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<body>\n\t <div class='navigation'>\n          Tests:\n          <a href=\"lineChartTest.html\">Line Chart</a>\n          <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n          <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n          <a href=\"ScatterChartTest.html\">Scatter</a>\n      </div>\n  <h3>Example showing real time chart updating</h3>\n  The chart below is a historical bar chart, which is ideal for visualizing time series data.<br/>\n  First, you need to update the data model for the chart. In the example, we append a random number\n  every half a second. Then, you call <strong>chart.update()</strong>.\n\n<div id='chart' class='chart half with-transitions'>\n\t<svg></svg>\n\t<button id='start-stop-button'>Start/Stop Stream</button>\n</div>\n\n<script>\nvar chart;\nvar data = [{\n\tkey: \"Stream 1\",\n\tcolor: \"orange\",\n\tvalues: [\n\t\t{x: 1, y: 1}\n\t]\n}];\nnv.addGraph(function() {\n\n  chart = nv.models.historicalBarChart();\n\n  chart\n      .x(function(d,i) { return d.x });\n\n  chart.xAxis // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n      .tickFormat(d3.format(',.1f'))\n      .axisLabel(\"Time\")\n      ;\n\n  chart.yAxis\n      .axisLabel('Random Number')\n      .tickFormat(d3.format(',.4f'));\n\n  chart.showXAxis(true).showYAxis(true).rightAlignYAxis(true).margin({right: 90});\n\n  d3.select('#chart svg')\n      .datum(data)\n      .transition().duration(500)\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  return chart;\n});\n\nvar x = 2;\nvar run = true;\nsetInterval(function(){\n\tif (!run) return;\n\n\tvar spike = (Math.random() > 0.95) ? 10: 1;\n\tdata[0].values.push({\n\t\tx: x,\n\t\ty: Math.random() * spike\n\t});\n\n\tif (data[0].values.length > 70) {\n\t\tdata[0].values.shift();\n\t}\n\tx++;\n\n\tchart.update();\n}, 500);\n\nd3.select(\"#start-stop-button\").on(\"click\",function() {\n\trun = !run;\n});\n\n</script>\n\n</body>\n</html>"
  },
  {
    "path": "test/scatterPlusLineChart.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../src/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n\n<style>\n\nbody {\n  overflow-y:scroll;\n  margin: 0;\n  padding: 0;\n}\n\nsvg {\n  overflow: hidden;\n}\n\ndiv {\n  border: 0;\n  margin: 0;\n}\n\n/*\n#offsetDiv {\n  margin-left: 100px;\n  margin-top: 100px;\n}\n*/\n\n\n#test1 {\n  margin: 0;\n}\n\n#test1 svg {\n  height: 500px;\n}\n\n</style>\n\n<body class='with-3d-shadow with-transitions'>\n\n<div id=\"offsetDiv\">\n  <div id=\"test1\" class=\"chartWrap\">\n    <svg></svg>\n  </div>\n</div>\n\n<script src=\"../lib/d3.v3.js\"></script>\n<script src=\"../lib/fisheye.js\"></script>\n<script src=\"../nv.d3.js\"></script>\n<script src=\"../src/tooltip.js\"></script>\n<script src=\"../src/utils.js\"></script>\n<script src=\"../src/models/legend.js\"></script>\n<script src=\"../src/models/axis.js\"></script>\n<script src=\"../src/models/distribution.js\"></script>\n<script src=\"../src/models/scatter.js\"></script>\n<script src=\"../src/models/scatterPlusLineChart.js\"></script>\n<script>\n\n\n\n//Format A\nvar chart;\nnv.addGraph(function() {\n  chart = nv.models.scatterPlusLineChart()\n                .showDistX(true)\n                .showDistY(true)\n                .transitionDuration(300)\n                .color(d3.scale.category10().range());\n\n  chart.dispatch.on('renderEnd', function(){\n    console.log('render complete');\n  });\n\n  chart.xAxis.tickFormat(d3.format('.02f'))\n  chart.yAxis.tickFormat(d3.format('.02f'))\n\n  d3.select('#test1 svg')\n      .datum(nv.log(randomData(4,40)))\n      .call(chart);\n\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\n\nfunction randomData(groups, points) { //# groups,# points per group\n  var data = [],\n      shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],\n      random = d3.random.normal();\n\n  for (i = 0; i < groups; i++) {\n    data.push({\n      key: 'Group ' + i,\n      values: [],\n      slope: Math.random() - .01,\n      intercept: Math.random() - .5\n    });\n\n    for (j = 0; j < points; j++) {\n      data[i].values.push({\n        x: random(), \n        y: random(), \n        size: Math.random(), \n        shape: shapes[j % 6]\n      });\n    }\n  }\n\n  return data;\n}\n\n\n\n</script>\n"
  },
  {
    "path": "test/scrollTest.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"../bower_components/d3/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <style>\n        body {\n            display: block;\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            overflow: hidden;\n        }\n\n        .ghost {\n            width: 100%;\n            height: 100%;\n            overflow-y: auto;\n        }\n        #chart1 {\n            height: 1000px\n        }\n        #chart2, #chart3 {\n            height: 500px\n        }\n    </style>\n</head>\n<body>\n    <p> Charts: </p>\n    <div class=\"ghost\">\n        <div id=\"chart1\">\n            <p> Chart 1</p>\n            <svg></svg>\n        </div>\n        <div id=\"chart2\">\n            <svg></svg>\n        </div>\n        <div id=\"chart3\">\n            <svg></svg>\n        </div>\n        <div id=\"chart4\">\n            <svg></svg>\n        </div>\n    </div>\n    <script>\n    createChart('#chart1');\n    createChart('#chart2');\n    createChart('#chart3');\n\n    function createChart(id) {\n        nv.addGraph(function () {\n            var chart = nv.models.lineChart()\n                .useInteractiveGuideline(true);\n\n            d3.select(id + ' svg')\n                .datum(data())\n                .transition().duration(500)\n                .call(chart);\n\n            nv.utils.windowResize(chart.update);\n\n            return chart;\n        });\n\n\n        function data() {\n            var sin = [],\n                cos = [];\n\n            for (var i = 0; i < 100; i++) {\n                sin.push({\n                    x: i,\n                    y: Math.sin(i / 10)\n                });\n                cos.push({\n                    x: i,\n                    y: .5 * Math.cos(i / 10)\n                });\n            }\n\n            return [{\n                values: sin,\n                key: 'Sine Wave',\n                color: '#ff7f0e'\n            }, {\n                values: cos,\n                key: 'Cosine Wave',\n                color: '#2ca02c'\n            }];\n        }\n    }\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "test/scrollTest2.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"../bower_components/d3/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n\n        .dashed {\n            stroke-dasharray: 5,5;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<script>\n    var chart;\n\n    graph();\n\n    function graph() {\n        nv.addGraph(function() {\n            chart = nv.models.lineChart()\n                .useInteractiveGuideline(true);\n\n            // chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately\n            chart.xAxis\n                .axisLabel(\"Time (s)\")\n                .tickFormat(d3.format(',.1f'))\n                .staggerLabels(true)\n            ;\n\n            chart.yAxis\n                .axisLabel('Voltage (v)')\n                .tickFormat(function(d) {\n                    if (d == null) {\n                        return 'N/A';\n                    }\n                    return d3.format(',.2f')(d);\n                })\n            ;\n\n            chart.tooltip.gravity('w');\n\n\n\n            var data = sinAndCos();\n\n            d3.select('body').append('svg')\n                .datum(data)\n                .call(chart);\n\n            nv.utils.windowResize(chart.update);\n\n            return chart;\n        });\n    }\n\n    function sinAndCos() {\n        var sin = [],\n            sin2 = [],\n            cos = [],\n            rand = [],\n            rand2 = []\n            ;\n\n        for (var i = 0; i < 100; i++) {\n            sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works\n            sin2.push({x: i, y: Math.sin(i/5) * 0.4 - 0.25});\n            cos.push({x: i, y: .5 * Math.cos(i/10)});\n            rand.push({x:i, y: Math.random() / 10});\n            rand2.push({x: i, y: Math.cos(i/10) + Math.random() / 10 })\n        }\n\n        return [\n            {\n                area: true,\n                values: sin,\n                key: \"Sine Wave\",\n                color: \"#ff7f0e\",\n                strokeWidth: 4,\n                classed: 'dashed'\n            },\n            {\n                values: cos,\n                key: \"Cosine Wave\",\n                color: \"#2ca02c\"\n            },\n            {\n                values: rand,\n                key: \"Random Points\",\n                color: \"#2222ff\"\n            },\n            {\n                values: rand2,\n                key: \"Random Cosine\",\n                color: \"#667711\",\n                strokeWidth: 3.5\n            },\n            {\n                area: true,\n                values: sin2,\n                key: \"Fill opacity\",\n                color: \"#EF9CFB\",\n                fillOpacity: .1\n            }\n        ];\n    }\n\n</script>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n<p>.</p>\n</body>\n</html>\n"
  },
  {
    "path": "test/stackedAreaChartMissingData.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n\n    <style>\n        text {\n            font: 12px sans-serif;\n        }\n        svg {\n            display: block;\n        }\n        html, body, svg {\n            margin: 0px;\n            padding: 0px;\n            height: 100%;\n            width: 100%;\n        }\n    </style>\n</head>\n<body class='with-3d-shadow with-transitions'>\n\n<svg id=\"chart1\"></svg>\n\n<script>\n\n    var data = [\n        {\n            \"key\" : \"Consumer Discretionary\" ,\n            \"values\" : [ [ 1138683600000 , 27.38478809681] , [ 1141102800000 , 27.371377218208] , [ 1143781200000 , 26.309915460827] , [ 1146369600000 , 26.425199957521] , [ 1149048000000 , 26.823411519395] , [ 1151640000000 , 23.850443591584] , [ 1154318400000 , 23.158355444054] , [ 1156996800000 , 22.998689393694] , [ 1159588800000 , 27.977128511299] , [ 1162270800000 , 29.073672469721] , [ 1164862800000 , 28.587640408904] , [ 1167541200000 , 22.788453687638] , [ 1170219600000 , 22.429199073597] , [ 1172638800000 , 22.324103271051] , [ 1175313600000 , 17.558388444186] , [ 1177905600000 , 16.769518096208] , [ 1180584000000 , 16.214738201302] , [ 1183176000000 , 18.729632971228] , [ 1185854400000 , 18.814523318848] , [ 1188532800000 , 19.789986451358] , [ 1191124800000 , 17.070049054933] , [ 1193803200000 , 16.121349575715] , [ 1196398800000 , 15.141659430091] , [ 1199077200000 , 17.175388025298] , [ 1201755600000 , 17.286592443521] , [ 1204261200000 , 16.323141626569] , [ 1206936000000 , 19.231263773952] , [ 1209528000000 , 18.446256391094] , [ 1212206400000 , 17.822632399764] , [ 1214798400000 , 15.539366475979] , [ 1217476800000 , 15.255131790216] , [ 1220155200000 , 15.660963922593] , [ 1222747200000 , 13.254482273697] , [ 1225425600000 , 11.920796202299] , [ 1228021200000 , 12.122809090925] , [ 1230699600000 , 15.691026271393] , [ 1233378000000 , 14.720881635107] , [ 1235797200000 , 15.387939360044] , [ 1238472000000 , 13.765436672229] , [ 1241064000000 , 14.6314458648] , [ 1243742400000 , 14.292446536221] , [ 1246334400000 , 16.170071367016] , [ 1249012800000 , 15.948135554337] , [ 1251691200000 , 16.612872685134] , [ 1254283200000 , 18.778338719091] , [ 1256961600000 , 16.75602606542] , [ 1259557200000 , 19.385804443147] , [ 1262235600000 , 22.950590240168] , [ 1264914000000 , 23.61159018141] , [ 1267333200000 , 25.708586989581] , [ 1270008000000 , 26.883915999885] , [ 1272600000000 , 25.893486687065] , [ 1275278400000 , 24.678914263176] , [ 1277870400000 , 25.937275793023] , [ 1280548800000 , 29.46138169384] , [ 1283227200000 , 27.357322961862] , [ 1285819200000 , 29.057235285673] , [ 1288497600000 , 28.549434189386] , [ 1291093200000 , 28.506352379723] , [ 1293771600000 , 29.449241421597] , [ 1296450000000 , 25.796838168807] , [ 1298869200000 , 28.740145449189] , [ 1301544000000 , 22.091744141872] , [ 1304136000000 , 25.079662545409] , [ 1306814400000 , 23.674906973064] , [ 1309406400000 , 23.41800274293] , [ 1312084800000 , 23.243644138871] , [ 1314763200000 , 31.591854066817] , [ 1317355200000 , 31.497112374114] , [ 1320033600000 , 26.672380820431] , [ 1322629200000 , 27.297080015495] , [ 1325307600000 , 20.174315530051] , [ 1327986000000 , 19.631084213899] , [ 1330491600000 , 20.366462219462] , [ 1333166400000 , 17.429019937289] , [ 1335758400000 , 16.75543633539] , [ 1338436800000 , 16.182906906042]]\n        } ,\n        {\n            \"key\" : \"Consumer Staples\" ,\n            \"values\" : [ [ 1138683600000 , 7.2800122043237] , [ 1141102800000 , 7.1187787503354] , [ 1143781200000 , 8.351887016482] , [ 1146369600000 , 8.4156698763993] , [ 1149048000000 , 8.1673298604231] , [ 1151640000000 , 5.5132447126042] , [ 1154318400000 , 6.1152537710599] , [ 1156996800000 , 6.076765091942] , [ 1159588800000 , 4.6304473798646] , [ 1162270800000 , 4.6301068469402] , [ 1164862800000 , 4.3466656309389] , [ 1167541200000 , 6.830104897003] , [ 1170219600000 , 7.241633040029] , [ 1172638800000 , 7.1432372054153] , [ 1175313600000 , 10.608942063374] , [ 1177905600000 , 10.914964549494] , [ 1180584000000 , 10.933223880565] , [ 1183176000000 , 8.3457524851265] , [ 1185854400000 , 8.1078413081882] , [ 1188532800000 , 8.2697185922474] , [ 1191124800000 , 8.4742436475968] , [ 1193803200000 , 8.4994601179319] , [ 1196398800000 , 8.7387319683243] , [ 1199077200000 , 6.8829183612895] , [ 1201755600000 , 6.984133637885] , [ 1204261200000 , 7.0860136043287] , [ 1206936000000 , 4.3961787956053] , [ 1209528000000 , 3.8699674365231] , [ 1212206400000 , 3.6928925238305] , [ 1214798400000 , 6.7571718894253] , [ 1217476800000 , 6.4367313362344] , [ 1220155200000 , 6.4048441521454] , [ 1222747200000 , 5.4643833239669] , [ 1225425600000 , 5.3150786833374] , [ 1228021200000 , 5.3011272612576] , [ 1230699600000 , 4.1203601430809] , [ 1233378000000 , 4.0881783200525] , [ 1235797200000 , 4.1928665957189] , [ 1238472000000 , 7.0249415663205] , [ 1241064000000 , 7.006530880769] , [ 1243742400000 , 6.994835633224] , [ 1246334400000 , 6.1220222336254] , [ 1249012800000 , 6.1177436137653] , [ 1251691200000 , 6.1413396231981] , [ 1254283200000 , 4.8046006145874] , [ 1256961600000 , 4.6647600660544] , [ 1259557200000 , 4.544865006255] , [ 1262235600000 , 6.0488249316539] , [ 1264914000000 , 6.3188669540206] , [ 1267333200000 , 6.5873958262306] , [ 1270008000000 , 6.2281189839578] , [ 1272600000000 , 5.8948915746059] , [ 1275278400000 , 5.5967320482214] , [ 1277870400000 , 0.99784432084837] , [ 1280548800000 , 1.0950794175359] , [ 1283227200000 , 0.94479734407491] , [ 1285819200000 , 1.222093988688] , [ 1288497600000 , 1.335093106856] , [ 1291093200000 , 1.3302565104985] , [ 1293771600000 , 1.340824670897] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 4.4583692315] , [ 1320033600000 , 3.6493043348059] , [ 1322629200000 , 3.8610064091761] , [ 1325307600000 , 5.5144800685202] , [ 1327986000000 , 5.1750695220792] , [ 1330491600000 , 5.6710066952691] , [ 1333166400000 , 8.5658461590953] , [ 1335758400000 , 8.6135447714243] , [ 1338436800000 , 8.0231460925212]]\n        } ,\n        {\n            \"key\" : \"Energy\" ,\n            \"values\" : [ [ 1138683600000 , 1.544303464167] , [ 1141102800000 , 1.4387289432421] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 1.328626801128] , [ 1154318400000 , 1.2874050802627] , [ 1156996800000 , 1.0872743105593] , [ 1159588800000 , 0.96042562635813] , [ 1162270800000 , 0.93139372870616] , [ 1164862800000 , 0.94432167305385] , [ 1167541200000 , 1.277750166208] , [ 1170219600000 , 1.2204893886811] , [ 1172638800000 , 1.207489123122] , [ 1175313600000 , 1.2490651414113] , [ 1177905600000 , 1.2593129913052] , [ 1180584000000 , 1.373329808388] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 1.4516108933695] , [ 1225425600000 , 1.1856025268225] , [ 1228021200000 , 1.3430470355439] , [ 1230699600000 , 2.2752595354509] , [ 1233378000000 , 2.4031560010523] , [ 1235797200000 , 2.0822430731926] , [ 1238472000000 , 1.5640902826938] , [ 1241064000000 , 1.5812873972356] , [ 1243742400000 , 1.9462448548894] , [ 1246334400000 , 2.9464870223957] , [ 1249012800000 , 3.0744699383222] , [ 1251691200000 , 2.9422304628446] , [ 1254283200000 , 2.7503075599999] , [ 1256961600000 , 2.6506701800427] , [ 1259557200000 , 2.8005425319977] , [ 1262235600000 , 2.6816184971185] , [ 1264914000000 , 2.681206271327] , [ 1267333200000 , 2.8195488011259] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 1.0687057346382] , [ 1280548800000 , 1.2539400544134] , [ 1283227200000 , 1.1862969445955] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 1.941972859484] , [ 1298869200000 , 2.1142247697552] , [ 1301544000000 , 2.3788590206824] , [ 1304136000000 , 2.5337302877545] , [ 1306814400000 , 2.3163370395199] , [ 1309406400000 , 2.0645451843195] , [ 1312084800000 , 2.1004446672411] , [ 1314763200000 , 3.6301875804303] , [ 1317355200000 , 2.454204664652] , [ 1320033600000 , 2.196082370894] , [ 1322629200000 , 2.3358418255202] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0.39001201038526] , [ 1335758400000 , 0.30945472725559] , [ 1338436800000 , 0.31062439305591]]\n        } ,\n        {\n            \"key\" : \"Financials\" ,\n            \"values\" : [ [ 1138683600000 , 13.356778764352] , [ 1141102800000 , 13.611196863271] , [ 1143781200000 , 6.895903006119] , [ 1146369600000 , 6.9939633271352] , [ 1149048000000 , 6.7241510257675] , [ 1151640000000 , 5.5611293669516] , [ 1154318400000 , 5.6086488714041] , [ 1156996800000 , 5.4962849907033] , [ 1159588800000 , 6.9193153169279] , [ 1162270800000 , 7.0016334389777] , [ 1164862800000 , 6.7865422443273] , [ 1167541200000 , 9.0006454225383] , [ 1170219600000 , 9.2233916171431] , [ 1172638800000 , 8.8929316009479] , [ 1175313600000 , 10.345937520404] , [ 1177905600000 , 10.075914677026] , [ 1180584000000 , 10.089006188111] , [ 1183176000000 , 10.598330295008] , [ 1185854400000 , 9.968954653301] , [ 1188532800000 , 9.7740580198146] , [ 1191124800000 , 10.558483060626] , [ 1193803200000 , 9.9314651823603] , [ 1196398800000 , 9.3997715873769] , [ 1199077200000 , 8.4086493387262] , [ 1201755600000 , 8.9698309085926] , [ 1204261200000 , 8.2778357995396] , [ 1206936000000 , 8.8585045600123] , [ 1209528000000 , 8.7013756413322] , [ 1212206400000 , 7.7933605469443] , [ 1214798400000 , 7.0236183483064] , [ 1217476800000 , 6.9873088186829] , [ 1220155200000 , 6.8031713070097] , [ 1222747200000 , 6.6869531315723] , [ 1225425600000 , 6.138256993963] , [ 1228021200000 , 5.6434994016354] , [ 1230699600000 , 5.495220262512] , [ 1233378000000 , 4.6885326869846] , [ 1235797200000 , 4.4524349883438] , [ 1238472000000 , 5.6766520778185] , [ 1241064000000 , 5.7675774480752] , [ 1243742400000 , 5.7882863168337] , [ 1246334400000 , 7.2666010034924] , [ 1249012800000 , 7.519182132226] , [ 1251691200000 , 7.849651451445] , [ 1254283200000 , 10.383992037985] , [ 1256961600000 , 9.0653691861818] , [ 1259557200000 , 9.6705248324159] , [ 1262235600000 , 10.856380561349] , [ 1264914000000 , 11.27452370892] , [ 1267333200000 , 11.754156529088] , [ 1270008000000 , 8.2870811422456] , [ 1272600000000 , 8.0210264360699] , [ 1275278400000 , 7.5375074474865] , [ 1277870400000 , 8.3419527338039] , [ 1280548800000 , 9.4197471818443] , [ 1283227200000 , 8.7321733185797] , [ 1285819200000 , 9.6627062648126] , [ 1288497600000 , 10.187962234549] , [ 1291093200000 , 9.8144201733476] , [ 1293771600000 , 10.275723361713] , [ 1296450000000 , 16.796066079353] , [ 1298869200000 , 17.543254984075] , [ 1301544000000 , 16.673660675084] , [ 1304136000000 , 17.963944353609] , [ 1306814400000 , 16.637740867211] , [ 1309406400000 , 15.84857094609] , [ 1312084800000 , 14.767303362182] , [ 1314763200000 , 24.778452182432] , [ 1317355200000 , 18.370353229999] , [ 1320033600000 , 15.2531374291] , [ 1322629200000 , 14.989600840649] , [ 1325307600000 , 16.052539160125] , [ 1327986000000 , 16.424390322793] , [ 1330491600000 , 17.884020741105] , [ 1333166400000 , 7.1424929577921] , [ 1335758400000 , 7.8076213051482] , [ 1338436800000 , 7.2462684949232]]\n        } ,\n        {\n            \"key\" : \"Health Care\" ,\n            \"values\" : [ [ 1138683600000 , 14.212410956029] , [ 1141102800000 , 13.973193618249] , [ 1143781200000 , 15.218233920665] , [ 1146369600000 , 14.38210972745] , [ 1149048000000 , 13.894310878491] , [ 1151640000000 , 15.593086090032] , [ 1154318400000 , 16.244839695188] , [ 1156996800000 , 16.017088850646] , [ 1159588800000 , 14.183951830055] , [ 1162270800000 , 14.148523245697] , [ 1164862800000 , 13.424326059972] , [ 1167541200000 , 12.974450435753] , [ 1170219600000 , 13.23247041802] , [ 1172638800000 , 13.318762655574] , [ 1175313600000 , 15.961407746104] , [ 1177905600000 , 16.287714639805] , [ 1180584000000 , 16.246590583889] , [ 1183176000000 , 17.564505594809] , [ 1185854400000 , 17.872725373165] , [ 1188532800000 , 18.018998508757] , [ 1191124800000 , 15.584518016603] , [ 1193803200000 , 15.480850647181] , [ 1196398800000 , 15.699120036984] , [ 1199077200000 , 19.184281817226] , [ 1201755600000 , 19.691226605207] , [ 1204261200000 , 18.982314051295] , [ 1206936000000 , 18.707820309008] , [ 1209528000000 , 17.459630929761] , [ 1212206400000 , 16.500616076782] , [ 1214798400000 , 18.086324003979] , [ 1217476800000 , 18.929464156258] , [ 1220155200000 , 18.233728682084] , [ 1222747200000 , 16.315776297325] , [ 1225425600000 , 14.63289219025] , [ 1228021200000 , 14.667835024478] , [ 1230699600000 , 13.946993947308] , [ 1233378000000 , 14.394304684397] , [ 1235797200000 , 13.724462792967] , [ 1238472000000 , 10.930879035806] , [ 1241064000000 , 9.8339915513708] , [ 1243742400000 , 10.053858541872] , [ 1246334400000 , 11.786998438287] , [ 1249012800000 , 11.780994901769] , [ 1251691200000 , 11.305889670276] , [ 1254283200000 , 10.918452290083] , [ 1256961600000 , 9.6811395055706] , [ 1259557200000 , 10.971529744038] , [ 1262235600000 , 13.330210480209] , [ 1264914000000 , 14.592637568961] , [ 1267333200000 , 14.605329141157] , [ 1270008000000 , 13.936853794037] , [ 1272600000000 , 12.189480759072] , [ 1275278400000 , 11.676151385046] , [ 1277870400000 , 13.058852800017] , [ 1280548800000 , 13.62891543203] , [ 1283227200000 , 13.811107569918] , [ 1285819200000 , 13.786494560787] , [ 1288497600000 , 14.04516285753] , [ 1291093200000 , 13.697412447288] , [ 1293771600000 , 13.677681376221] , [ 1296450000000 , 19.961511864531] , [ 1298869200000 , 21.049198298158] , [ 1301544000000 , 22.687631094008] , [ 1304136000000 , 25.469010617433] , [ 1306814400000 , 24.883799437121] , [ 1309406400000 , 24.203843814248] , [ 1312084800000 , 22.138760964038] , [ 1314763200000 , 16.034636966228] , [ 1317355200000 , 15.394958944556] , [ 1320033600000 , 12.625642461969] , [ 1322629200000 , 12.973735699739] , [ 1325307600000 , 15.786018336149] , [ 1327986000000 , 15.227368020134] , [ 1330491600000 , 15.899752650734] , [ 1333166400000 , 18.994731295388] , [ 1335758400000 , 18.450055817702] , [ 1338436800000 , 17.863719889669]]\n        } ,\n        {\n            \"key\" : \"Industrials\" ,\n            \"values\" : [ [ 1138683600000 , 7.1590087090398] , [ 1141102800000 , 7.1297210970108] , [ 1143781200000 , 5.5774588290586] , [ 1146369600000 , 5.4977254491156] , [ 1149048000000 , 5.5138153113634] , [ 1151640000000 , 4.3198084032122] , [ 1154318400000 , 3.9179295839125] , [ 1156996800000 , 3.8110093051479] , [ 1159588800000 , 5.5629020916939] , [ 1162270800000 , 5.7241673711336] , [ 1164862800000 , 5.4715049695004] , [ 1167541200000 , 4.9193763571618] , [ 1170219600000 , 5.136053947247] , [ 1172638800000 , 5.1327258759766] , [ 1175313600000 , 5.1888943925082] , [ 1177905600000 , 5.5191481293345] , [ 1180584000000 , 5.6093625614921] , [ 1183176000000 , 4.2706312987397] , [ 1185854400000 , 4.4453235132117] , [ 1188532800000 , 4.6228003109761] , [ 1191124800000 , 5.0645764756954] , [ 1193803200000 , 5.0723447230959] , [ 1196398800000 , 5.1457765818846] , [ 1199077200000 , 5.4067851597282] , [ 1201755600000 , 5.472241916816] , [ 1204261200000 , 5.3742740389688] , [ 1206936000000 , 6.251751933664] , [ 1209528000000 , 6.1406852153472] , [ 1212206400000 , 5.8164385627465] , [ 1214798400000 , 5.4255846656171] , [ 1217476800000 , 5.3738499417204] , [ 1220155200000 , 5.1815627753979] , [ 1222747200000 , 5.0305983235349] , [ 1225425600000 , 4.6823058607165] , [ 1228021200000 , 4.5941481589093] , [ 1230699600000 , 5.4669598474575] , [ 1233378000000 , 5.1249037357] , [ 1235797200000 , 4.3504421250742] , [ 1238472000000 , 4.6260881026002] , [ 1241064000000 , 5.0140402458946] , [ 1243742400000 , 4.7458462454774] , [ 1246334400000 , 6.0437019654564] , [ 1249012800000 , 6.4595216249754] , [ 1251691200000 , 6.6420468254155] , [ 1254283200000 , 5.8927271960913] , [ 1256961600000 , 5.4712108838003] , [ 1259557200000 , 6.1220254207747] , [ 1262235600000 , 5.5385935169255] , [ 1264914000000 , 5.7383377612639] , [ 1267333200000 , 6.1715976730415] , [ 1270008000000 , 4.0102262681174] , [ 1272600000000 , 3.769389679692] , [ 1275278400000 , 3.5301571031152] , [ 1277870400000 , 2.7660252652526] , [ 1280548800000 , 3.1409983385775] , [ 1283227200000 , 3.0528024863055] , [ 1285819200000 , 4.3126123157971] , [ 1288497600000 , 4.594654041683] , [ 1291093200000 , 4.5424126126793] , [ 1293771600000 , 4.7790043987302] , [ 1296450000000 , 7.4969154058289] , [ 1298869200000 , 7.9424751557821] , [ 1301544000000 , 7.1560736250547] , [ 1304136000000 , 7.9478117337855] , [ 1306814400000 , 7.4109214848895] , [ 1309406400000 , 7.5966457641101] , [ 1312084800000 , 7.165754444071] , [ 1314763200000 , 5.4816702524302] , [ 1317355200000 , 4.9893656089584] , [ 1320033600000 , 4.498385105327] , [ 1322629200000 , 4.6776090358151] , [ 1325307600000 , 8.1350814368063] , [ 1327986000000 , 8.0732769990652] , [ 1330491600000 , 8.5602340387277] , [ 1333166400000 , 5.1293714074325] , [ 1335758400000 , 5.2586794619016] , [ 1338436800000 , 5.1100853569977]]\n        } ,\n        {\n            \"key\" : \"Information Technology\" ,\n            \"values\" : [ [ 1138683600000 , 13.242301508051] , [ 1141102800000 , 12.863536342042] , [ 1143781200000 , 21.034044171629] , [ 1146369600000 , 21.419084618803] , [ 1149048000000 , 21.142678863691] , [ 1151640000000 , 26.568489677529] , [ 1154318400000 , 24.839144939905] , [ 1156996800000 , 25.456187462167] , [ 1159588800000 , 26.350164502826] , [ 1162270800000 , 26.47833320519] , [ 1164862800000 , 26.425979547847] , [ 1167541200000 , 28.191461582256] , [ 1170219600000 , 28.930307448808] , [ 1172638800000 , 29.521413891117] , [ 1175313600000 , 28.188285966466] , [ 1177905600000 , 27.704619625832] , [ 1180584000000 , 27.490862424829] , [ 1183176000000 , 28.770679721286] , [ 1185854400000 , 29.060480671449] , [ 1188532800000 , 28.240998844973] , [ 1191124800000 , 33.004893194127] , [ 1193803200000 , 34.075180359928] , [ 1196398800000 , 32.548560664833] , [ 1199077200000 , 30.629727432728] , [ 1201755600000 , 28.642858788159] , [ 1204261200000 , 27.973575227842] , [ 1206936000000 , 27.393351882726] , [ 1209528000000 , 28.476095288523] , [ 1212206400000 , 29.29667866426] , [ 1214798400000 , 29.222333802896] , [ 1217476800000 , 28.092966093843] , [ 1220155200000 , 28.107159262922] , [ 1222747200000 , 25.482974832098] , [ 1225425600000 , 21.208115993834] , [ 1228021200000 , 20.295043095268] , [ 1230699600000 , 15.925754618401] , [ 1233378000000 , 17.162864628346] , [ 1235797200000 , 17.084345773174] , [ 1238472000000 , 22.246007102281] , [ 1241064000000 , 24.530543998509] , [ 1243742400000 , 25.084184918242] , [ 1246334400000 , 16.606166527358] , [ 1249012800000 , 17.239620011628] , [ 1251691200000 , 17.336739127379] , [ 1254283200000 , 25.478492475753] , [ 1256961600000 , 23.017152085245] , [ 1259557200000 , 25.617745423683] , [ 1262235600000 , 24.061133998642] , [ 1264914000000 , 23.223933318644] , [ 1267333200000 , 24.425887263937] , [ 1270008000000 , 35.501471156693] , [ 1272600000000 , 33.775013878676] , [ 1275278400000 , 30.417993630285] , [ 1277870400000 , 30.023598978467] , [ 1280548800000 , 33.327519522436] , [ 1283227200000 , 31.963388450371] , [ 1285819200000 , 30.498967232092] , [ 1288497600000 , 32.403696817912] , [ 1291093200000 , 31.47736071922] , [ 1293771600000 , 31.53259666241] , [ 1296450000000 , 41.760282761548] , [ 1298869200000 , 45.605771243237] , [ 1301544000000 , 39.986557966215] , [ 1304136000000 , 43.846330510051] , [ 1306814400000 , 39.857316881857] , [ 1309406400000 , 37.675127768208] , [ 1312084800000 , 35.775077970313] , [ 1314763200000 , 48.631009702577] , [ 1317355200000 , 42.830831754505] , [ 1320033600000 , 35.611502589362] , [ 1322629200000 , 35.320136981738] , [ 1325307600000 , 31.564136901516] , [ 1327986000000 , 32.074407502433] , [ 1330491600000 , 35.053013769976] , [ 1333166400000 , 26.434568573937] , [ 1335758400000 , 25.305617871002] , [ 1338436800000 , 24.520919418236]]\n        } ,\n        {\n            \"key\" : \"Materials\" ,\n            \"values\" : [ [ 1138683600000 , 5.5806167415681] , [ 1141102800000 , 5.4539047069985] , [ 1143781200000 , 7.6728842432362] , [ 1146369600000 , 7.719946716654] , [ 1149048000000 , 8.0144619912942] , [ 1151640000000 , 7.942223133434] , [ 1154318400000 , 8.3998279827444] , [ 1156996800000 , 8.532324572605] , [ 1159588800000 , 4.7324285199763] , [ 1162270800000 , 4.7402397487697] , [ 1164862800000 , 4.9042069355168] , [ 1167541200000 , 5.9583963430882] , [ 1170219600000 , 6.3693899239171] , [ 1172638800000 , 6.261153903813] , [ 1175313600000 , 5.3443942184584] , [ 1177905600000 , 5.4932111235361] , [ 1180584000000 , 5.5747393101109] , [ 1183176000000 , 5.3833633060013] , [ 1185854400000 , 5.5125898831832] , [ 1188532800000 , 5.8116112661327] , [ 1191124800000 , 4.3962296939996] , [ 1193803200000 , 4.6967663605521] , [ 1196398800000 , 4.7963004350914] , [ 1199077200000 , 4.1817985183351] , [ 1201755600000 , 4.3797643870182] , [ 1204261200000 , 4.6966642197965] , [ 1206936000000 , 4.3609995132565] , [ 1209528000000 , 4.4736290996496] , [ 1212206400000 , 4.3749762738128] , [ 1214798400000 , 3.3274661194507] , [ 1217476800000 , 3.0316184691337] , [ 1220155200000 , 2.5718140204728] , [ 1222747200000 , 2.7034994044603] , [ 1225425600000 , 2.2033786591364] , [ 1228021200000 , 1.9850621240805] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0.44495950017788] , [ 1256961600000 , 0.33945469262483] , [ 1259557200000 , 0.38348269455195] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0.52216435716176] , [ 1298869200000 , 0.59275786698454] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Telecommunication Services\" ,\n            \"values\" : [ [ 1138683600000 , 3.7056975170243] , [ 1141102800000 , 3.7561118692318] , [ 1143781200000 , 2.861913700854] , [ 1146369600000 , 2.9933744103381] , [ 1149048000000 , 2.7127537218463] , [ 1151640000000 , 3.1195497076283] , [ 1154318400000 , 3.4066964004508] , [ 1156996800000 , 3.3754571113569] , [ 1159588800000 , 2.2965579982924] , [ 1162270800000 , 2.4486818633018] , [ 1164862800000 , 2.4002308848517] , [ 1167541200000 , 1.9649579750349] , [ 1170219600000 , 1.9385263638056] , [ 1172638800000 , 1.9128975336387] , [ 1175313600000 , 2.3412869836298] , [ 1177905600000 , 2.4337870351445] , [ 1180584000000 , 2.62179703171] , [ 1183176000000 , 3.2642864957929] , [ 1185854400000 , 3.3200396223709] , [ 1188532800000 , 3.3934212707572] , [ 1191124800000 , 4.2822327088179] , [ 1193803200000 , 4.1474964228541] , [ 1196398800000 , 4.1477082879801] , [ 1199077200000 , 5.2947122916128] , [ 1201755600000 , 5.2919843508028] , [ 1204261200000 , 5.1989783050309] , [ 1206936000000 , 3.5603057673513] , [ 1209528000000 , 3.3009087690692] , [ 1212206400000 , 3.1784852603792] , [ 1214798400000 , 4.5889503538868] , [ 1217476800000 , 4.401779617494] , [ 1220155200000 , 4.2208301828278] , [ 1222747200000 , 3.89396671475] , [ 1225425600000 , 3.0423832241354] , [ 1228021200000 , 3.135520611578] , [ 1230699600000 , 1.9631418164089] , [ 1233378000000 , 1.8963543874958] , [ 1235797200000 , 1.8266636017025] , [ 1238472000000 , 0.93136635895188] , [ 1241064000000 , 0.92737801918888] , [ 1243742400000 , 0.97591889805002] , [ 1246334400000 , 2.6841193805515] , [ 1249012800000 , 2.5664341140531] , [ 1251691200000 , 2.3887523699873] , [ 1254283200000 , 1.1737801663681] , [ 1256961600000 , 1.0953582317281] , [ 1259557200000 , 1.2495674976653] , [ 1262235600000 , 0.36607452464754] , [ 1264914000000 , 0.3548719047291] , [ 1267333200000 , 0.36769242398939] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0.85450741275337] , [ 1288497600000 , 0.91360317921637] , [ 1291093200000 , 0.89647678692269] , [ 1293771600000 , 0.87800687192639] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0.43668720882994] , [ 1304136000000 , 0.4756523602692] , [ 1306814400000 , 0.46947368328469] , [ 1309406400000 , 0.45138896152316] , [ 1312084800000 , 0.43828726648117] , [ 1314763200000 , 2.0820861395316] , [ 1317355200000 , 0.9364411075395] , [ 1320033600000 , 0.60583907839773] , [ 1322629200000 , 0.61096950747437] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        } ,\n        {\n            \"key\" : \"Utilities\" ,\n            \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 0] , [ 1225425600000 , 0] , [ 1228021200000 , 0] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0] , [ 1256961600000 , 0] , [ 1259557200000 , 0] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n        }\n    ];\n\n    // Set some y data to null\n    var i, j, d, o;\n    for(i = 0; i < data.length; i++) {\n        d = data[i];\n        for(j = 0; j < d.values.length; j++) {\n            o = d.values[j];\n            if (j % (i + 5) == 0) {\n                o[1] = null;\n            }\n        }\n    }\n\n    var colors = d3.scale.category20();\n\n    var chart;\n    nv.addGraph(function() {\n        chart = nv.models.stackedAreaChart()\n            .useInteractiveGuideline(true)\n            .x(function(d) { return d[0] })\n            .y(function(d) { return d[1] })\n            .controlLabels({stacked: \"Stacked\"})\n            .duration(300);\n\n        chart.xAxis.tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n        chart.yAxis.tickFormat(d3.format(',.4f'));\n\n        d3.select('#chart1')\n            .datum(data)\n            .transition().duration(1000)\n            .call(chart)\n            .each('start', function() {\n                setTimeout(function() {\n                    d3.selectAll('#chart1 *').each(function() {\n                        if(this.__transition__)\n                            this.__transition__.duration = 1;\n                    })\n                }, 0)\n            });\n\n        nv.utils.windowResize(chart.update);\n        return chart;\n    });\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "test/stackedAreaChartTest.html",
    "content": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n\n<link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n<script src=\"../bower_components/d3/d3.js\"></script>\n<script src=\"../build/nv.d3.js\"></script>\n\n<link href=\"teststyle.css\" rel=\"stylesheet\" type='text/css'>\n<body>\n  <h3>Stacked area chart test cases - feel free to add more tests</h3>\n  <div class='navigation'>\n      Tests:\n      <a href=\"lineChartTest.html\">Line Chart</a>\n      <a href=\"stackedAreaChartTest.html\">Stacked Area</a>\n      <a href=\"../examples/cumulativeLineChart.html\">Cumulative Line</a>\n  </div>\n  <div class='chart full' id='chart1'>Full chart example with new tooltip and guideline<button>Select chart</button><svg></svg></div>\n  <div class='chart half with-transitions' id='chart2'>Chart with old tooltips (with-transitions)<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart3'>Chart with single point<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart4'>Chart with two points<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart5'>Chart with 'holes'<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart6'>Total random points<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart7'>Less than four points, old tooltips<button>Select chart</button><svg></svg></div>\n  <div class='chart half' id='chart8'>No data<svg></svg></div>\n  <div class='chart half' id='chart9'>Data is all negative<svg></svg></div>\n\n<script src=\"testScript.js\"></script>\n<script>\n\n\nvar histcatexplong = [\n  {\n    \"key\" : \"Consumer Discretionary\" ,\n    \"values\" : [ [ 1138683600000 , 27.38478809681] , [ 1141102800000 , 27.371377218208] , [ 1143781200000 , 26.309915460827] , [ 1146369600000 , 26.425199957521] , [ 1149048000000 , 26.823411519395] , [ 1151640000000 , 23.850443591584] , [ 1154318400000 , 23.158355444054] , [ 1156996800000 , 22.998689393694] , [ 1159588800000 , 27.977128511299] , [ 1162270800000 , 29.073672469721] , [ 1164862800000 , 28.587640408904] , [ 1167541200000 , 22.788453687638] , [ 1170219600000 , 22.429199073597] , [ 1172638800000 , 22.324103271051] , [ 1175313600000 , 17.558388444186] , [ 1177905600000 , 16.769518096208] , [ 1180584000000 , 16.214738201302] , [ 1183176000000 , 18.729632971228] , [ 1185854400000 , 18.814523318848] , [ 1188532800000 , 19.789986451358] , [ 1191124800000 , 17.070049054933] , [ 1193803200000 , 16.121349575715] , [ 1196398800000 , 15.141659430091] , [ 1199077200000 , 17.175388025298] , [ 1201755600000 , 17.286592443521] , [ 1204261200000 , 16.323141626569] , [ 1206936000000 , 19.231263773952] , [ 1209528000000 , 18.446256391094] , [ 1212206400000 , 17.822632399764] , [ 1214798400000 , 15.539366475979] , [ 1217476800000 , 15.255131790216] , [ 1220155200000 , 15.660963922593] , [ 1222747200000 , 13.254482273697] , [ 1225425600000 , 11.920796202299] , [ 1228021200000 , 12.122809090925] , [ 1230699600000 , 15.691026271393] , [ 1233378000000 , 14.720881635107] , [ 1235797200000 , 15.387939360044] , [ 1238472000000 , 13.765436672229] , [ 1241064000000 , 14.6314458648] , [ 1243742400000 , 14.292446536221] , [ 1246334400000 , 16.170071367016] , [ 1249012800000 , 15.948135554337] , [ 1251691200000 , 16.612872685134] , [ 1254283200000 , 18.778338719091] , [ 1256961600000 , 16.75602606542] , [ 1259557200000 , 19.385804443147] , [ 1262235600000 , 22.950590240168] , [ 1264914000000 , 23.61159018141] , [ 1267333200000 , 25.708586989581] , [ 1270008000000 , 26.883915999885] , [ 1272600000000 , 25.893486687065] , [ 1275278400000 , 24.678914263176] , [ 1277870400000 , 25.937275793023] , [ 1280548800000 , 29.46138169384] , [ 1283227200000 , 27.357322961862] , [ 1285819200000 , 29.057235285673] , [ 1288497600000 , 28.549434189386] , [ 1291093200000 , 28.506352379723] , [ 1293771600000 , 29.449241421597] , [ 1296450000000 , 25.796838168807] , [ 1298869200000 , 28.740145449189] , [ 1301544000000 , 22.091744141872] , [ 1304136000000 , 25.079662545409] , [ 1306814400000 , 23.674906973064] , [ 1309406400000 , 23.41800274293] , [ 1312084800000 , 23.243644138871] , [ 1314763200000 , 31.591854066817] , [ 1317355200000 , 31.497112374114] , [ 1320033600000 , 26.672380820431] , [ 1322629200000 , 27.297080015495] , [ 1325307600000 , 20.174315530051] , [ 1327986000000 , 19.631084213899] , [ 1330491600000 , 20.366462219462] , [ 1333166400000 , 17.429019937289] , [ 1335758400000 , 16.75543633539] , [ 1338436800000 , 16.182906906042]]\n  } ,\n  {\n    \"key\" : \"Consumer Staples\" ,\n    \"values\" : [ [ 1138683600000 , 7.2800122043237] , [ 1141102800000 , 7.1187787503354] , [ 1143781200000 , 8.351887016482] , [ 1146369600000 , 8.4156698763993] , [ 1149048000000 , 8.1673298604231] , [ 1151640000000 , 5.5132447126042] , [ 1154318400000 , 6.1152537710599] , [ 1156996800000 , 6.076765091942] , [ 1159588800000 , 4.6304473798646] , [ 1162270800000 , 4.6301068469402] , [ 1164862800000 , 4.3466656309389] , [ 1167541200000 , 6.830104897003] , [ 1170219600000 , 7.241633040029] , [ 1172638800000 , 7.1432372054153] , [ 1175313600000 , 10.608942063374] , [ 1177905600000 , 10.914964549494] , [ 1180584000000 , 10.933223880565] , [ 1183176000000 , 8.3457524851265] , [ 1185854400000 , 8.1078413081882] , [ 1188532800000 , 8.2697185922474] , [ 1191124800000 , 8.4742436475968] , [ 1193803200000 , 8.4994601179319] , [ 1196398800000 , 8.7387319683243] , [ 1199077200000 , 6.8829183612895] , [ 1201755600000 , 6.984133637885] , [ 1204261200000 , 7.0860136043287] , [ 1206936000000 , 4.3961787956053] , [ 1209528000000 , 3.8699674365231] , [ 1212206400000 , 3.6928925238305] , [ 1214798400000 , 6.7571718894253] , [ 1217476800000 , 6.4367313362344] , [ 1220155200000 , 6.4048441521454] , [ 1222747200000 , 5.4643833239669] , [ 1225425600000 , 5.3150786833374] , [ 1228021200000 , 5.3011272612576] , [ 1230699600000 , 4.1203601430809] , [ 1233378000000 , 4.0881783200525] , [ 1235797200000 , 4.1928665957189] , [ 1238472000000 , 7.0249415663205] , [ 1241064000000 , 7.006530880769] , [ 1243742400000 , 6.994835633224] , [ 1246334400000 , 6.1220222336254] , [ 1249012800000 , 6.1177436137653] , [ 1251691200000 , 6.1413396231981] , [ 1254283200000 , 4.8046006145874] , [ 1256961600000 , 4.6647600660544] , [ 1259557200000 , 4.544865006255] , [ 1262235600000 , 6.0488249316539] , [ 1264914000000 , 6.3188669540206] , [ 1267333200000 , 6.5873958262306] , [ 1270008000000 , 6.2281189839578] , [ 1272600000000 , 5.8948915746059] , [ 1275278400000 , 5.5967320482214] , [ 1277870400000 , 0.99784432084837] , [ 1280548800000 , 1.0950794175359] , [ 1283227200000 , 0.94479734407491] , [ 1285819200000 , 1.222093988688] , [ 1288497600000 , 1.335093106856] , [ 1291093200000 , 1.3302565104985] , [ 1293771600000 , 1.340824670897] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 4.4583692315] , [ 1320033600000 , 3.6493043348059] , [ 1322629200000 , 3.8610064091761] , [ 1325307600000 , 5.5144800685202] , [ 1327986000000 , 5.1750695220792] , [ 1330491600000 , 5.6710066952691] , [ 1333166400000 , 8.5658461590953] , [ 1335758400000 , 8.6135447714243] , [ 1338436800000 , 8.0231460925212]]\n  } ,\n  {\n    \"key\" : \"Energy\" ,\n    \"values\" : [ [ 1138683600000 , 1.544303464167] , [ 1141102800000 , 1.4387289432421] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 1.328626801128] , [ 1154318400000 , 1.2874050802627] , [ 1156996800000 , 1.0872743105593] , [ 1159588800000 , 0.96042562635813] , [ 1162270800000 , 0.93139372870616] , [ 1164862800000 , 0.94432167305385] , [ 1167541200000 , 1.277750166208] , [ 1170219600000 , 1.2204893886811] , [ 1172638800000 , 1.207489123122] , [ 1175313600000 , 1.2490651414113] , [ 1177905600000 , 1.2593129913052] , [ 1180584000000 , 1.373329808388] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 1.4516108933695] , [ 1225425600000 , 1.1856025268225] , [ 1228021200000 , 1.3430470355439] , [ 1230699600000 , 2.2752595354509] , [ 1233378000000 , 2.4031560010523] , [ 1235797200000 , 2.0822430731926] , [ 1238472000000 , 1.5640902826938] , [ 1241064000000 , 1.5812873972356] , [ 1243742400000 , 1.9462448548894] , [ 1246334400000 , 2.9464870223957] , [ 1249012800000 , 3.0744699383222] , [ 1251691200000 , 2.9422304628446] , [ 1254283200000 , 2.7503075599999] , [ 1256961600000 , 2.6506701800427] , [ 1259557200000 , 2.8005425319977] , [ 1262235600000 , 2.6816184971185] , [ 1264914000000 , 2.681206271327] , [ 1267333200000 , 2.8195488011259] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 1.0687057346382] , [ 1280548800000 , 1.2539400544134] , [ 1283227200000 , 1.1862969445955] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 1.941972859484] , [ 1298869200000 , 2.1142247697552] , [ 1301544000000 , 2.3788590206824] , [ 1304136000000 , 2.5337302877545] , [ 1306814400000 , 2.3163370395199] , [ 1309406400000 , 2.0645451843195] , [ 1312084800000 , 2.1004446672411] , [ 1314763200000 , 3.6301875804303] , [ 1317355200000 , 2.454204664652] , [ 1320033600000 , 2.196082370894] , [ 1322629200000 , 2.3358418255202] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0.39001201038526] , [ 1335758400000 , 0.30945472725559] , [ 1338436800000 , 0.31062439305591]]\n  } ,\n  {\n    \"key\" : \"Financials\" ,\n    \"values\" : [ [ 1138683600000 , 13.356778764352] , [ 1141102800000 , 13.611196863271] , [ 1143781200000 , 6.895903006119] , [ 1146369600000 , 6.9939633271352] , [ 1149048000000 , 6.7241510257675] , [ 1151640000000 , 5.5611293669516] , [ 1154318400000 , 5.6086488714041] , [ 1156996800000 , 5.4962849907033] , [ 1159588800000 , 6.9193153169279] , [ 1162270800000 , 7.0016334389777] , [ 1164862800000 , 6.7865422443273] , [ 1167541200000 , 9.0006454225383] , [ 1170219600000 , 9.2233916171431] , [ 1172638800000 , 8.8929316009479] , [ 1175313600000 , 10.345937520404] , [ 1177905600000 , 10.075914677026] , [ 1180584000000 , 10.089006188111] , [ 1183176000000 , 10.598330295008] , [ 1185854400000 , 9.968954653301] , [ 1188532800000 , 9.7740580198146] , [ 1191124800000 , 10.558483060626] , [ 1193803200000 , 9.9314651823603] , [ 1196398800000 , 9.3997715873769] , [ 1199077200000 , 8.4086493387262] , [ 1201755600000 , 8.9698309085926] , [ 1204261200000 , 8.2778357995396] , [ 1206936000000 , 8.8585045600123] , [ 1209528000000 , 8.7013756413322] , [ 1212206400000 , 7.7933605469443] , [ 1214798400000 , 7.0236183483064] , [ 1217476800000 , 6.9873088186829] , [ 1220155200000 , 6.8031713070097] , [ 1222747200000 , 6.6869531315723] , [ 1225425600000 , 6.138256993963] , [ 1228021200000 , 5.6434994016354] , [ 1230699600000 , 5.495220262512] , [ 1233378000000 , 4.6885326869846] , [ 1235797200000 , 4.4524349883438] , [ 1238472000000 , 5.6766520778185] , [ 1241064000000 , 5.7675774480752] , [ 1243742400000 , 5.7882863168337] , [ 1246334400000 , 7.2666010034924] , [ 1249012800000 , 7.519182132226] , [ 1251691200000 , 7.849651451445] , [ 1254283200000 , 10.383992037985] , [ 1256961600000 , 9.0653691861818] , [ 1259557200000 , 9.6705248324159] , [ 1262235600000 , 10.856380561349] , [ 1264914000000 , 11.27452370892] , [ 1267333200000 , 11.754156529088] , [ 1270008000000 , 8.2870811422456] , [ 1272600000000 , 8.0210264360699] , [ 1275278400000 , 7.5375074474865] , [ 1277870400000 , 8.3419527338039] , [ 1280548800000 , 9.4197471818443] , [ 1283227200000 , 8.7321733185797] , [ 1285819200000 , 9.6627062648126] , [ 1288497600000 , 10.187962234549] , [ 1291093200000 , 9.8144201733476] , [ 1293771600000 , 10.275723361713] , [ 1296450000000 , 16.796066079353] , [ 1298869200000 , 17.543254984075] , [ 1301544000000 , 16.673660675084] , [ 1304136000000 , 17.963944353609] , [ 1306814400000 , 16.637740867211] , [ 1309406400000 , 15.84857094609] , [ 1312084800000 , 14.767303362182] , [ 1314763200000 , 24.778452182432] , [ 1317355200000 , 18.370353229999] , [ 1320033600000 , 15.2531374291] , [ 1322629200000 , 14.989600840649] , [ 1325307600000 , 16.052539160125] , [ 1327986000000 , 16.424390322793] , [ 1330491600000 , 17.884020741105] , [ 1333166400000 , 7.1424929577921] , [ 1335758400000 , 7.8076213051482] , [ 1338436800000 , 7.2462684949232]]\n  } ,\n  {\n    \"key\" : \"Health Care\" ,\n    \"values\" : [ [ 1138683600000 , 14.212410956029] , [ 1141102800000 , 13.973193618249] , [ 1143781200000 , 15.218233920665] , [ 1146369600000 , 14.38210972745] , [ 1149048000000 , 13.894310878491] , [ 1151640000000 , 15.593086090032] , [ 1154318400000 , 16.244839695188] , [ 1156996800000 , 16.017088850646] , [ 1159588800000 , 14.183951830055] , [ 1162270800000 , 14.148523245697] , [ 1164862800000 , 13.424326059972] , [ 1167541200000 , 12.974450435753] , [ 1170219600000 , 13.23247041802] , [ 1172638800000 , 13.318762655574] , [ 1175313600000 , 15.961407746104] , [ 1177905600000 , 16.287714639805] , [ 1180584000000 , 16.246590583889] , [ 1183176000000 , 17.564505594809] , [ 1185854400000 , 17.872725373165] , [ 1188532800000 , 18.018998508757] , [ 1191124800000 , 15.584518016603] , [ 1193803200000 , 15.480850647181] , [ 1196398800000 , 15.699120036984] , [ 1199077200000 , 19.184281817226] , [ 1201755600000 , 19.691226605207] , [ 1204261200000 , 18.982314051295] , [ 1206936000000 , 18.707820309008] , [ 1209528000000 , 17.459630929761] , [ 1212206400000 , 16.500616076782] , [ 1214798400000 , 18.086324003979] , [ 1217476800000 , 18.929464156258] , [ 1220155200000 , 18.233728682084] , [ 1222747200000 , 16.315776297325] , [ 1225425600000 , 14.63289219025] , [ 1228021200000 , 14.667835024478] , [ 1230699600000 , 13.946993947308] , [ 1233378000000 , 14.394304684397] , [ 1235797200000 , 13.724462792967] , [ 1238472000000 , 10.930879035806] , [ 1241064000000 , 9.8339915513708] , [ 1243742400000 , 10.053858541872] , [ 1246334400000 , 11.786998438287] , [ 1249012800000 , 11.780994901769] , [ 1251691200000 , 11.305889670276] , [ 1254283200000 , 10.918452290083] , [ 1256961600000 , 9.6811395055706] , [ 1259557200000 , 10.971529744038] , [ 1262235600000 , 13.330210480209] , [ 1264914000000 , 14.592637568961] , [ 1267333200000 , 14.605329141157] , [ 1270008000000 , 13.936853794037] , [ 1272600000000 , 12.189480759072] , [ 1275278400000 , 11.676151385046] , [ 1277870400000 , 13.058852800017] , [ 1280548800000 , 13.62891543203] , [ 1283227200000 , 13.811107569918] , [ 1285819200000 , 13.786494560787] , [ 1288497600000 , 14.04516285753] , [ 1291093200000 , 13.697412447288] , [ 1293771600000 , 13.677681376221] , [ 1296450000000 , 19.961511864531] , [ 1298869200000 , 21.049198298158] , [ 1301544000000 , 22.687631094008] , [ 1304136000000 , 25.469010617433] , [ 1306814400000 , 24.883799437121] , [ 1309406400000 , 24.203843814248] , [ 1312084800000 , 22.138760964038] , [ 1314763200000 , 16.034636966228] , [ 1317355200000 , 15.394958944556] , [ 1320033600000 , 12.625642461969] , [ 1322629200000 , 12.973735699739] , [ 1325307600000 , 15.786018336149] , [ 1327986000000 , 15.227368020134] , [ 1330491600000 , 15.899752650734] , [ 1333166400000 , 18.994731295388] , [ 1335758400000 , 18.450055817702] , [ 1338436800000 , 17.863719889669]]\n  } ,\n  {\n    \"key\" : \"Industrials\" ,\n    \"values\" : [ [ 1138683600000 , 7.1590087090398] , [ 1141102800000 , 7.1297210970108] , [ 1143781200000 , 5.5774588290586] , [ 1146369600000 , 5.4977254491156] , [ 1149048000000 , 5.5138153113634] , [ 1151640000000 , 4.3198084032122] , [ 1154318400000 , 3.9179295839125] , [ 1156996800000 , 3.8110093051479] , [ 1159588800000 , 5.5629020916939] , [ 1162270800000 , 5.7241673711336] , [ 1164862800000 , 5.4715049695004] , [ 1167541200000 , 4.9193763571618] , [ 1170219600000 , 5.136053947247] , [ 1172638800000 , 5.1327258759766] , [ 1175313600000 , 5.1888943925082] , [ 1177905600000 , 5.5191481293345] , [ 1180584000000 , 5.6093625614921] , [ 1183176000000 , 4.2706312987397] , [ 1185854400000 , 4.4453235132117] , [ 1188532800000 , 4.6228003109761] , [ 1191124800000 , 5.0645764756954] , [ 1193803200000 , 5.0723447230959] , [ 1196398800000 , 5.1457765818846] , [ 1199077200000 , 5.4067851597282] , [ 1201755600000 , 5.472241916816] , [ 1204261200000 , 5.3742740389688] , [ 1206936000000 , 6.251751933664] , [ 1209528000000 , 6.1406852153472] , [ 1212206400000 , 5.8164385627465] , [ 1214798400000 , 5.4255846656171] , [ 1217476800000 , 5.3738499417204] , [ 1220155200000 , 5.1815627753979] , [ 1222747200000 , 5.0305983235349] , [ 1225425600000 , 4.6823058607165] , [ 1228021200000 , 4.5941481589093] , [ 1230699600000 , 5.4669598474575] , [ 1233378000000 , 5.1249037357] , [ 1235797200000 , 4.3504421250742] , [ 1238472000000 , 4.6260881026002] , [ 1241064000000 , 5.0140402458946] , [ 1243742400000 , 4.7458462454774] , [ 1246334400000 , 6.0437019654564] , [ 1249012800000 , 6.4595216249754] , [ 1251691200000 , 6.6420468254155] , [ 1254283200000 , 5.8927271960913] , [ 1256961600000 , 5.4712108838003] , [ 1259557200000 , 6.1220254207747] , [ 1262235600000 , 5.5385935169255] , [ 1264914000000 , 5.7383377612639] , [ 1267333200000 , 6.1715976730415] , [ 1270008000000 , 4.0102262681174] , [ 1272600000000 , 3.769389679692] , [ 1275278400000 , 3.5301571031152] , [ 1277870400000 , 2.7660252652526] , [ 1280548800000 , 3.1409983385775] , [ 1283227200000 , 3.0528024863055] , [ 1285819200000 , 4.3126123157971] , [ 1288497600000 , 4.594654041683] , [ 1291093200000 , 4.5424126126793] , [ 1293771600000 , 4.7790043987302] , [ 1296450000000 , 7.4969154058289] , [ 1298869200000 , 7.9424751557821] , [ 1301544000000 , 7.1560736250547] , [ 1304136000000 , 7.9478117337855] , [ 1306814400000 , 7.4109214848895] , [ 1309406400000 , 7.5966457641101] , [ 1312084800000 , 7.165754444071] , [ 1314763200000 , 5.4816702524302] , [ 1317355200000 , 4.9893656089584] , [ 1320033600000 , 4.498385105327] , [ 1322629200000 , 4.6776090358151] , [ 1325307600000 , 8.1350814368063] , [ 1327986000000 , 8.0732769990652] , [ 1330491600000 , 8.5602340387277] , [ 1333166400000 , 5.1293714074325] , [ 1335758400000 , 5.2586794619016] , [ 1338436800000 , 5.1100853569977]]\n  } ,\n  {\n    \"key\" : \"Information Technology\" ,\n    \"values\" : [ [ 1138683600000 , 13.242301508051] , [ 1141102800000 , 12.863536342042] , [ 1143781200000 , 21.034044171629] , [ 1146369600000 , 21.419084618803] , [ 1149048000000 , 21.142678863691] , [ 1151640000000 , 26.568489677529] , [ 1154318400000 , 24.839144939905] , [ 1156996800000 , 25.456187462167] , [ 1159588800000 , 26.350164502826] , [ 1162270800000 , 26.47833320519] , [ 1164862800000 , 26.425979547847] , [ 1167541200000 , 28.191461582256] , [ 1170219600000 , 28.930307448808] , [ 1172638800000 , 29.521413891117] , [ 1175313600000 , 28.188285966466] , [ 1177905600000 , 27.704619625832] , [ 1180584000000 , 27.490862424829] , [ 1183176000000 , 28.770679721286] , [ 1185854400000 , 29.060480671449] , [ 1188532800000 , 28.240998844973] , [ 1191124800000 , 33.004893194127] , [ 1193803200000 , 34.075180359928] , [ 1196398800000 , 32.548560664833] , [ 1199077200000 , 30.629727432728] , [ 1201755600000 , 28.642858788159] , [ 1204261200000 , 27.973575227842] , [ 1206936000000 , 27.393351882726] , [ 1209528000000 , 28.476095288523] , [ 1212206400000 , 29.29667866426] , [ 1214798400000 , 29.222333802896] , [ 1217476800000 , 28.092966093843] , [ 1220155200000 , 28.107159262922] , [ 1222747200000 , 25.482974832098] , [ 1225425600000 , 21.208115993834] , [ 1228021200000 , 20.295043095268] , [ 1230699600000 , 15.925754618401] , [ 1233378000000 , 17.162864628346] , [ 1235797200000 , 17.084345773174] , [ 1238472000000 , 22.246007102281] , [ 1241064000000 , 24.530543998509] , [ 1243742400000 , 25.084184918242] , [ 1246334400000 , 16.606166527358] , [ 1249012800000 , 17.239620011628] , [ 1251691200000 , 17.336739127379] , [ 1254283200000 , 25.478492475753] , [ 1256961600000 , 23.017152085245] , [ 1259557200000 , 25.617745423683] , [ 1262235600000 , 24.061133998642] , [ 1264914000000 , 23.223933318644] , [ 1267333200000 , 24.425887263937] , [ 1270008000000 , 35.501471156693] , [ 1272600000000 , 33.775013878676] , [ 1275278400000 , 30.417993630285] , [ 1277870400000 , 30.023598978467] , [ 1280548800000 , 33.327519522436] , [ 1283227200000 , 31.963388450371] , [ 1285819200000 , 30.498967232092] , [ 1288497600000 , 32.403696817912] , [ 1291093200000 , 31.47736071922] , [ 1293771600000 , 31.53259666241] , [ 1296450000000 , 41.760282761548] , [ 1298869200000 , 45.605771243237] , [ 1301544000000 , 39.986557966215] , [ 1304136000000 , 43.846330510051] , [ 1306814400000 , 39.857316881857] , [ 1309406400000 , 37.675127768208] , [ 1312084800000 , 35.775077970313] , [ 1314763200000 , 48.631009702577] , [ 1317355200000 , 42.830831754505] , [ 1320033600000 , 35.611502589362] , [ 1322629200000 , 35.320136981738] , [ 1325307600000 , 31.564136901516] , [ 1327986000000 , 32.074407502433] , [ 1330491600000 , 35.053013769976] , [ 1333166400000 , 26.434568573937] , [ 1335758400000 , 25.305617871002] , [ 1338436800000 , 24.520919418236]]\n  } ,\n  {\n    \"key\" : \"Materials\" ,\n    \"values\" : [ [ 1138683600000 , 5.5806167415681] , [ 1141102800000 , 5.4539047069985] , [ 1143781200000 , 7.6728842432362] , [ 1146369600000 , 7.719946716654] , [ 1149048000000 , 8.0144619912942] , [ 1151640000000 , 7.942223133434] , [ 1154318400000 , 8.3998279827444] , [ 1156996800000 , 8.532324572605] , [ 1159588800000 , 4.7324285199763] , [ 1162270800000 , 4.7402397487697] , [ 1164862800000 , 4.9042069355168] , [ 1167541200000 , 5.9583963430882] , [ 1170219600000 , 6.3693899239171] , [ 1172638800000 , 6.261153903813] , [ 1175313600000 , 5.3443942184584] , [ 1177905600000 , 5.4932111235361] , [ 1180584000000 , 5.5747393101109] , [ 1183176000000 , 5.3833633060013] , [ 1185854400000 , 5.5125898831832] , [ 1188532800000 , 5.8116112661327] , [ 1191124800000 , 4.3962296939996] , [ 1193803200000 , 4.6967663605521] , [ 1196398800000 , 4.7963004350914] , [ 1199077200000 , 4.1817985183351] , [ 1201755600000 , 4.3797643870182] , [ 1204261200000 , 4.6966642197965] , [ 1206936000000 , 4.3609995132565] , [ 1209528000000 , 4.4736290996496] , [ 1212206400000 , 4.3749762738128] , [ 1214798400000 , 3.3274661194507] , [ 1217476800000 , 3.0316184691337] , [ 1220155200000 , 2.5718140204728] , [ 1222747200000 , 2.7034994044603] , [ 1225425600000 , 2.2033786591364] , [ 1228021200000 , 1.9850621240805] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0.44495950017788] , [ 1256961600000 , 0.33945469262483] , [ 1259557200000 , 0.38348269455195] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0.52216435716176] , [ 1298869200000 , 0.59275786698454] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n  } ,\n  {\n    \"key\" : \"Telecommunication Services\" ,\n    \"values\" : [ [ 1138683600000 , 3.7056975170243] , [ 1141102800000 , 3.7561118692318] , [ 1143781200000 , 2.861913700854] , [ 1146369600000 , 2.9933744103381] , [ 1149048000000 , 2.7127537218463] , [ 1151640000000 , 3.1195497076283] , [ 1154318400000 , 3.4066964004508] , [ 1156996800000 , 3.3754571113569] , [ 1159588800000 , 2.2965579982924] , [ 1162270800000 , 2.4486818633018] , [ 1164862800000 , 2.4002308848517] , [ 1167541200000 , 1.9649579750349] , [ 1170219600000 , 1.9385263638056] , [ 1172638800000 , 1.9128975336387] , [ 1175313600000 , 2.3412869836298] , [ 1177905600000 , 2.4337870351445] , [ 1180584000000 , 2.62179703171] , [ 1183176000000 , 3.2642864957929] , [ 1185854400000 , 3.3200396223709] , [ 1188532800000 , 3.3934212707572] , [ 1191124800000 , 4.2822327088179] , [ 1193803200000 , 4.1474964228541] , [ 1196398800000 , 4.1477082879801] , [ 1199077200000 , 5.2947122916128] , [ 1201755600000 , 5.2919843508028] , [ 1204261200000 , 5.1989783050309] , [ 1206936000000 , 3.5603057673513] , [ 1209528000000 , 3.3009087690692] , [ 1212206400000 , 3.1784852603792] , [ 1214798400000 , 4.5889503538868] , [ 1217476800000 , 4.401779617494] , [ 1220155200000 , 4.2208301828278] , [ 1222747200000 , 3.89396671475] , [ 1225425600000 , 3.0423832241354] , [ 1228021200000 , 3.135520611578] , [ 1230699600000 , 1.9631418164089] , [ 1233378000000 , 1.8963543874958] , [ 1235797200000 , 1.8266636017025] , [ 1238472000000 , 0.93136635895188] , [ 1241064000000 , 0.92737801918888] , [ 1243742400000 , 0.97591889805002] , [ 1246334400000 , 2.6841193805515] , [ 1249012800000 , 2.5664341140531] , [ 1251691200000 , 2.3887523699873] , [ 1254283200000 , 1.1737801663681] , [ 1256961600000 , 1.0953582317281] , [ 1259557200000 , 1.2495674976653] , [ 1262235600000 , 0.36607452464754] , [ 1264914000000 , 0.3548719047291] , [ 1267333200000 , 0.36769242398939] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0.85450741275337] , [ 1288497600000 , 0.91360317921637] , [ 1291093200000 , 0.89647678692269] , [ 1293771600000 , 0.87800687192639] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0.43668720882994] , [ 1304136000000 , 0.4756523602692] , [ 1306814400000 , 0.46947368328469] , [ 1309406400000 , 0.45138896152316] , [ 1312084800000 , 0.43828726648117] , [ 1314763200000 , 2.0820861395316] , [ 1317355200000 , 0.9364411075395] , [ 1320033600000 , 0.60583907839773] , [ 1322629200000 , 0.61096950747437] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n  } ,\n  {\n    \"key\" : \"Utilities\" ,\n    \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , 0] , [ 1217476800000 , 0] , [ 1220155200000 , 0] , [ 1222747200000 , 0] , [ 1225425600000 , 0] , [ 1228021200000 , 0] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , 0] , [ 1256961600000 , 0] , [ 1259557200000 , 0] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n  }\n];\n\n\n// for testing single data point\nvar histcatexplong_singledatapoint = [\n  {\n    \"key\" : \"Consumer Discretionary\" ,\n    \"values\" : [ [ 1138683600000 , 27.38478809681]]\n  } ,\n  {\n    \"key\" : \"Consumer Staples\" ,\n    \"values\" : [ [ 1138683600000 , 7.2800122043237]]\n  } ,\n  {\n    \"key\" : \"Energy\" ,\n    \"values\" : [ [ 1138683600000 , 1.544303464167]]\n  } ,\n  {\n    \"key\" : \"Financials\" ,\n    \"values\" : [ [ 1138683600000 , 13.356778764352]]\n  } ,\n  {\n    \"key\" : \"Health Care\" ,\n    \"values\" : [ [ 1138683600000 , 14.212410956029]]\n  } ,\n  {\n    \"key\" : \"Industrials\" ,\n    \"values\" : [ [ 1138683600000 , 7.1590087090398]]\n  } ,\n  {\n    \"key\" : \"Information Technology\" ,\n    \"values\" : [ [ 1138683600000 , 13.242301508051]]\n  } ,\n  {\n    \"key\" : \"Materials\" ,\n    \"values\" : [ [ 1138683600000 , 5.5806167415681]]\n  } ,\n  {\n    \"key\" : \"Telecommunication Services\" ,\n    \"values\" : [ [ 1138683600000 , 3.7056975170243]]\n  } ,\n  {\n    \"key\" : \"Utilities\" ,\n    \"values\" : [ [ 1138683600000 , 0]]\n  }\n];\n\n\n// for testing two data point s\nvar histcatexplong_twodatapoint = [\n  {\n    \"key\" : \"Consumer Discretionary\" ,\n    \"values\" : [ [ 1138683600000 , 27.38478809681], [ 1141102800000 , 29.4] ]\n  } ,\n  {\n    \"key\" : \"Consumer Staples\" ,\n    \"values\" : [ [ 1138683600000 , 7.2800122043237], [ 1141102800000 , 6.7]]\n  } ,\n  {\n    \"key\" : \"Energy\" ,\n    \"values\" : [ [ 1138683600000 , 1.544303464167], [ 1141102800000 , 2.4]]\n  } ,\n  {\n    \"key\" : \"Financials\" ,\n    \"values\" : [ [ 1138683600000 , 13.356778764352], [ 1141102800000 , 19.2]]\n  } ,\n  {\n    \"key\" : \"Health Care\" ,\n    \"values\" : [ [ 1138683600000 , 14.212410956029], [ 1141102800000 , 15.4]]\n  } ,\n  {\n    \"key\" : \"Industrials\" ,\n    \"values\" : [ [ 1138683600000 , 7.1590087090398], [ 1141102800000 , 10.3]]\n  } ,\n  {\n    \"key\" : \"Information Technology\" ,\n    \"values\" : [ [ 1138683600000 , 13.242301508051], [ 1141102800000 , 14.3]]\n  } ,\n  {\n    \"key\" : \"Materials\" ,\n    \"values\" : [ [ 1138683600000 , 5.5806167415681], [ 1141102800000 , 3.2]]\n  } ,\n  {\n    \"key\" : \"Telecommunication Services\" ,\n    \"values\" : [ [ 1138683600000 , 3.7056975170243], [ 1141102800000 , 1.3]]\n  } ,\n  {\n    \"key\" : \"Utilities\" ,\n    \"values\" : [ [ 1138683600000 , 0], [ 1141102800000 , 2]]\n  }\n];\n\nvar histcatexplong_withholes = [\n  {\n    \"key\" : \"Consumer Discretionary\" ,\n    \"values\" : [ [ 1138683600000 , 27.38478809681] , [ 1141102800000 , 27.371377218208] , [ 1143781200000 , 26.309915460827] , [ 1146369600000 , 26.425199957521] , [ 1149048000000 , 26.823411519395] , [ 1151640000000 , 23.850443591584] , [ 1154318400000 , 23.158355444054] , [ 1156996800000 , 22.998689393694] , [ 1159588800000 , 27.977128511299] , [ 1162270800000 , 29.073672469721] , [ 1164862800000 , 28.587640408904] , [ 1167541200000 , 22.788453687638] , [ 1170219600000 , 22.429199073597] , [ 1172638800000 , 22.324103271051] , [ 1175313600000 , 17.558388444186] , [ 1177905600000 , 16.769518096208] , [ 1180584000000 , 16.214738201302] , [ 1183176000000 , 18.729632971228] , [ 1185854400000 , 18.814523318848] , [ 1188532800000 , 19.789986451358] , [ 1191124800000 , 17.070049054933] , [ 1193803200000 , 16.121349575715] , [ 1196398800000 , 15.141659430091] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 19.231263773952] , [ 1209528000000 , 18.446256391094] , [ 1212206400000 , 17.822632399764] , [ 1214798400000 , 15.539366475979] , [ 1217476800000 , 15.255131790216] , [ 1220155200000 , 15.660963922593] , [ 1222747200000 , 13.254482273697] , [ 1225425600000 , 11.920796202299] , [ 1228021200000 , 12.122809090925] , [ 1230699600000 , 15.691026271393] , [ 1233378000000 , 14.720881635107] , [ 1235797200000 , 15.387939360044] , [ 1238472000000 , 13.765436672229] , [ 1241064000000 , 14.6314458648] , [ 1243742400000 , 14.292446536221] , [ 1246334400000 , 16.170071367016] , [ 1249012800000 , 15.948135554337] , [ 1251691200000 , 16.612872685134] , [ 1254283200000 , 18.778338719091] , [ 1256961600000 , 16.75602606542] , [ 1259557200000 , 19.385804443147] , [ 1262235600000 , 22.950590240168] , [ 1264914000000 , 23.61159018141] , [ 1267333200000 , 25.708586989581] , [ 1270008000000 , 26.883915999885] , [ 1272600000000 , 25.893486687065] , [ 1275278400000 , 24.678914263176] , [ 1277870400000 , 25.937275793023] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 29.057235285673] , [ 1288497600000 , 28.549434189386] , [ 1291093200000 , 28.506352379723] , [ 1293771600000 , 29.449241421597] , [ 1296450000000 , 25.796838168807] , [ 1298869200000 , 28.740145449189] , [ 1301544000000 , 22.091744141872] , [ 1304136000000 , 25.079662545409] , [ 1306814400000 , 23.674906973064] , [ 1309406400000 , 23.41800274293] , [ 1312084800000 , 23.243644138871] , [ 1314763200000 , 31.591854066817] , [ 1317355200000 , 31.497112374114] , [ 1320033600000 , 26.672380820431] , [ 1322629200000 , 27.297080015495] , [ 1325307600000 , 20.174315530051] , [ 1327986000000 , 19.631084213899] , [ 1330491600000 , 20.366462219462] , [ 1333166400000 , 17.429019937289] , [ 1335758400000 , 16.75543633539] , [ 1338436800000 , 16.182906906042]]\n  } ,\n  {\n    \"key\" : \"Consumer Staples\" ,\n    \"values\" : [ [ 1138683600000 , 7.2800122043237] , [ 1141102800000 , 7.1187787503354] , [ 1143781200000 , 8.351887016482] , [ 1146369600000 , 8.4156698763993] , [ 1149048000000 , 8.1673298604231] , [ 1151640000000 , 5.5132447126042] , [ 1154318400000 , 6.1152537710599] , [ 1156996800000 , 6.076765091942] , [ 1159588800000 , 4.6304473798646] , [ 1162270800000 , 4.6301068469402] , [ 1164862800000 , 4.3466656309389] , [ 1167541200000 , 6.830104897003] , [ 1170219600000 , 7.241633040029] , [ 1172638800000 , 7.1432372054153] , [ 1175313600000 , 10.608942063374] , [ 1177905600000 , 10.914964549494] , [ 1180584000000 , 10.933223880565] , [ 1183176000000 , 8.3457524851265] , [ 1185854400000 , 8.1078413081882] , [ 1188532800000 , 8.2697185922474] , [ 1191124800000 , 8.4742436475968] , [ 1193803200000 , 8.4994601179319] , [ 1196398800000 , 8.7387319683243] , [ 1199077200000 , 6.8829183612895] , [ 1201755600000 , 6.984133637885] , [ 1204261200000 , 7.0860136043287] , [ 1206936000000 , 4.3961787956053] , [ 1209528000000 , 3.8699674365231] , [ 1212206400000 , 3.6928925238305] , [ 1214798400000 , 6.7571718894253] , [ 1217476800000 , 6.4367313362344] , [ 1220155200000 , 6.4048441521454] , [ 1222747200000 , 5.4643833239669] , [ 1225425600000 , 5.3150786833374] , [ 1228021200000 , 5.3011272612576] , [ 1230699600000 , 4.1203601430809] , [ 1233378000000 , 4.0881783200525] , [ 1235797200000 , 4.1928665957189] , [ 1238472000000 , 7.0249415663205] , [ 1241064000000 , 7.006530880769] , [ 1243742400000 , 6.994835633224] , [ 1246334400000 , 6.1220222336254] , [ 1249012800000 , 6.1177436137653] , [ 1251691200000 , 6.1413396231981] , [ 1254283200000 , 4.8046006145874] , [ 1256961600000 , 4.6647600660544] , [ 1259557200000 , 4.544865006255] , [ 1262235600000 , 6.0488249316539] , [ 1264914000000 , 6.3188669540206] , [ 1267333200000 , 6.5873958262306] , [ 1270008000000 , 6.2281189839578] , [ 1272600000000 , 5.8948915746059] , [ 1275278400000 , 5.5967320482214] , [ 1277870400000 , 0.99784432084837] , [ 1280548800000 , 1.0950794175359] , [ 1283227200000 , 0.94479734407491] , [ 1285819200000 , 1.222093988688] , [ 1288497600000 , 1.335093106856] , [ 1291093200000 , 1.3302565104985] , [ 1293771600000 , 1.340824670897] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 4.4583692315] , [ 1320033600000 , 3.6493043348059] , [ 1322629200000 , 3.8610064091761] , [ 1325307600000 , 5.5144800685202] , [ 1327986000000 , 5.1750695220792] , [ 1330491600000 , 5.6710066952691] , [ 1333166400000 , 8.5658461590953] , [ 1335758400000 , 8.6135447714243] , [ 1338436800000 , 8.0231460925212]]\n  }];\n\nvar histcatexpshort = [\n  {\n    \"key\" : \"Consumer Staples\" ,\n    \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , -0.24102139376003] , [ 1170219600000 , -0.69960584365035] , [ 1172638800000 , -0.67365051426185] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , -0.31429312464988] , [ 1185854400000 , -0.90018700397153] , [ 1188532800000 , -0.96926214328714] , [ 1191124800000 , -1.1343386468131] , [ 1193803200000 , -1.1335426595455] , [ 1196398800000 , -1.2327663032424] , [ 1199077200000 , -0.41027135492155] , [ 1201755600000 , -0.41779167524802] , [ 1204261200000 , -0.38133883625885] , [ 1206936000000 , 0] , [ 1209528000000 , -0.32550520320253] , [ 1212206400000 , -0.33185144615505] , [ 1214798400000 , -0.68609668877894] , [ 1217476800000 , -0.70001207744308] , [ 1220155200000 , -0.68378680840919] , [ 1222747200000 , -0.40908783182034] , [ 1225425600000 , -0.39074266525646] , [ 1228021200000 , -0.40358490474562] , [ 1230699600000 , -0.85752207262267] , [ 1233378000000 , -0.74395750438805] , [ 1235797200000 , -0.70718832429489] , [ 1238472000000 , -0.76244465406965] , [ 1241064000000 , -0.67618572591984] , [ 1243742400000 , -0.67649596761402] , [ 1246334400000 , -0.94618002703247] , [ 1249012800000 , -0.95408485581014] , [ 1251691200000 , -0.96272139504276] , [ 1254283200000 , 0] , [ 1256961600000 , 0] , [ 1259557200000 , 0] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , -0.25516420149471] , [ 1272600000000 , -0.24106264576017] , [ 1275278400000 , -0.22802547751448] , [ 1277870400000 , -0.62187524046697] , [ 1280548800000 , -0.72155608677106] , [ 1283227200000 , -0.70221659944774] , [ 1285819200000 , -1.1117002584543] , [ 1288497600000 , -1.190911001336] , [ 1291093200000 , -1.1781082003972] , [ 1293771600000 , -1.2125860264875] , [ 1296450000000 , -1.7748010365657] , [ 1298869200000 , -1.8919594178596] , [ 1301544000000 , -1.7077946421533] , [ 1304136000000 , -2.024238803094] , [ 1306814400000 , -1.9769844081819] , [ 1309406400000 , -2.0730275464065] , [ 1312084800000 , -1.9690128240888] , [ 1314763200000 , -5.5557852269348] , [ 1317355200000 , -7.2527933190641] , [ 1320033600000 , -5.7367677053109] , [ 1322629200000 , -6.0409316206662] , [ 1325307600000 , -4.6511525539195] , [ 1327986000000 , -4.526116059083] , [ 1330491600000 , -4.846292325197] , [ 1333166400000 , -2.2663198779425] , [ 1335758400000 , -2.4172072568564] , [ 1338436800000 , -2.3204729601189]]\n  } ,\n  {\n    \"key\" : \"Consumer Discretionary\" ,\n    \"values\" : [ [ 1138683600000 , -0.62238434102863] , [ 1141102800000 , -0.61484565039024] , [ 1143781200000 , -1.0769367918668] , [ 1146369600000 , -1.2221156604129] , [ 1149048000000 , -1.2434858263377] , [ 1151640000000 , -0.58606435489597] , [ 1154318400000 , -0.61478911495141] , [ 1156996800000 , -0.61429362688591] , [ 1159588800000 , -1.1168614112788] , [ 1162270800000 , -1.1510268716612] , [ 1164862800000 , -1.1104724164222] , [ 1167541200000 , -1.2298338563471] , [ 1170219600000 , -1.5053664389104] , [ 1172638800000 , -1.5535266372193] , [ 1175313600000 , -3.1690472535854] , [ 1177905600000 , -3.1273013967041] , [ 1180584000000 , -3.155466271777] , [ 1183176000000 , -3.7158562579437] , [ 1185854400000 , -3.8244546635586] , [ 1188532800000 , -3.5524464859972] , [ 1191124800000 , -3.0472339109128] , [ 1193803200000 , -3.064978140815] , [ 1196398800000 , -3.0818130124986] , [ 1199077200000 , -2.9806791138312] , [ 1201755600000 , -3.7360958775824] , [ 1204261200000 , -3.4687841733263] , [ 1206936000000 , -3.3702018615806] , [ 1209528000000 , -3.1982756208679] , [ 1212206400000 , -3.0489433155104] , [ 1214798400000 , -3.7008275605963] , [ 1217476800000 , -3.8980507260892] , [ 1220155200000 , -3.7680083260241] , [ 1222747200000 , -3.2061890012391] , [ 1225425600000 , -2.6727551440484] , [ 1228021200000 , -2.4469327462935] , [ 1230699600000 , -3.0192419668784] , [ 1233378000000 , -2.892958553476] , [ 1235797200000 , -3.1153570053479] , [ 1238472000000 , -2.9927580570711] , [ 1241064000000 , -3.5061796706294] , [ 1243742400000 , -3.2944159516725] , [ 1246334400000 , -3.4154213240617] , [ 1249012800000 , -3.6492125438171] , [ 1251691200000 , -3.6674164998394] , [ 1254283200000 , -4.6271484977727] , [ 1256961600000 , -4.2433407292676] , [ 1259557200000 , -4.4742625247274] , [ 1262235600000 , -5.2078214612359] , [ 1264914000000 , -5.2209579214469] , [ 1267333200000 , -5.4596395756061] , [ 1270008000000 , -5.6906459276584] , [ 1272600000000 , -6.4981737808665] , [ 1275278400000 , -6.2563044048578] , [ 1277870400000 , -6.175479487959] , [ 1280548800000 , -6.6641002427295] , [ 1283227200000 , -6.3648667745556] , [ 1285819200000 , -5.0270168607884] , [ 1288497600000 , -5.1186072976233] , [ 1291093200000 , -5.1127601587872] , [ 1293771600000 , -5.3015262972641] , [ 1296450000000 , -4.4295728671596] , [ 1298869200000 , -4.5488139745696] , [ 1301544000000 , -2.9021260315957] , [ 1304136000000 , -3.1482096241139] , [ 1306814400000 , -2.8648831814763] , [ 1309406400000 , -2.8149423433441] , [ 1312084800000 , -2.6350669145713] , [ 1314763200000 , -5.9871754759038] , [ 1317355200000 , -8.6127555816399] , [ 1320033600000 , -7.0712887348892] , [ 1322629200000 , -7.3930257999857] , [ 1325307600000 , -6.5183071556304] , [ 1327986000000 , -7.4388913793503] , [ 1330491600000 , -8.2134465182649] , [ 1333166400000 , -7.7836036697105] , [ 1335758400000 , -8.0955053683936] , [ 1338436800000 , -8.0981845818893]]\n  } ,\n  {\n    \"key\" : \"Energy\" ,\n    \"values\" : [ [ 1138683600000 , -0.95707527558303] , [ 1141102800000 , -0.78324346694487] , [ 1143781200000 , -1.2905241058019] , [ 1146369600000 , -1.3880880486779] , [ 1149048000000 , -1.3337247185993] , [ 1151640000000 , -1.0342112071924] , [ 1154318400000 , -1.1264764100183] , [ 1156996800000 , -1.0001002640852] , [ 1159588800000 , -0.85341153093953] , [ 1162270800000 , -0.88452017844596] , [ 1164862800000 , -0.84305725300642] , [ 1167541200000 , -1.0874455682301] , [ 1170219600000 , -1.1714969043168] , [ 1172638800000 , -1.1445856467934] , [ 1175313600000 , -1.1928513334073] , [ 1177905600000 , -1.2365691634265] , [ 1180584000000 , -1.2690940962478] , [ 1183176000000 , -1.662233774695] , [ 1185854400000 , -1.745760538781] , [ 1188532800000 , -1.5209200931271] , [ 1191124800000 , -1.7874791820886] , [ 1193803200000 , -1.7755668105117] , [ 1196398800000 , -1.5456069064618] , [ 1199077200000 , -1.7077541586335] , [ 1201755600000 , -1.6462081650757] , [ 1204261200000 , -1.8624735339628] , [ 1206936000000 , -0.71073453533048] , [ 1209528000000 , -0.75380709640219] , [ 1212206400000 , -0.71020554911716] , [ 1214798400000 , -1.2077850914504] , [ 1217476800000 , -1.0505576787644] , [ 1220155200000 , -0.97804595164878] , [ 1222747200000 , -0.34591294663671] , [ 1225425600000 , -0.19958331514025] , [ 1228021200000 , -0.17599782216296] , [ 1230699600000 , -0.49577714121027] , [ 1233378000000 , -0.51644059173978] , [ 1235797200000 , -0.48576859637083] , [ 1238472000000 , -0.75596531126452] , [ 1241064000000 , -0.72073358315801] , [ 1243742400000 , -0.82125996732294] , [ 1246334400000 , -1.4933216860121] , [ 1249012800000 , -1.5003760525933] , [ 1251691200000 , -1.4744921420596] , [ 1254283200000 , -1.8197844060652] , [ 1256961600000 , -1.6558574419626] , [ 1259557200000 , -1.7256149254159] , [ 1262235600000 , -2.7667194124217] , [ 1264914000000 , -2.9113351806903] , [ 1267333200000 , -3.0172806042796] , [ 1270008000000 , -2.8607175559701] , [ 1272600000000 , -2.629226972169] , [ 1275278400000 , -2.1855196883832] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , -1.3788733828844] , [ 1288497600000 , -1.4136792139765] , [ 1291093200000 , -1.5176522942901] , [ 1293771600000 , -1.5776651933208] , [ 1296450000000 , -1.7171675182182] , [ 1298869200000 , -1.8121885250566] , [ 1301544000000 , -1.2221934283206] , [ 1304136000000 , -1.2910715239439] , [ 1306814400000 , -1.1492301612576] , [ 1309406400000 , -1.0613891302841] , [ 1312084800000 , -0.99605193205308] , [ 1314763200000 , -1.7324212072278] , [ 1317355200000 , -1.5226856867477] , [ 1320033600000 , -1.3159138896549] , [ 1322629200000 , -1.3925952659299] , [ 1325307600000 , -1.59624913621] , [ 1327986000000 , -1.5235879880296] , [ 1330491600000 , -1.7315573519279] , [ 1333166400000 , -0.86883431220926] , [ 1335758400000 , -0.90144871282829] , [ 1338436800000 , -0.7010492182517]]\n  } ,\n  {\n    \"key\" : \"Financials\" ,\n    \"values\" : [ [ 1138683600000 , -0.56797103580254] , [ 1141102800000 , -0.57324319174933] , [ 1143781200000 , -1.1014818753272] , [ 1146369600000 , -1.1480256918118] , [ 1149048000000 , -1.0709335336775] , [ 1151640000000 , -0.84876993929658] , [ 1154318400000 , -0.88122638919979] , [ 1156996800000 , -0.86421146074279] , [ 1159588800000 , -0.95093689377974] , [ 1162270800000 , -0.96646862382248] , [ 1164862800000 , -0.96726919442167] , [ 1167541200000 , -0.99874655234936] , [ 1170219600000 , -1.0004843898938] , [ 1172638800000 , -0.9925349676815] , [ 1175313600000 , -1.1888941931287] , [ 1177905600000 , -1.9402228220929] , [ 1180584000000 , -2.03915987194] , [ 1183176000000 , -2.4620526931074] , [ 1185854400000 , -2.2423544651877] , [ 1188532800000 , -1.8790998536037] , [ 1191124800000 , -0.43246873489492] , [ 1193803200000 , -0.40142684216371] , [ 1196398800000 , -0.35646635110466] , [ 1199077200000 , -0.90385702817642] , [ 1201755600000 , -0.86997575249605] , [ 1204261200000 , -0.80101406775415] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , -0.31816167663298] , [ 1217476800000 , -0.309250081849] , [ 1220155200000 , -0.27723698582762] , [ 1222747200000 , -0.32001379372079] , [ 1225425600000 , -0.1940212908561] , [ 1228021200000 , -0.051964569203423] , [ 1230699600000 , -0.68342686502452] , [ 1233378000000 , -0.57645644730726] , [ 1235797200000 , -0.50860972184555] , [ 1238472000000 , -0.44405217759605] , [ 1241064000000 , -0.45224333626901] , [ 1243742400000 , -0.41691818252313] , [ 1246334400000 , -2.4654561579904] , [ 1249012800000 , -2.5473566378551] , [ 1251691200000 , -2.8340604021307] , [ 1254283200000 , -1.8452445924041] , [ 1256961600000 , -1.5626544265386] , [ 1259557200000 , -1.707842764916] , [ 1262235600000 , -1.2237258567344] , [ 1264914000000 , -1.9756896168227] , [ 1267333200000 , -2.0920321696833] , [ 1270008000000 , -1.9782327706952] , [ 1272600000000 , -2.0416328165753] , [ 1275278400000 , -1.7816736134798] , [ 1277870400000 , -0.66092275437689] , [ 1280548800000 , -0.73608099025756] , [ 1283227200000 , -0.63686713461189] , [ 1285819200000 , -0.0024159482973197] , [ 1288497600000 , -0.0023052643588188] , [ 1291093200000 , -0.0023008251965446] , [ 1293771600000 , -0.002247807834351] , [ 1296450000000 , -0.62004345920743] , [ 1298869200000 , -0.69634926653235] , [ 1301544000000 , -0.76013525555354] , [ 1304136000000 , -1.505368495849] , [ 1306814400000 , -1.3456949237707] , [ 1309406400000 , -1.3013934898695] , [ 1312084800000 , -1.183199519395] , [ 1314763200000 , -0.0074317809719494] , [ 1317355200000 , -0.019430458325379] , [ 1320033600000 , -0.015777413509084] , [ 1322629200000 , -0.016463879837718] , [ 1325307600000 , -0.0031338919976225] , [ 1327986000000 , -0.0029770278967514] , [ 1330491600000 , -0.003048902987439] , [ 1333166400000 , -0.71171545945298] , [ 1335758400000 , -0.72003299240508] , [ 1338436800000 , -0.72961974845039]]\n  } ,\n  {\n    \"key\" : \"Health Care\" ,\n    \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , 0] , [ 1146369600000 , 0] , [ 1149048000000 , 0] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , -0.16816074963595] , [ 1185854400000 , -0.19318598121302] , [ 1188532800000 , -0.20130864403797] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , 0] , [ 1209528000000 , 0] , [ 1212206400000 , 0] , [ 1214798400000 , -0.30476443991021] , [ 1217476800000 , -0.31836730824777] , [ 1220155200000 , -0.30797427879366] , [ 1222747200000 , -0.48318623977865] , [ 1225425600000 , -0.50834562674351] , [ 1228021200000 , -0.47936068182503] , [ 1230699600000 , -0.61753010081956] , [ 1233378000000 , -0.59493587396819] , [ 1235797200000 , -0.62664324339064] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , -1.3076157801726] , [ 1256961600000 , -1.2306204787628] , [ 1259557200000 , -1.4728435992801] , [ 1262235600000 , -1.7729831226837] , [ 1264914000000 , -1.7711733839842] , [ 1267333200000 , -1.8233584472099] , [ 1270008000000 , -1.8505979461969] , [ 1272600000000 , -1.5989071613823] , [ 1275278400000 , -1.6636770720413] , [ 1277870400000 , -1.4523909758725] , [ 1280548800000 , -1.503771584105] , [ 1283227200000 , -1.5458561450475] , [ 1285819200000 , -1.457331837483] , [ 1288497600000 , -1.4217332434071] , [ 1291093200000 , -1.4687927303394] , [ 1293771600000 , -1.437223057967] , [ 1296450000000 , -0.72221871524334] , [ 1298869200000 , -0.7399575414588] , [ 1301544000000 , -1.9712239746745] , [ 1304136000000 , -2.2360949351942] , [ 1306814400000 , -2.2147572530541] , [ 1309406400000 , -2.0440932285023] , [ 1312084800000 , -1.9438209561938] , [ 1314763200000 , -4.9035620630386] , [ 1317355200000 , -4.9036674804213] , [ 1320033600000 , -4.1900706458801] , [ 1322629200000 , -4.5602615827955] , [ 1325307600000 , -1.9194421885814] , [ 1327986000000 , -1.8854470816382] , [ 1330491600000 , -1.9514785018245] , [ 1333166400000 , -0.65282205870454] , [ 1335758400000 , -0.57068368199209] , [ 1338436800000 , -0.55902563384907]]\n  } ,\n  {\n    \"key\" : \"Industrials\" ,\n    \"values\" : [ [ 1138683600000 , -0.390983707093] , [ 1141102800000 , -0.38471122730537] , [ 1143781200000 , -0.22897173467143] , [ 1146369600000 , -0.23798946472286] , [ 1149048000000 , -0.20721233428173] , [ 1151640000000 , -0.54577697700394] , [ 1154318400000 , -0.50300252995937] , [ 1156996800000 , -0.49609518628103] , [ 1159588800000 , -0.19582276889273] , [ 1162270800000 , -0.60399139945108] , [ 1164862800000 , -0.61477368082886] , [ 1167541200000 , -0.13665869881705] , [ 1170219600000 , -0.13147565243332] , [ 1172638800000 , -0.11819441593356] , [ 1175313600000 , -0.41610825689528] , [ 1177905600000 , -0.38815419659358] , [ 1180584000000 , -0.3703838943035] , [ 1183176000000 , -1.6193903804534] , [ 1185854400000 , -1.6502660417328] , [ 1188532800000 , -1.481875010149] , [ 1191124800000 , -0.96180099322536] , [ 1193803200000 , -0.97017301394967] , [ 1196398800000 , -0.97432971260093] , [ 1199077200000 , -0.36071934518387] , [ 1201755600000 , -0.42150070991777] , [ 1204261200000 , -0.41784042793202] , [ 1206936000000 , -0.70494708349169] , [ 1209528000000 , -0.73449590911984] , [ 1212206400000 , -0.7400163600788] , [ 1214798400000 , -0.52584502195668] , [ 1217476800000 , -0.56224806965368] , [ 1220155200000 , -0.50830855192741] , [ 1222747200000 , -0.79494637898049] , [ 1225425600000 , -0.70391433947286] , [ 1228021200000 , -0.61420660317009] , [ 1230699600000 , -0.41699636242004] , [ 1233378000000 , -0.3779041158185] , [ 1235797200000 , -0.34282498854047] , [ 1238472000000 , -0.83845630450592] , [ 1241064000000 , -0.85937944918912] , [ 1243742400000 , -0.85530287999615] , [ 1246334400000 , -1.2819866264007] , [ 1249012800000 , -1.4598491663715] , [ 1251691200000 , -1.5261472177779] , [ 1254283200000 , -1.2503948993549] , [ 1256961600000 , -1.1767079775724] , [ 1259557200000 , -1.2585538260386] , [ 1262235600000 , -3.420972598165] , [ 1264914000000 , -3.3381337072954] , [ 1267333200000 , -3.7043129330694] , [ 1270008000000 , -4.6924500756609] , [ 1272600000000 , -4.6880683704908] , [ 1275278400000 , -4.3335249071719] , [ 1277870400000 , -3.6545810416445] , [ 1280548800000 , -4.1639787701262] , [ 1283227200000 , -3.8249597612047] , [ 1285819200000 , -0.33221815335641] , [ 1288497600000 , -0.33346468179047] , [ 1291093200000 , -0.34546911228789] , [ 1293771600000 , -0.36609971997147] , [ 1296450000000 , -0.42502545672607] , [ 1298869200000 , -0.38192733348507] , [ 1301544000000 , -0.01991033447621] , [ 1304136000000 , -0.020319195299659] , [ 1306814400000 , -0.018147820835144] , [ 1309406400000 , -0.017923186209383] , [ 1312084800000 , -0.016133999253684] , [ 1314763200000 , -0.72058656278977] , [ 1317355200000 , -0.42812646564889] , [ 1320033600000 , -0.35896134792589] , [ 1322629200000 , -0.38637896444549] , [ 1325307600000 , -0.31794663984021] , [ 1327986000000 , -0.32220831831888] , [ 1330491600000 , -0.37107872672214] , [ 1333166400000 , -0.81968633933695] , [ 1335758400000 , -0.77148300885994] , [ 1338436800000 , -0.77392261735539]]\n  } ,\n  {\n    \"key\" : \"Information Technology\" ,\n    \"values\" : [ [ 1138683600000 , -0.86346955704548] , [ 1141102800000 , -0.88352373534584] , [ 1143781200000 , -1.2630802711685] , [ 1146369600000 , -1.2352593999242] , [ 1149048000000 , -1.2086379045093] , [ 1151640000000 , -1.0416778473647] , [ 1154318400000 , -0.99326278105154] , [ 1156996800000 , -1.0095045907007] , [ 1159588800000 , -2.0762515478576] , [ 1162270800000 , -2.13066829429] , [ 1164862800000 , -2.2458400474235] , [ 1167541200000 , -2.1315262677135] , [ 1170219600000 , -2.4063108252146] , [ 1172638800000 , -2.3753290631454] , [ 1175313600000 , -2.1119577565913] , [ 1177905600000 , -2.1546804750397] , [ 1180584000000 , -2.3768374034303] , [ 1183176000000 , -1.244878330098] , [ 1185854400000 , -1.2233210265236] , [ 1188532800000 , -1.1715073644317] , [ 1191124800000 , -1.0036136395928] , [ 1193803200000 , -0.9510676777939] , [ 1196398800000 , -0.97553526602196] , [ 1199077200000 , -1.9083849411912] , [ 1201755600000 , -1.855965027796] , [ 1204261200000 , -1.7343633512402] , [ 1206936000000 , -2.1847032903649] , [ 1209528000000 , -2.2095446284368] , [ 1212206400000 , -2.2060678671735] , [ 1214798400000 , -1.0941627910924] , [ 1217476800000 , -1.0004352405294] , [ 1220155200000 , -0.93563501378075] , [ 1222747200000 , 0] , [ 1225425600000 , -0.65155092645953] , [ 1228021200000 , -0.66021585164047] , [ 1230699600000 , 0] , [ 1233378000000 , 0] , [ 1235797200000 , 0] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , 0] , [ 1249012800000 , 0] , [ 1251691200000 , 0] , [ 1254283200000 , -0.29297573068109] , [ 1256961600000 , -0.75043756379084] , [ 1259557200000 , -0.85690846482745] , [ 1262235600000 , -0.21937480770873] , [ 1264914000000 , -0.93232569935343] , [ 1267333200000 , -0.94180327525084] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , -0.21253553193891] , [ 1288497600000 , -0.23178244747722] , [ 1291093200000 , -0.21481706129968] , [ 1293771600000 , -0.23306463011242] , [ 1296450000000 , -0.90244048159158] , [ 1298869200000 , -1.0410052083529] , [ 1301544000000 , -2.209350937089] , [ 1304136000000 , -2.6540796712932] , [ 1306814400000 , -3.2481210590957] , [ 1309406400000 , -3.0717986354635] , [ 1312084800000 , -2.7493296528921] , [ 1314763200000 , -2.1973991293256] , [ 1317355200000 , -0.86403111842659] , [ 1320033600000 , -0.87824756160219] , [ 1322629200000 , -0.80812571482871] , [ 1325307600000 , -1.6419820357151] , [ 1327986000000 , -1.6893790342619] , [ 1330491600000 , -1.8614499455474] , [ 1333166400000 , -1.814727017516] , [ 1335758400000 , -1.8744942128618] , [ 1338436800000 , -1.7880124850882]]\n  } ,\n  {\n    \"key\" : \"Materials\" ,\n    \"values\" : [ [ 1138683600000 , -0.26079769654951] , [ 1141102800000 , -0.23368425410881] , [ 1143781200000 , -0.46285283466193] , [ 1146369600000 , -0.4588429059205] , [ 1149048000000 , -0.43055120080853] , [ 1151640000000 , -0.26428963363642] , [ 1154318400000 , -0.26203611963364] , [ 1156996800000 , -0.26706156717825] , [ 1159588800000 , -0.024613610779192] , [ 1162270800000 , -0.024351047945929] , [ 1164862800000 , -0.031497065480344] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , 0] , [ 1185854400000 , 0] , [ 1188532800000 , 0] , [ 1191124800000 , 0] , [ 1193803200000 , 0] , [ 1196398800000 , 0] , [ 1199077200000 , 0] , [ 1201755600000 , 0] , [ 1204261200000 , 0] , [ 1206936000000 , -0.83875613435932] , [ 1209528000000 , -0.84367445572656] , [ 1212206400000 , -0.78928126005463] , [ 1214798400000 , -1.1075954825404] , [ 1217476800000 , -1.2704836497926] , [ 1220155200000 , -1.307504052056] , [ 1222747200000 , -0.70440409992826] , [ 1225425600000 , -0.74122140007729] , [ 1228021200000 , -0.82224393045109] , [ 1230699600000 , -1.8719055314571] , [ 1233378000000 , -1.5200311233975] , [ 1235797200000 , -1.5552386899059] , [ 1238472000000 , -1.1576593040773] , [ 1241064000000 , -1.0757811060575] , [ 1243742400000 , -1.0250125722511] , [ 1246334400000 , -2.2747597224127] , [ 1249012800000 , -2.3125499227974] , [ 1251691200000 , -2.2784386530745] , [ 1254283200000 , -1.1518806233757] , [ 1256961600000 , -1.0075503399018] , [ 1259557200000 , -1.1400577929481] , [ 1262235600000 , -0.50677891891165] , [ 1264914000000 , -0.54332908490051] , [ 1267333200000 , -0.55473181189807] , [ 1270008000000 , -0.3633796157757] , [ 1272600000000 , -0.30361861470847] , [ 1275278400000 , -0.24614951229153] , [ 1277870400000 , -1.0959443687647] , [ 1280548800000 , -1.1881529264637] , [ 1283227200000 , -1.1835349242596] , [ 1285819200000 , -0.92507477884561] , [ 1288497600000 , -0.94531016133473] , [ 1291093200000 , -0.93519433603434] , [ 1293771600000 , -1.009221344252] , [ 1296450000000 , -2.3640716285835] , [ 1298869200000 , -2.4914494188556] , [ 1301544000000 , -1.7979456141716] , [ 1304136000000 , -2.1389760840247] , [ 1306814400000 , -1.9721362241269] , [ 1309406400000 , -1.9170229522382] , [ 1312084800000 , -1.8076246545605] , [ 1314763200000 , -2.1010686108381] , [ 1317355200000 , -2.2396373791195] , [ 1320033600000 , -1.8469012813015] , [ 1322629200000 , -2.0079125997321] , [ 1325307600000 , -1.9170007806182] , [ 1327986000000 , -1.9239118384243] , [ 1330491600000 , -2.0649464738798] , [ 1333166400000 , -0.88385747789351] , [ 1335758400000 , -0.91438087144161] , [ 1338436800000 , -0.96513752020965]]\n  } ,\n  {\n    \"key\" : \"Telecommunication Services\" ,\n    \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , -0.077395192503573] , [ 1146369600000 , -0.079342784160835] , [ 1149048000000 , -0.07376956808809] , [ 1151640000000 , -0.041850521681201] , [ 1154318400000 , -0.037598545052499] , [ 1156996800000 , -0.040984079427717] , [ 1159588800000 , -0.19335817797448] , [ 1162270800000 , -0.18578493919925] , [ 1164862800000 , -0.1769473933101] , [ 1167541200000 , -0.57245352054975] , [ 1170219600000 , -0.61554187332911] , [ 1172638800000 , -0.63016714701151] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , -0.12118014109021] , [ 1185854400000 , -0.11085831487208] , [ 1188532800000 , -0.10901265358445] , [ 1191124800000 , -0.17205583275088] , [ 1193803200000 , -0.16573676303991] , [ 1196398800000 , -0.17954841680392] , [ 1199077200000 , -0.82703336198161] , [ 1201755600000 , -0.76741763304227] , [ 1204261200000 , -0.79430844816827] , [ 1206936000000 , -1.0279404050708] , [ 1209528000000 , -1.0342425093761] , [ 1212206400000 , -1.0903083860383] , [ 1214798400000 , -1.0895432841007] , [ 1217476800000 , -1.1392703218146] , [ 1220155200000 , -0.98872086340391] , [ 1222747200000 , -1.227654651568] , [ 1225425600000 , -1.0527419580394] , [ 1228021200000 , -0.84338280322309] , [ 1230699600000 , -0.5982617279246] , [ 1233378000000 , -0.74123723862634] , [ 1235797200000 , -0.81665712408277] , [ 1238472000000 , -0.89868760705228] , [ 1241064000000 , -0.86338472153689] , [ 1243742400000 , -0.85040889603889] , [ 1246334400000 , -0.82872733882926] , [ 1249012800000 , -1.2797824676355] , [ 1251691200000 , -1.152043882336] , [ 1254283200000 , -0.70125890680538] , [ 1256961600000 , -0.69496338525418] , [ 1259557200000 , -0.81982038022784] , [ 1262235600000 , -0.42841700219624] , [ 1264914000000 , -0.43298861575253] , [ 1267333200000 , -0.46951194437705] , [ 1270008000000 , -0.46723980191721] , [ 1272600000000 , -0.43139262322841] , [ 1275278400000 , -0.4052075794202] , [ 1277870400000 , -0.45399431179247] , [ 1280548800000 , -0.50492374473014] , [ 1283227200000 , -0.49032976375464] , [ 1285819200000 , -0.95769381063728] , [ 1288497600000 , -0.92968381683254] , [ 1291093200000 , -0.90984207437415] , [ 1293771600000 , -0.91448295661871] , [ 1296450000000 , -1.3204103334172] , [ 1298869200000 , -1.3896989018] , [ 1301544000000 , -1.8536993972883] , [ 1304136000000 , -1.9901582471947] , [ 1306814400000 , -1.8731097808809] , [ 1309406400000 , -1.8109819859122] , [ 1312084800000 , -1.7946593386661] , [ 1314763200000 , -1.6002716669781] , [ 1317355200000 , -0.056479286204019] , [ 1320033600000 , -0.046232413998891] , [ 1322629200000 , -0.051182355563531] , [ 1325307600000 , -0.032858749040145] , [ 1327986000000 , -0.032326418106178] , [ 1330491600000 , -0.033980477379241] , [ 1333166400000 , -0.053069550536519] , [ 1335758400000 , -0.055741850564434] , [ 1338436800000 , -0.055851808568252]]\n  } ,\n  {\n    \"key\" : \"Utilities\" ,\n    \"values\" : [ [ 1138683600000 , 0] , [ 1141102800000 , 0] , [ 1143781200000 , -0.073769471773675] , [ 1146369600000 , -0.077824496315782] , [ 1149048000000 , -0.080696288096361] , [ 1151640000000 , 0] , [ 1154318400000 , 0] , [ 1156996800000 , 0] , [ 1159588800000 , 0] , [ 1162270800000 , 0] , [ 1164862800000 , 0] , [ 1167541200000 , 0] , [ 1170219600000 , 0] , [ 1172638800000 , 0] , [ 1175313600000 , 0] , [ 1177905600000 , 0] , [ 1180584000000 , 0] , [ 1183176000000 , -0.16073291656515] , [ 1185854400000 , -0.1646253606633] , [ 1188532800000 , -0.1655815581449] , [ 1191124800000 , -0.74417496631713] , [ 1193803200000 , -0.76230340423681] , [ 1196398800000 , -0.73882938190048] , [ 1199077200000 , -0.3820573391806] , [ 1201755600000 , -0.360757285179] , [ 1204261200000 , -0.38081058463615] , [ 1206936000000 , -0.92767439811083] , [ 1209528000000 , -0.92774728028789] , [ 1212206400000 , -0.85273481694714] , [ 1214798400000 , -1.69407085613] , [ 1217476800000 , -1.5179726219101] , [ 1220155200000 , -1.3576700600738] , [ 1222747200000 , -1.0404839864076] , [ 1225425600000 , -0.95251478838915] , [ 1228021200000 , -1.0610509118017] , [ 1230699600000 , -0.3316792294278] , [ 1233378000000 , -0.33745002288524] , [ 1235797200000 , -0.28806366796683] , [ 1238472000000 , 0] , [ 1241064000000 , 0] , [ 1243742400000 , 0] , [ 1246334400000 , -0.6338555382785] , [ 1249012800000 , -0.62797265130959] , [ 1251691200000 , -0.60264057253794] , [ 1254283200000 , -0.28687231077181] , [ 1256961600000 , -0.22215649778327] , [ 1259557200000 , -0.24027664555676] , [ 1262235600000 , 0] , [ 1264914000000 , 0] , [ 1267333200000 , 0] , [ 1270008000000 , 0] , [ 1272600000000 , 0] , [ 1275278400000 , 0] , [ 1277870400000 , 0] , [ 1280548800000 , 0] , [ 1283227200000 , 0] , [ 1285819200000 , 0] , [ 1288497600000 , 0] , [ 1291093200000 , 0] , [ 1293771600000 , 0] , [ 1296450000000 , 0] , [ 1298869200000 , 0] , [ 1301544000000 , 0] , [ 1304136000000 , 0] , [ 1306814400000 , 0] , [ 1309406400000 , 0] , [ 1312084800000 , 0] , [ 1314763200000 , 0] , [ 1317355200000 , 0] , [ 1320033600000 , 0] , [ 1322629200000 , 0] , [ 1325307600000 , 0] , [ 1327986000000 , 0] , [ 1330491600000 , 0] , [ 1333166400000 , 0] , [ 1335758400000 , 0] , [ 1338436800000 , 0]]\n  }\n];\n\nfunction totalRandom() {\n  var rval = [];\n  for(var n=1; n <= 2; n++) {\n      var series = [];\n      for(var i =0; i < 50; i++) {\n          series.push([\n              Math.floor(Math.random() * 100),\n              Math.random() * 6\n            ]);\n      }\n      rval.push({key: \"Random \" + n, values: series});\n  }\n  return rval;\n}\n\nfunction nPoints() {\n  var rval = [\n    {key: \"Series 1\",\n    values: [\n        [1,2],\n        [2,4],\n        [3,8]\n    ]}\n  ];\n  return rval;\n\n}\n\n//an example of harmonizing colors between visualizations\n//observe that Consumer Discretionary and Consumer Staples have\n//been flipped in the second chart\nvar colors = d3.scale.category20();\nvar keyColor = function(d, i) {return colors(d.key)};\n\nfunction defaultChartConfig(container, data, useGuideline) {\n  if (useGuideline === undefined) useGuideline = true;\n  nv.addGraph(function() {\n    var chart;\n    chart = nv.models.stackedAreaChart()\n                  .useInteractiveGuideline(useGuideline)\n                  .x(function(d) { return d[0] })\n                  .y(function(d) { return d[1] })\n                  .color(keyColor)\n                    ;\n\n    chart.xAxis\n        .tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n\n    chart.yAxis\n        .tickFormat(d3.format(',.2f'));\n\n    d3.select('#' + container + ' svg')\n          .datum(data)\n        .transition().duration(500).call(chart);\n\n    nv.utils.windowResize(chart.update);\n\n    chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n    return chart;\n  });\n}\n\n//Chart with old tooltip format.\nnv.addGraph(function() {\n  var chart = nv.models.stackedAreaChart()\n                .x(function(d) { return d[0] })\n                .y(function(d) { return d[1] })\n                .showControls(false)\n                .color(keyColor)\n                .margin({right:90})\n                .rightAlignYAxis(true)\n                ;\n\n  chart.xAxis\n      .tickFormat(function(d) { return d3.time.format('%x')(new Date(d)) });\n\n  chart.yAxis\n      .tickFormat(d3.format(',.2f'));\n\n  d3.select('#chart2 svg')\n    .datum(histcatexpshort)\n      .call(chart);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  nv.utils.windowResize(chart.update);\n\n  chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });\n\n  return chart;\n});\n\ndefaultChartConfig(\"chart1\", histcatexplong);\ndefaultChartConfig(\"chart3\", histcatexplong_singledatapoint);\ndefaultChartConfig(\"chart4\", histcatexplong_twodatapoint);\ndefaultChartConfig(\"chart5\", histcatexplong_withholes);\ndefaultChartConfig(\"chart6\", totalRandom(), false);\ndefaultChartConfig(\"chart7\", nPoints(),false);\ndefaultChartConfig(\"chart8\", []);\ndefaultChartConfig(\"chart9\", histcatexpshort,true);\n</script>\n"
  },
  {
    "path": "test/stream_layers.js",
    "content": "\n/* Inspired by Lee Byron's test data generator. */\nfunction stream_layers(n, m, o) {\n  if (arguments.length < 3) o = 0;\n  function bump(a) {\n    var x = 1 / (.1 + Math.random()),\n        y = 2 * Math.random() - .5,\n        z = 10 / (.1 + Math.random());\n    for (var i = 0; i < m; i++) {\n      var w = (i / m - y) * z;\n      a[i] += x * Math.exp(-w * w);\n    }\n  }\n  return d3.range(n).map(function() {\n      var a = [], i;\n      for (i = 0; i < m; i++) a[i] = o + o * Math.random();\n      for (i = 0; i < 5; i++) bump(a);\n      return a.map(stream_index);\n    });\n}\n\n/* Another layer generator using gamma distributions. */\nfunction stream_waves(n, m) {\n  return d3.range(n).map(function(i) {\n    return d3.range(m).map(function(j) {\n        var x = 20 * j / m - i / 3;\n        return 2 * x * Math.exp(-.5 * x);\n      }).map(stream_index);\n    });\n}\n\nfunction stream_index(d, i) {\n  return {x: i, y: Math.max(0, d)};\n}\n\n"
  },
  {
    "path": "test/testScript.js",
    "content": "//A little snippet of D3 code that creates a button that lets you toggle whether a chart is the only one visible on a page or not.\nd3.selectAll(\".chart button\").on(\"click\",function() {\n   var thisId = this.parentElement.id;\n\n   var chartContainer = d3.select(\"#\" + thisId);\n   if (chartContainer.attr(\"class\").match(\"selected\"))\n      chartContainer.classed(\"selected\",false);\n   else\n      chartContainer.classed(\"selected\",true);\n\n   d3.selectAll(\".chart\").style(\"display\",function() {\n        if (thisId === this.id) return \"block\";\n\n        if (d3.select(this).style(\"display\") === \"none\")\n          return \"block\";\n        else\n          return \"none\";\n   });\n   window.onresize();\n});"
  },
  {
    "path": "test/teststyle.css",
    "content": "body {\n  overflow-y:scroll;\n  font-family: arial;\n}\n\ntext {\n  font: 12px sans-serif;\n}\n\n.chart {\n  float:left;\n  height: 500px;\n  text-align: center;\n  font-weight: bold;\n  margin-bottom: 2em;\n}\n.chart.full {\n  width: 100%;\n}\n\n.chart.half {\n  width: 50%;\n}\n\n.chart.third {\n  width: 33%;\n}\n\n.chart.selected {\n  width: 100% !important;\n}\n\n.navigation a{\n  margin-right: 1em;\n}\n\n.navigation {\n  margin-bottom: 1em;\n}\n"
  },
  {
    "path": "test/tinytest/nv-is-defined-test.js",
    "content": "// nv-is-defined-test.js\n\nTinytest.add('nv object is defined', function(test) {\n  test.isNotUndefined(nv, 'nv is undefined at global scope for Meteor');\n});\n\n"
  },
  {
    "path": "test/translateTest.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <link href=\"../build/nv.d3.css\" rel=\"stylesheet\" type=\"text/css\">\n    <script src=\"../bower_components/d3/d3.min.js\" charset=\"utf-8\"></script>\n    <script src=\"../build/nv.d3.js\"></script>\n    <style>\n        body{\n            transform: translate(-225px,0px);\n        }\n        svg{\n\n            position: absolute;\n            left: 225px;\n        }\n    </style>\n</head>\n<body>\n    <svg style=\"height: 400px; width: 400px\"></svg>\n    <script>\n        function drawGraph() {\n            nv.addGraph(function() {\n                var chart = nv.models.lineChart().useInteractiveGuideline(true);\n                var myData = [{key: 'key', values: [{x: 1, y: 1}]}];\n\n                d3.select('svg')\n                    .datum(myData)\n                    .call(chart);\n\n                return chart;\n            });\n        }\n\n        drawGraph();\n    </script>\n</body>\n</html>\n"
  }
]