From 6666e9d725c9c4a17f90f80e6ace9f7ae01e34aa Mon Sep 17 00:00:00 2001 From: christianesperar Date: Thu, 2 Jun 2016 20:54:58 +0800 Subject: [PATCH 1/3] Add bower resolution --- bower.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bower.json b/bower.json index 36b7fe83..ade06474 100644 --- a/bower.json +++ b/bower.json @@ -74,5 +74,9 @@ "echarts": "^3.1.7", "malihu-custom-scrollbar-plugin": "^3.1.3", "animate.css": "^3.5.1" + }, + "resolutions": { + "jquery": "^2.2.3", + "fastclick": "^1.0.6" } } From 89d7f6df20011dbe6d96099fbf3fb06ad999c8ff Mon Sep 17 00:00:00 2001 From: christianesperar Date: Fri, 3 Jun 2016 00:08:25 +0800 Subject: [PATCH 2/3] Update libraries --- vendors/Chart.js/.bower.json | 10 +- vendors/Chart.js/.editorconfig | 10 + vendors/Chart.js/.github/ISSUE_TEMPLATE.md | 2 + .../Chart.js/.github/PULL_REQUEST_TEMPLATE.md | 2 + vendors/Chart.js/.gitignore | 2 +- vendors/Chart.js/README.md | 4 +- vendors/Chart.js/bower.json | 6 +- vendors/Chart.js/dist/Chart.bundle.js | 19109 ++++++++-------- vendors/Chart.js/dist/Chart.bundle.min.js | 21 +- vendors/Chart.js/dist/Chart.js | 17496 +++++++------- vendors/Chart.js/dist/Chart.min.js | 13 +- vendors/Chart.js/docs/00-Getting-Started.md | 207 +- .../Chart.js/docs/01-Chart-Configuration.md | 408 + vendors/Chart.js/docs/01-Scales.md | 301 - vendors/Chart.js/docs/02-Scales.md | 357 + .../{02-Line-Chart.md => 03-Line-Chart.md} | 103 +- .../docs/{03-Bar-Chart.md => 04-Bar-Chart.md} | 15 +- .../{04-Radar-Chart.md => 05-Radar-Chart.md} | 6 +- ...r-Area-Chart.md => 06-Polar-Area-Chart.md} | 8 +- ...hnut-Chart.md => 07-Pie-Doughnut-Chart.md} | 12 +- vendors/Chart.js/docs/08-Bubble-Chart.md | 100 + .../docs/{07-Advanced.md => 09-Advanced.md} | 13 +- .../docs/{08-Notes.md => 10-Notes.md} | 4 +- vendors/Chart.js/gulpfile.js | 61 +- vendors/Chart.js/package.json | 6 +- .../timeScale/line-time-point-data.html | 3 +- vendors/Chart.js/src/chart.js | 22 +- vendors/Chart.js/src/charts/Chart.Radar.js | 10 +- .../src/controllers/controller.bar.js | 392 +- .../src/controllers/controller.bubble.js | 100 +- .../src/controllers/controller.doughnut.js | 189 +- .../src/controllers/controller.line.js | 294 +- .../src/controllers/controller.polarArea.js | 148 +- .../src/controllers/controller.radar.js | 143 +- vendors/Chart.js/src/core/core.controller.js | 325 +- .../src/core/core.datasetController.js | 107 +- vendors/Chart.js/src/core/core.element.js | 4 +- vendors/Chart.js/src/core/core.helpers.js | 297 +- vendors/Chart.js/src/core/core.legend.js | 184 +- vendors/Chart.js/src/core/core.plugin.js | 25 +- vendors/Chart.js/src/core/core.scale.js | 584 +- .../Chart.js/src/core/core.scaleService.js | 6 + vendors/Chart.js/src/core/core.title.js | 131 +- vendors/Chart.js/src/core/core.tooltip.js | 61 +- vendors/Chart.js/src/elements/element.arc.js | 39 +- vendors/Chart.js/src/elements/element.line.js | 20 +- .../Chart.js/src/elements/element.point.js | 212 +- .../src/elements/element.rectangle.js | 34 +- vendors/Chart.js/src/scales/scale.linear.js | 204 +- .../Chart.js/src/scales/scale.logarithmic.js | 164 +- .../Chart.js/src/scales/scale.radialLinear.js | 44 +- vendors/Chart.js/src/scales/scale.time.js | 34 +- vendors/Chart.js/test/core.helpers.tests.js | 35 +- .../Chart.js/test/core.scaleService.tests.js | 29 + vendors/Chart.js/test/core.title.tests.js | 14 +- vendors/Chart.js/test/scale.category.tests.js | 5 +- vendors/Chart.js/test/scale.linear.tests.js | 32 +- .../Chart.js/test/scale.logarithmic.tests.js | 5 +- .../Chart.js/test/scale.radialLinear.tests.js | 5 +- vendors/Chart.js/test/scale.time.tests.js | 36 +- vendors/Flot/.bower.json | 3 +- vendors/PACE/.bower.json | 45 - vendors/PACE/LICENSE | 8 - vendors/PACE/README.md | 27 - vendors/PACE/bower.json | 35 - vendors/PACE/install.json | 86 - vendors/PACE/pace.coffee | 755 - vendors/PACE/pace.js | 935 - vendors/PACE/pace.min.js | 2 - .../themes/black/pace-theme-barber-shop.css | 83 - .../themes/black/pace-theme-big-counter.css | 40 - .../PACE/themes/black/pace-theme-bounce.css | 231 - .../themes/black/pace-theme-center-atom.css | 131 - .../themes/black/pace-theme-center-circle.css | 90 - .../themes/black/pace-theme-center-radar.css | 74 - .../themes/black/pace-theme-center-simple.css | 52 - .../black/pace-theme-corner-indicator.css | 73 - .../themes/black/pace-theme-fill-left.css | 22 - .../PACE/themes/black/pace-theme-flash.css | 77 - .../PACE/themes/black/pace-theme-flat-top.css | 41 - .../themes/black/pace-theme-loading-bar.css | 198 - .../PACE/themes/black/pace-theme-mac-osx.css | 87 - .../PACE/themes/black/pace-theme-minimal.css | 23 - .../themes/blue/pace-theme-barber-shop.css | 83 - .../themes/blue/pace-theme-big-counter.css | 40 - .../PACE/themes/blue/pace-theme-bounce.css | 231 - .../themes/blue/pace-theme-center-atom.css | 131 - .../themes/blue/pace-theme-center-circle.css | 90 - .../themes/blue/pace-theme-center-radar.css | 74 - .../themes/blue/pace-theme-center-simple.css | 52 - .../blue/pace-theme-corner-indicator.css | 73 - .../PACE/themes/blue/pace-theme-fill-left.css | 22 - vendors/PACE/themes/blue/pace-theme-flash.css | 77 - .../PACE/themes/blue/pace-theme-flat-top.css | 41 - .../themes/blue/pace-theme-loading-bar.css | 198 - .../PACE/themes/blue/pace-theme-mac-osx.css | 87 - .../PACE/themes/blue/pace-theme-minimal.css | 23 - .../themes/green/pace-theme-barber-shop.css | 83 - .../themes/green/pace-theme-big-counter.css | 40 - .../PACE/themes/green/pace-theme-bounce.css | 231 - .../themes/green/pace-theme-center-atom.css | 131 - .../themes/green/pace-theme-center-circle.css | 90 - .../themes/green/pace-theme-center-radar.css | 74 - .../themes/green/pace-theme-center-simple.css | 52 - .../green/pace-theme-corner-indicator.css | 73 - .../themes/green/pace-theme-fill-left.css | 22 - .../PACE/themes/green/pace-theme-flash.css | 77 - .../PACE/themes/green/pace-theme-flat-top.css | 41 - .../themes/green/pace-theme-loading-bar.css | 198 - .../PACE/themes/green/pace-theme-mac-osx.css | 87 - .../PACE/themes/green/pace-theme-minimal.css | 23 - .../themes/orange/pace-theme-barber-shop.css | 83 - .../themes/orange/pace-theme-big-counter.css | 40 - .../PACE/themes/orange/pace-theme-bounce.css | 231 - .../themes/orange/pace-theme-center-atom.css | 131 - .../orange/pace-theme-center-circle.css | 90 - .../themes/orange/pace-theme-center-radar.css | 74 - .../orange/pace-theme-center-simple.css | 52 - .../orange/pace-theme-corner-indicator.css | 73 - .../themes/orange/pace-theme-fill-left.css | 22 - .../PACE/themes/orange/pace-theme-flash.css | 77 - .../themes/orange/pace-theme-flat-top.css | 41 - .../themes/orange/pace-theme-loading-bar.css | 198 - .../PACE/themes/orange/pace-theme-mac-osx.css | 87 - .../PACE/themes/orange/pace-theme-minimal.css | 23 - .../themes/pink/pace-theme-barber-shop.css | 83 - .../themes/pink/pace-theme-big-counter.css | 40 - .../PACE/themes/pink/pace-theme-bounce.css | 231 - .../themes/pink/pace-theme-center-atom.css | 131 - .../themes/pink/pace-theme-center-circle.css | 90 - .../themes/pink/pace-theme-center-radar.css | 74 - .../themes/pink/pace-theme-center-simple.css | 52 - .../pink/pace-theme-corner-indicator.css | 73 - .../PACE/themes/pink/pace-theme-fill-left.css | 22 - vendors/PACE/themes/pink/pace-theme-flash.css | 77 - .../PACE/themes/pink/pace-theme-flat-top.css | 41 - .../themes/pink/pace-theme-loading-bar.css | 198 - .../PACE/themes/pink/pace-theme-mac-osx.css | 87 - .../PACE/themes/pink/pace-theme-minimal.css | 23 - .../themes/purple/pace-theme-barber-shop.css | 83 - .../themes/purple/pace-theme-big-counter.css | 40 - .../PACE/themes/purple/pace-theme-bounce.css | 231 - .../themes/purple/pace-theme-center-atom.css | 131 - .../purple/pace-theme-center-circle.css | 90 - .../themes/purple/pace-theme-center-radar.css | 74 - .../purple/pace-theme-center-simple.css | 52 - .../purple/pace-theme-corner-indicator.css | 73 - .../themes/purple/pace-theme-fill-left.css | 22 - .../PACE/themes/purple/pace-theme-flash.css | 77 - .../themes/purple/pace-theme-flat-top.css | 41 - .../themes/purple/pace-theme-loading-bar.css | 198 - .../PACE/themes/purple/pace-theme-mac-osx.css | 87 - .../PACE/themes/purple/pace-theme-minimal.css | 23 - .../themes/red/pace-theme-barber-shop.css | 83 - .../themes/red/pace-theme-big-counter.css | 40 - vendors/PACE/themes/red/pace-theme-bounce.css | 231 - .../themes/red/pace-theme-center-atom.css | 131 - .../themes/red/pace-theme-center-circle.css | 90 - .../themes/red/pace-theme-center-radar.css | 74 - .../themes/red/pace-theme-center-simple.css | 52 - .../red/pace-theme-corner-indicator.css | 73 - .../PACE/themes/red/pace-theme-fill-left.css | 22 - vendors/PACE/themes/red/pace-theme-flash.css | 77 - .../PACE/themes/red/pace-theme-flat-top.css | 41 - .../themes/red/pace-theme-loading-bar.css | 198 - .../PACE/themes/red/pace-theme-mac-osx.css | 87 - .../PACE/themes/red/pace-theme-minimal.css | 23 - .../themes/silver/pace-theme-barber-shop.css | 83 - .../themes/silver/pace-theme-big-counter.css | 40 - .../PACE/themes/silver/pace-theme-bounce.css | 231 - .../themes/silver/pace-theme-center-atom.css | 131 - .../silver/pace-theme-center-circle.css | 90 - .../themes/silver/pace-theme-center-radar.css | 74 - .../silver/pace-theme-center-simple.css | 52 - .../silver/pace-theme-corner-indicator.css | 73 - .../themes/silver/pace-theme-fill-left.css | 22 - .../PACE/themes/silver/pace-theme-flash.css | 77 - .../themes/silver/pace-theme-flat-top.css | 41 - .../themes/silver/pace-theme-loading-bar.css | 198 - .../PACE/themes/silver/pace-theme-mac-osx.css | 87 - .../PACE/themes/silver/pace-theme-minimal.css | 23 - .../themes/white/pace-theme-barber-shop.css | 83 - .../themes/white/pace-theme-big-counter.css | 40 - .../PACE/themes/white/pace-theme-bounce.css | 231 - .../themes/white/pace-theme-center-atom.css | 131 - .../themes/white/pace-theme-center-circle.css | 90 - .../themes/white/pace-theme-center-radar.css | 74 - .../themes/white/pace-theme-center-simple.css | 52 - .../white/pace-theme-corner-indicator.css | 73 - .../themes/white/pace-theme-fill-left.css | 22 - .../PACE/themes/white/pace-theme-flash.css | 77 - .../PACE/themes/white/pace-theme-flat-top.css | 41 - .../themes/white/pace-theme-loading-bar.css | 198 - .../PACE/themes/white/pace-theme-mac-osx.css | 87 - .../PACE/themes/white/pace-theme-minimal.css | 23 - .../themes/yellow/pace-theme-barber-shop.css | 83 - .../themes/yellow/pace-theme-big-counter.css | 40 - .../PACE/themes/yellow/pace-theme-bounce.css | 231 - .../themes/yellow/pace-theme-center-atom.css | 131 - .../yellow/pace-theme-center-circle.css | 90 - .../themes/yellow/pace-theme-center-radar.css | 74 - .../yellow/pace-theme-center-simple.css | 52 - .../yellow/pace-theme-corner-indicator.css | 73 - .../themes/yellow/pace-theme-fill-left.css | 22 - .../PACE/themes/yellow/pace-theme-flash.css | 77 - .../themes/yellow/pace-theme-flat-top.css | 41 - .../themes/yellow/pace-theme-loading-bar.css | 198 - .../PACE/themes/yellow/pace-theme-mac-osx.css | 87 - .../PACE/themes/yellow/pace-theme-minimal.css | 23 - vendors/animate.css/.bower.json | 3 +- vendors/autosize/.bower.json | 3 +- vendors/bernii/gauge.js/.bower.json | 25 - vendors/bernii/gauge.js/README.md | 35 - vendors/bernii/gauge.js/assets/arrow.gif | Bin 66 -> 0 bytes vendors/bernii/gauge.js/assets/bg.png | Bin 17908 -> 0 bytes .../bernii/gauge.js/assets/bootstrap.min.css | 9 - vendors/bernii/gauge.js/assets/browsers.png | Bin 34450 -> 0 bytes vendors/bernii/gauge.js/assets/cross.gif | Bin 83 -> 0 bytes vendors/bernii/gauge.js/assets/crosshair.gif | Bin 13167 -> 0 bytes .../gauge.js/assets/excanvas.compiled.js | 35 - .../assets/fd-slider/fd-slider-tooltip.css | 117 - .../gauge.js/assets/fd-slider/fd-slider.css | 143 - .../gauge.js/assets/fd-slider/fd-slider.js | 1212 - vendors/bernii/gauge.js/assets/github.gif | Bin 1298 -> 0 bytes vendors/bernii/gauge.js/assets/hs.png | Bin 2684 -> 0 bytes vendors/bernii/gauge.js/assets/hv.png | Bin 2865 -> 0 bytes vendors/bernii/gauge.js/assets/jscolor.js | 935 - vendors/bernii/gauge.js/assets/main.css | 258 - vendors/bernii/gauge.js/assets/prettify.css | 49 - vendors/bernii/gauge.js/assets/prettify.js | 28 - vendors/bernii/gauge.js/assets/preview.jpg | Bin 26488 -> 0 bytes vendors/bernii/gauge.js/assets/ribbon.png | Bin 7660 -> 0 bytes vendors/bernii/gauge.js/assets/strike.png | Bin 8343 -> 0 bytes vendors/bernii/gauge.js/bower.json | 17 - vendors/bernii/gauge.js/dist/gauge.coffee | 524 - vendors/bernii/gauge.js/dist/gauge.js | 773 - vendors/bernii/gauge.js/dist/gauge.min.js | 61 - vendors/bernii/gauge.js/favicon.ico | Bin 1439 -> 0 bytes vendors/bernii/gauge.js/index.html | 370 - vendors/bootstrap-daterangepicker/.bower.json | 11 +- .../daterangepicker.css | 87 +- .../daterangepicker.js | 126 +- .../daterangepicker.scss | 131 +- vendors/bootstrap-daterangepicker/demo.html | 7 + .../example/amd/index.html | 210 + .../example/amd/main.js | 141 + .../example/amd/require.js | 36 + .../example/browserify/README.md | 11 + .../example/browserify/bundle.js | 0 .../example/browserify/index.html | 209 + .../example/browserify/main.js | 135 + vendors/bootstrap-daterangepicker/package.js | 2 +- .../bootstrap-daterangepicker/package.json | 2 +- .../website/index.html | 7 +- .../website/website.js | 3 +- vendors/bootstrap-progressbar/.bower.json | 3 +- vendors/bootstrap-wysiwyg/.bower.json | 3 +- vendors/bootstrap/.bower.json | 3 +- vendors/cropper/.bower.json | 19 +- vendors/cropper/CHANGELOG.md | 7 + vendors/cropper/README.md | 55 +- vendors/cropper/bower.json | 8 +- vendors/cropper/dist/cropper.css | 4 +- vendors/cropper/dist/cropper.js | 23 +- vendors/cropper/dist/cropper.min.css | 4 +- vendors/cropper/dist/cropper.min.js | 6 +- vendors/cropper/package.json | 12 +- vendors/cropper/src/js/init.js | 4 + vendors/cropper/src/js/methods.js | 6 +- vendors/cropper/src/js/utilities.js | 9 +- vendors/cropper/src/scss/_variables.scss | 14 +- vendors/datatables.net-bs/.bower.json | 11 +- .../css/dataTables.bootstrap.css | 4 +- .../css/dataTables.bootstrap.min.css | 2 +- vendors/datatables.net-buttons-bs/.bower.json | 11 +- .../js/buttons.bootstrap.js | 2 +- .../js/buttons.bootstrap.min.js | 2 +- vendors/datatables.net-buttons/.bower.json | 11 +- .../js/buttons.colVis.js | 14 +- .../js/buttons.colVis.min.js | 10 +- .../js/buttons.flash.js | 520 +- .../js/buttons.flash.min.js | 50 +- .../js/buttons.html5.js | 705 +- .../js/buttons.html5.min.js | 48 +- .../js/buttons.print.js | 17 +- .../js/buttons.print.min.js | 8 +- .../js/dataTables.buttons.js | 554 +- .../js/dataTables.buttons.min.js | 67 +- .../datatables.net-fixedheader-bs/.bower.json | 11 +- .../datatables.net-fixedheader/.bower.json | 11 +- .../js/dataTables.fixedHeader.js | 28 +- .../js/dataTables.fixedHeader.min.js | 22 +- vendors/datatables.net-keytable/.bower.json | 11 +- .../js/dataTables.keyTable.js | 33 +- .../js/dataTables.keyTable.min.js | 30 +- .../datatables.net-responsive-bs/.bower.json | 11 +- .../css/responsive.bootstrap.css | 23 +- .../css/responsive.bootstrap.min.css | 2 +- .../js/responsive.bootstrap.js | 37 +- vendors/datatables.net-responsive/.bower.json | 11 +- .../js/dataTables.responsive.js | 88 +- .../js/dataTables.responsive.min.js | 45 +- .../datatables.net-scroller-bs/.bower.json | 11 +- vendors/datatables.net-scroller/.bower.json | 11 +- .../js/dataTables.scroller.js | 14 +- .../js/dataTables.scroller.min.js | 37 +- vendors/datatables.net/.bower.json | 11 +- .../datatables.net/js/jquery.dataTables.js | 2680 +-- .../js/jquery.dataTables.min.js | 274 +- vendors/devbridge-autocomplete/.bower.json | 3 +- vendors/dropzone/.bower.json | 3 +- vendors/echarts/.bower.json | 11 +- vendors/echarts/.gitignore | 1 + vendors/echarts/.jshintignore | 2 - vendors/echarts/dist/echarts.common.js | 2640 ++- vendors/echarts/dist/echarts.common.min.js | 22 +- vendors/echarts/dist/echarts.js | 8052 ++++--- vendors/echarts/dist/echarts.min.js | 33 +- vendors/echarts/dist/echarts.simple.js | 1594 +- vendors/echarts/dist/echarts.simple.min.js | 16 +- vendors/echarts/package.json | 6 +- vendors/echarts/src/action/geoRoam.js | 45 +- vendors/echarts/src/action/roamHelper.js | 53 +- vendors/echarts/src/chart/bar/BarSeries.js | 8 - vendors/echarts/src/chart/bar/BarView.js | 10 +- .../src/chart/candlestick/CandlestickView.js | 6 +- .../echarts/src/chart/funnel/FunnelView.js | 12 +- vendors/echarts/src/chart/gauge/GaugeView.js | 32 +- vendors/echarts/src/chart/graph.js | 1 + .../echarts/src/chart/graph/GraphSeries.js | 122 +- vendors/echarts/src/chart/graph/GraphView.js | 167 +- vendors/echarts/src/chart/graph/adjustEdge.js | 145 + .../echarts/src/chart/graph/categoryVisual.js | 10 +- .../src/chart/graph/circularLayoutHelper.js | 13 +- vendors/echarts/src/chart/graph/createView.js | 22 +- vendors/echarts/src/chart/graph/edgeVisual.js | 33 + .../echarts/src/chart/graph/forceLayout.js | 4 + vendors/echarts/src/chart/graph/roamAction.js | 14 +- .../echarts/src/chart/graph/simpleLayout.js | 18 +- .../src/chart/graph/simpleLayoutEdge.js | 18 + .../src/chart/graph/simpleLayoutHelper.js | 17 +- .../echarts/src/chart/heatmap/HeatmapView.js | 5 +- .../echarts/src/chart/helper/EffectLine.js | 12 +- .../echarts/src/chart/helper/EffectSymbol.js | 2 + .../src/chart/helper/LargeSymbolDraw.js | 2 +- vendors/echarts/src/chart/helper/Line.js | 251 +- vendors/echarts/src/chart/helper/LineDraw.js | 32 +- vendors/echarts/src/chart/helper/LinePath.js | 19 +- vendors/echarts/src/chart/helper/Symbol.js | 42 +- .../src/chart/helper/WhiskerBoxDraw.js | 4 +- .../chart/helper/createGraphFromNodeEdge.js | 42 +- .../chart/helper/createGraphFromNodeMatrix.js | 32 +- .../src/chart/helper/createListFromArray.js | 12 + vendors/echarts/src/chart/line/LineSeries.js | 42 +- vendors/echarts/src/chart/line/LineView.js | 42 +- vendors/echarts/src/chart/line/poly.js | 81 +- vendors/echarts/src/chart/map/MapSeries.js | 91 +- vendors/echarts/src/chart/map/MapView.js | 2 +- .../echarts/src/chart/map/backwardCompat.js | 5 +- .../src/chart/parallel/ParallelView.js | 5 +- vendors/echarts/src/chart/pie/PieSeries.js | 6 +- vendors/echarts/src/chart/pie/PieView.js | 14 +- .../echarts/src/chart/radar/RadarSeries.js | 21 - vendors/echarts/src/chart/radar/RadarView.js | 11 +- .../echarts/src/chart/sankey/SankeySeries.js | 30 +- .../echarts/src/chart/sankey/SankeyView.js | 29 +- .../echarts/src/chart/sankey/sankeyVisual.js | 10 +- .../src/chart/treemap/TreemapSeries.js | 8 +- .../echarts/src/chart/treemap/TreemapView.js | 497 +- vendors/echarts/src/chart/treemap/helper.js | 13 +- .../src/chart/treemap/treemapAction.js | 27 +- .../src/chart/treemap/treemapLayout.js | 94 +- .../src/chart/treemap/treemapVisual.js | 4 +- .../src/component/dataZoom/AxisProxy.js | 32 +- .../src/component/dataZoom/InsideZoomView.js | 2 +- .../src/component/dataZoom/SliderZoomModel.js | 2 - .../component/dataZoom/dataZoomProcessor.js | 1 + .../echarts/src/component/dataZoom/roams.js | 5 +- vendors/echarts/src/component/geo.js | 41 + vendors/echarts/src/component/geo/GeoView.js | 18 +- .../echarts/src/component/helper/MapDraw.js | 171 +- .../src/component/helper/RoamController.js | 24 +- .../helper/selectableMixin.js} | 37 +- .../src/component/legend/LegendView.js | 3 + .../src/component/marker/MarkLineModel.js | 48 +- .../src/component/marker/MarkLineView.js | 122 +- .../src/component/marker/MarkPointModel.js | 44 +- .../src/component/marker/MarkPointView.js | 4 - .../src/component/marker/markerHelper.js | 8 +- .../component/timeline/SliderTimelineModel.js | 7 +- .../component/timeline/SliderTimelineView.js | 24 +- .../src/component/toolbox/feature/DataZoom.js | 2 +- .../src/component/tooltip/TooltipContent.js | 17 +- .../src/component/tooltip/TooltipView.js | 27 +- .../component/visualMap/ContinuousModel.js | 57 +- .../src/component/visualMap/ContinuousView.js | 374 +- .../src/component/visualMap/PiecewiseModel.js | 55 +- .../src/component/visualMap/PiecewiseView.js | 64 +- .../src/component/visualMap/VisualMapModel.js | 60 +- .../src/component/visualMap/VisualMapView.js | 17 +- .../echarts/src/component/visualMap/helper.js | 37 + .../src/component/visualMap/visualCoding.js | 2 +- vendors/echarts/src/coord/View.js | 96 +- vendors/echarts/src/coord/axisDefault.js | 2 + vendors/echarts/src/coord/axisHelper.js | 24 +- vendors/echarts/src/coord/geo/Geo.js | 23 + vendors/echarts/src/coord/geo/GeoModel.js | 66 +- vendors/echarts/src/coord/geo/geoCreator.js | 44 +- vendors/echarts/src/data/Graph.js | 27 +- vendors/echarts/src/data/List.js | 61 +- vendors/echarts/src/data/Tree.js | 30 +- vendors/echarts/src/data/helper/linkList.js | 148 +- vendors/echarts/src/echarts.js | 10 +- vendors/echarts/src/layout/points.js | 26 +- vendors/echarts/src/model/Model.js | 8 +- vendors/echarts/src/model/OptionManager.js | 41 +- vendors/echarts/src/model/Series.js | 68 +- vendors/echarts/src/scale/Time.js | 35 +- vendors/echarts/src/util/graphic.js | 63 +- vendors/echarts/src/util/model.js | 78 +- vendors/echarts/src/util/number.js | 55 +- vendors/echarts/src/visual/VisualMapping.js | 162 +- vendors/echarts/src/visual/visualDefault.js | 5 + vendors/echarts/test/README.md | 55 + vendors/echarts/test/area.html | 14 +- vendors/echarts/test/bar-large.html | 121 + vendors/echarts/test/candlestick.html | 18 + vendors/echarts/test/data/option-view2.json | 11714 ++++++++++ .../test/dataZoom-scatter-category.html | 192 + .../echarts/test/dataZoomHighPrecision.html | 255 +- vendors/echarts/test/geoScatter.html | 38 +- vendors/echarts/test/graph-grid.html | 90 + vendors/echarts/test/graph-simple.html | 126 + vendors/echarts/test/graph.html | 10 + vendors/echarts/test/ie8.html | 102 +- vendors/echarts/test/map.html | 11 +- vendors/echarts/test/markLine.html | 27 +- vendors/echarts/test/markPoint.html | 5 + vendors/echarts/test/media-finance.html | 10 + vendors/echarts/test/radar.html | 4 + vendors/echarts/test/reset.css | 3 +- vendors/echarts/test/sankey.html | 5 + vendors/echarts/test/scale-integer.html | 46 + vendors/echarts/test/scatter.html | 18 +- vendors/echarts/test/timeline-finance.html | 4 + vendors/echarts/test/treemap-disk.html | 4 + vendors/echarts/test/treemap-option.html | 82 +- vendors/echarts/test/treemap-option2.html | 120 + vendors/echarts/test/treemap-simple.html | 214 +- vendors/echarts/test/ut.html | 19 - vendors/echarts/test/ut/{spec => }/.jshintrc | 2 +- vendors/echarts/test/ut/all.js | 9 - vendors/echarts/test/ut/config.js | 23 + vendors/echarts/test/ut/configure | 10 + vendors/echarts/test/ut/core/uiHelper.js | 230 +- vendors/echarts/test/ut/core/utHelper.js | 150 +- .../echarts/test/ut/downloadLastRelease.sh | 3 - vendors/echarts/test/ut/lib/imagediff.js | 392 + .../ut/spec/component/visualMap/setOption.js | 241 + vendors/echarts/test/ut/spec/data/List.js | 26 +- .../echarts/test/ut/spec/model/Component.js | 18 +- vendors/echarts/test/ut/spec/model/Global.js | 189 +- .../test/ut/spec/model/timelineOptions.js | 161 + vendors/echarts/test/ut/spec/ui/config.js | 2 +- vendors/echarts/test/ut/spec/ui/legend.js | 586 + vendors/echarts/test/ut/spec/ui/title.js | 458 +- .../test/ut/spec/ui/title.subtextStyle.js | 353 + .../test/ut/spec/ui/title.textStyle.js | 351 + vendors/echarts/test/ut/spec/util/number.js | 200 + vendors/echarts/test/ut/ui.html | 19 +- vendors/echarts/test/ut/ut.html | 19 + vendors/echarts/test/ut/ut.js | 13 + .../echarts/test/visualMap-continuous.html | 663 + vendors/echarts/test/visualMap-layout.html | 4 +- vendors/echarts/test/visualMap-opacity.html | 208 +- vendors/echarts/test/visualMap-pieces.html | 1 + .../test/visualMap-scatter-continuous.html | 124 - vendors/fastclick/.bower.json | 3 +- vendors/font-awesome/.bower.json | 11 +- vendors/font-awesome/css/font-awesome.css | 29 +- vendors/font-awesome/css/font-awesome.min.css | 4 +- vendors/font-awesome/fonts/4.4.0/index.html | 58 - vendors/font-awesome/fonts/FontAwesome.otf | Bin 123112 -> 124988 bytes .../fonts/fontawesome-webfont.eot | Bin 75220 -> 76518 bytes .../fonts/fontawesome-webfont.svg | 16 +- .../fonts/fontawesome-webfont.ttf | Bin 150920 -> 152796 bytes .../fonts/fontawesome-webfont.woff | Bin 89076 -> 90412 bytes .../fonts/fontawesome-webfont.woff2 | Bin 70728 -> 71896 bytes vendors/font-awesome/less/font-awesome.less | 2 +- vendors/font-awesome/less/icons.less | 11 +- vendors/font-awesome/less/variables.less | 15 +- vendors/font-awesome/scss/_icons.scss | 11 +- vendors/font-awesome/scss/_variables.scss | 15 +- vendors/font-awesome/scss/font-awesome.scss | 2 +- vendors/fullcalendar/.bower.json | 8 +- vendors/fullcalendar/CHANGELOG.md | 19 + vendors/fullcalendar/bower.json | 2 +- vendors/fullcalendar/dist/fullcalendar.css | 49 +- vendors/fullcalendar/dist/fullcalendar.js | 414 +- .../fullcalendar/dist/fullcalendar.min.css | 4 +- vendors/fullcalendar/dist/fullcalendar.min.js | 2483 +- .../fullcalendar/dist/fullcalendar.print.css | 2 +- vendors/fullcalendar/dist/gcal.js | 2 +- vendors/iCheck/.bower.json | 3 +- vendors/jQuery-Smart-Wizard/.bower.json | 3 +- vendors/jquery-knob/.bower.json | 3 +- vendors/jquery-sparkline/.bower.json | 3 +- vendors/jquery.easy-pie-chart/.bower.json | 3 +- vendors/jquery.inputmask/.bower.json | 3 +- vendors/jquery.tagsinput/.bower.json | 3 +- vendors/jquery/.bower.json | 13 +- vendors/jquery/dist/jquery.js | 44 +- vendors/jquery/dist/jquery.min.js | 8 +- vendors/jquery/dist/jquery.min.map | 2 +- vendors/jquery/dist/jquery.slim.js | 7877 ------- vendors/jquery/dist/jquery.slim.min.js | 4 - vendors/jquery/dist/jquery.slim.min.map | 1 - .../jquery/{ => external}/sizzle/LICENSE.txt | 0 .../{ => external}/sizzle/dist/sizzle.js | 0 .../{ => external}/sizzle/dist/sizzle.min.js | 0 .../{ => external}/sizzle/dist/sizzle.min.map | 0 vendors/jquery/src/core/DOMEval.js | 14 - vendors/jquery/src/core/support.js | 18 - vendors/jquery/src/css.js | 13 - vendors/jquery/src/data/accepts.js | 20 - vendors/jquery/src/data/support.js | 23 - vendors/jquery/src/deferred/exceptionHook.js | 19 - vendors/jquery/src/effects/support.js | 58 - vendors/jquery/src/event.js | 7 +- vendors/jquery/src/event/trigger.js | 18 +- .../src/manipulation/createSafeFragment.js | 20 - .../jquery/src/manipulation/var/nodeNames.js | 5 - .../manipulation/var/rleadingWhitespace.js | 3 - vendors/jquery/src/support.js | 63 - vendors/jquery/src/var/deletedIds.js | 3 - .../mjolnic-bootstrap-colorpicker/.bower.json | 3 +- vendors/moment/.bower.json | 2 +- vendors/morris.js/.bower.json | 3 +- vendors/normalize-css/.bower.json | 3 +- vendors/nprogress/.bower.json | 3 +- vendors/parsleyjs/.bower.json | 8 +- vendors/parsleyjs/dist/i18n/lt.js | 29 + vendors/parsleyjs/dist/parsley.js | 13 +- vendors/parsleyjs/dist/parsley.js.map | 2 +- vendors/parsleyjs/dist/parsley.min.js | 6 +- vendors/parsleyjs/dist/parsley.min.js.map | 2 +- vendors/parsleyjs/src/i18n/lt.js | 29 + .../src/parsley/factory/constraint.js | 5 +- vendors/pdfmake/.bower.json | 3 +- vendors/pnotify/.bower.json | 3 +- vendors/select2/.bower.json | 11 +- vendors/select2/.jshintrc | 2 +- vendors/select2/component.json | 2 +- vendors/select2/dist/css/select2.css | 2 + vendors/select2/dist/css/select2.min.css | 2 +- vendors/select2/dist/js/i18n/ar.js | 2 +- vendors/select2/dist/js/i18n/az.js | 2 +- vendors/select2/dist/js/i18n/bg.js | 2 +- vendors/select2/dist/js/i18n/ca.js | 2 +- vendors/select2/dist/js/i18n/cs.js | 2 +- vendors/select2/dist/js/i18n/da.js | 2 +- vendors/select2/dist/js/i18n/de.js | 2 +- vendors/select2/dist/js/i18n/el.js | 3 + vendors/select2/dist/js/i18n/en.js | 2 +- vendors/select2/dist/js/i18n/es.js | 2 +- vendors/select2/dist/js/i18n/et.js | 2 +- vendors/select2/dist/js/i18n/eu.js | 2 +- vendors/select2/dist/js/i18n/fa.js | 2 +- vendors/select2/dist/js/i18n/fi.js | 2 +- vendors/select2/dist/js/i18n/fr.js | 4 +- vendors/select2/dist/js/i18n/gl.js | 2 +- vendors/select2/dist/js/i18n/he.js | 2 +- vendors/select2/dist/js/i18n/hi.js | 2 +- vendors/select2/dist/js/i18n/hr.js | 2 +- vendors/select2/dist/js/i18n/hu.js | 2 +- vendors/select2/dist/js/i18n/id.js | 2 +- vendors/select2/dist/js/i18n/is.js | 2 +- vendors/select2/dist/js/i18n/it.js | 2 +- vendors/select2/dist/js/i18n/ja.js | 2 +- vendors/select2/dist/js/i18n/km.js | 3 + vendors/select2/dist/js/i18n/ko.js | 2 +- vendors/select2/dist/js/i18n/lt.js | 4 +- vendors/select2/dist/js/i18n/lv.js | 2 +- vendors/select2/dist/js/i18n/mk.js | 2 +- vendors/select2/dist/js/i18n/ms.js | 2 +- vendors/select2/dist/js/i18n/nb.js | 4 +- vendors/select2/dist/js/i18n/nl.js | 2 +- vendors/select2/dist/js/i18n/pl.js | 2 +- vendors/select2/dist/js/i18n/pt-BR.js | 2 +- vendors/select2/dist/js/i18n/pt.js | 2 +- vendors/select2/dist/js/i18n/ro.js | 2 +- vendors/select2/dist/js/i18n/ru.js | 2 +- vendors/select2/dist/js/i18n/sk.js | 2 +- vendors/select2/dist/js/i18n/sr-Cyrl.js | 2 +- vendors/select2/dist/js/i18n/sr.js | 2 +- vendors/select2/dist/js/i18n/sv.js | 2 +- vendors/select2/dist/js/i18n/th.js | 2 +- vendors/select2/dist/js/i18n/tr.js | 2 +- vendors/select2/dist/js/i18n/uk.js | 2 +- vendors/select2/dist/js/i18n/vi.js | 2 +- vendors/select2/dist/js/i18n/zh-CN.js | 2 +- vendors/select2/dist/js/i18n/zh-TW.js | 2 +- vendors/select2/dist/js/select2.full.js | 201 +- vendors/select2/dist/js/select2.full.min.js | 6 +- vendors/select2/dist/js/select2.js | 201 +- vendors/select2/dist/js/select2.min.js | 5 +- .../docs/_includes/examples/basics.html | 37 +- vendors/select2/docs/_includes/footer.html | 2 +- vendors/select2/docs/_includes/head.html | 12 + .../docs/_includes/options/data/ajax.html | 38 + .../_includes/options/dropdown/placement.html | 4 + .../_includes/options/dropdown/tagging.html | 39 + .../docs/_includes/options/events/jquery.html | 12 + vendors/select2/docs/browserconfig.xml | 11 + .../docs/images/android-chrome-36x36.png | Bin 0 -> 916 bytes .../docs/images/android-chrome-48x48.png | Bin 0 -> 1109 bytes .../docs/images/android-chrome-72x72.png | Bin 0 -> 1533 bytes .../docs/images/apple-touch-icon-57x57.png | Bin 0 -> 1894 bytes .../docs/images/apple-touch-icon-60x60.png | Bin 0 -> 1952 bytes .../docs/images/apple-touch-icon-72x72.png | Bin 0 -> 1626 bytes .../images/apple-touch-icon-precomposed.png | Bin 0 -> 1586 bytes .../select2/docs/images/apple-touch-icon.png | Bin 0 -> 1626 bytes vendors/select2/docs/images/favicon-16x16.png | Bin 0 -> 655 bytes vendors/select2/docs/images/favicon-32x32.png | Bin 0 -> 1155 bytes vendors/select2/docs/images/favicon.ico | Bin 0 -> 15086 bytes vendors/select2/docs/images/manifest.json | 23 + .../select2/docs/images/mstile-150x150.png | Bin 0 -> 1394 bytes .../select2/docs/images/mstile-310x150.png | Bin 0 -> 1281 bytes vendors/select2/docs/images/mstile-70x70.png | Bin 0 -> 1546 bytes .../select2/docs/images/safari-pinned-tab.svg | 17 + vendors/select2/docs/index.html | 8 +- vendors/select2/package.json | 2 +- vendors/select2/select2.jquery.json | 2 +- vendors/select2/src/js/jquery.select2.js | 3 +- vendors/select2/src/js/select2/core.js | 80 +- vendors/select2/src/js/select2/data/ajax.js | 8 +- .../select2/src/js/select2/data/tokenizer.js | 25 +- .../src/js/select2/dropdown/attachBody.js | 3 +- .../src/js/select2/dropdown/closeOnSelect.js | 5 +- .../select2/src/js/select2/dropdown/search.js | 6 + .../src/js/select2/dropdown/selectOnClose.js | 16 +- vendors/select2/src/js/select2/i18n/el.js | 52 + vendors/select2/src/js/select2/i18n/fr.js | 3 + vendors/select2/src/js/select2/i18n/km.js | 36 + vendors/select2/src/js/select2/i18n/lt.js | 25 +- vendors/select2/src/js/select2/i18n/nb.js | 3 + vendors/select2/src/js/select2/results.js | 33 +- .../src/js/select2/selection/single.js | 6 + vendors/select2/src/js/select2/utils.js | 14 + .../src/scss/theme/default/_multiple.scss | 4 + vendors/select2/tests/data/inputData-tests.js | 4 +- vendors/select2/tests/data/tokenizer-tests.js | 56 +- .../tests/dropdown/positioning-tests.js | 16 +- .../tests/dropdown/selectOnClose-tests.js | 8 +- .../tests/dropdown/stopPropagation-tests.js | 2 +- vendors/select2/tests/integration.html | 6 +- .../select2/tests/integration/dom-changes.js | 257 + .../select2/tests/integration/jquery-calls.js | 30 + .../select2/tests/options/deprecated-tests.js | 8 +- .../select2/tests/results/focusing-tests.js | 138 + .../tests/selection/allowClear-tests.js | 2 +- .../select2/tests/selection/search-tests.js | 58 +- .../tests/selection/stopPropagation-tests.js | 2 +- vendors/select2/tests/unit.html | 6 +- vendors/select2/tests/vendor/qunit-1.14.0.js | 2288 -- .../{qunit-1.14.0.css => qunit-1.23.1.css} | 94 +- vendors/select2/tests/vendor/qunit-1.23.1.js | 4334 ++++ vendors/switchery/.bower.json | 3 +- 668 files changed, 60370 insertions(+), 61953 deletions(-) create mode 100644 vendors/Chart.js/.editorconfig create mode 100644 vendors/Chart.js/.github/ISSUE_TEMPLATE.md create mode 100644 vendors/Chart.js/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 vendors/Chart.js/docs/01-Chart-Configuration.md delete mode 100644 vendors/Chart.js/docs/01-Scales.md create mode 100644 vendors/Chart.js/docs/02-Scales.md rename vendors/Chart.js/docs/{02-Line-Chart.md => 03-Line-Chart.md} (67%) rename vendors/Chart.js/docs/{03-Bar-Chart.md => 04-Bar-Chart.md} (94%) rename vendors/Chart.js/docs/{04-Radar-Chart.md => 05-Radar-Chart.md} (97%) rename vendors/Chart.js/docs/{05-Polar-Area-Chart.md => 06-Polar-Area-Chart.md} (96%) rename vendors/Chart.js/docs/{06-Pie-Doughnut-Chart.md => 07-Pie-Doughnut-Chart.md} (93%) create mode 100644 vendors/Chart.js/docs/08-Bubble-Chart.md rename vendors/Chart.js/docs/{07-Advanced.md => 09-Advanced.md} (98%) rename vendors/Chart.js/docs/{08-Notes.md => 10-Notes.md} (86%) create mode 100644 vendors/Chart.js/test/core.scaleService.tests.js delete mode 100644 vendors/PACE/.bower.json delete mode 100644 vendors/PACE/LICENSE delete mode 100644 vendors/PACE/README.md delete mode 100644 vendors/PACE/bower.json delete mode 100644 vendors/PACE/install.json delete mode 100644 vendors/PACE/pace.coffee delete mode 100644 vendors/PACE/pace.js delete mode 100644 vendors/PACE/pace.min.js delete mode 100644 vendors/PACE/themes/black/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/black/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/black/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/black/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/black/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/black/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/black/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/black/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/black/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/black/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/black/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/black/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/black/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/black/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/blue/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/green/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/green/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/green/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/green/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/green/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/green/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/green/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/green/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/green/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/green/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/green/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/green/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/green/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/green/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/orange/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/pink/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/purple/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/red/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/red/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/red/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/red/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/red/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/red/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/red/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/red/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/red/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/red/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/red/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/red/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/red/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/red/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/silver/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/white/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/white/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/white/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/white/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/white/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/white/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/white/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/white/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/white/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/white/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/white/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/white/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/white/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/white/pace-theme-minimal.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-barber-shop.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-big-counter.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-bounce.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-center-atom.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-center-circle.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-center-radar.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-center-simple.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-corner-indicator.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-fill-left.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-flash.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-flat-top.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-loading-bar.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-mac-osx.css delete mode 100644 vendors/PACE/themes/yellow/pace-theme-minimal.css delete mode 100644 vendors/bernii/gauge.js/.bower.json delete mode 100644 vendors/bernii/gauge.js/README.md delete mode 100644 vendors/bernii/gauge.js/assets/arrow.gif delete mode 100755 vendors/bernii/gauge.js/assets/bg.png delete mode 100644 vendors/bernii/gauge.js/assets/bootstrap.min.css delete mode 100755 vendors/bernii/gauge.js/assets/browsers.png delete mode 100644 vendors/bernii/gauge.js/assets/cross.gif delete mode 100755 vendors/bernii/gauge.js/assets/crosshair.gif delete mode 100755 vendors/bernii/gauge.js/assets/excanvas.compiled.js delete mode 100755 vendors/bernii/gauge.js/assets/fd-slider/fd-slider-tooltip.css delete mode 100755 vendors/bernii/gauge.js/assets/fd-slider/fd-slider.css delete mode 100755 vendors/bernii/gauge.js/assets/fd-slider/fd-slider.js delete mode 100755 vendors/bernii/gauge.js/assets/github.gif delete mode 100644 vendors/bernii/gauge.js/assets/hs.png delete mode 100644 vendors/bernii/gauge.js/assets/hv.png delete mode 100644 vendors/bernii/gauge.js/assets/jscolor.js delete mode 100755 vendors/bernii/gauge.js/assets/main.css delete mode 100755 vendors/bernii/gauge.js/assets/prettify.css delete mode 100755 vendors/bernii/gauge.js/assets/prettify.js delete mode 100755 vendors/bernii/gauge.js/assets/preview.jpg delete mode 100755 vendors/bernii/gauge.js/assets/ribbon.png delete mode 100644 vendors/bernii/gauge.js/assets/strike.png delete mode 100644 vendors/bernii/gauge.js/bower.json delete mode 100644 vendors/bernii/gauge.js/dist/gauge.coffee delete mode 100644 vendors/bernii/gauge.js/dist/gauge.js delete mode 100644 vendors/bernii/gauge.js/dist/gauge.min.js delete mode 100755 vendors/bernii/gauge.js/favicon.ico delete mode 100644 vendors/bernii/gauge.js/index.html create mode 100644 vendors/bootstrap-daterangepicker/example/amd/index.html create mode 100644 vendors/bootstrap-daterangepicker/example/amd/main.js create mode 100644 vendors/bootstrap-daterangepicker/example/amd/require.js create mode 100644 vendors/bootstrap-daterangepicker/example/browserify/README.md create mode 100644 vendors/bootstrap-daterangepicker/example/browserify/bundle.js create mode 100644 vendors/bootstrap-daterangepicker/example/browserify/index.html create mode 100644 vendors/bootstrap-daterangepicker/example/browserify/main.js delete mode 100644 vendors/echarts/.jshintignore create mode 100644 vendors/echarts/src/chart/graph/adjustEdge.js create mode 100644 vendors/echarts/src/chart/graph/edgeVisual.js create mode 100644 vendors/echarts/src/chart/graph/simpleLayoutEdge.js rename vendors/echarts/src/{chart/helper/dataSelectableMixin.js => component/helper/selectableMixin.js} (51%) create mode 100644 vendors/echarts/test/README.md create mode 100644 vendors/echarts/test/bar-large.html create mode 100644 vendors/echarts/test/data/option-view2.json create mode 100644 vendors/echarts/test/dataZoom-scatter-category.html create mode 100644 vendors/echarts/test/graph-grid.html create mode 100644 vendors/echarts/test/graph-simple.html create mode 100644 vendors/echarts/test/scale-integer.html create mode 100644 vendors/echarts/test/treemap-option2.html delete mode 100755 vendors/echarts/test/ut.html rename vendors/echarts/test/ut/{spec => }/.jshintrc (93%) delete mode 100755 vendors/echarts/test/ut/all.js create mode 100644 vendors/echarts/test/ut/config.js create mode 100644 vendors/echarts/test/ut/configure delete mode 100755 vendors/echarts/test/ut/downloadLastRelease.sh create mode 100644 vendors/echarts/test/ut/lib/imagediff.js create mode 100644 vendors/echarts/test/ut/spec/component/visualMap/setOption.js create mode 100644 vendors/echarts/test/ut/spec/model/timelineOptions.js create mode 100644 vendors/echarts/test/ut/spec/ui/legend.js create mode 100644 vendors/echarts/test/ut/spec/ui/title.subtextStyle.js create mode 100644 vendors/echarts/test/ut/spec/ui/title.textStyle.js create mode 100644 vendors/echarts/test/ut/spec/util/number.js create mode 100644 vendors/echarts/test/ut/ut.html create mode 100644 vendors/echarts/test/ut/ut.js create mode 100644 vendors/echarts/test/visualMap-continuous.html delete mode 100644 vendors/echarts/test/visualMap-scatter-continuous.html delete mode 100644 vendors/font-awesome/fonts/4.4.0/index.html delete mode 100644 vendors/jquery/dist/jquery.slim.js delete mode 100644 vendors/jquery/dist/jquery.slim.min.js delete mode 100644 vendors/jquery/dist/jquery.slim.min.map rename vendors/jquery/{ => external}/sizzle/LICENSE.txt (100%) rename vendors/jquery/{ => external}/sizzle/dist/sizzle.js (100%) rename vendors/jquery/{ => external}/sizzle/dist/sizzle.min.js (100%) rename vendors/jquery/{ => external}/sizzle/dist/sizzle.min.map (100%) delete mode 100644 vendors/jquery/src/core/DOMEval.js delete mode 100644 vendors/jquery/src/core/support.js delete mode 100644 vendors/jquery/src/data/accepts.js delete mode 100644 vendors/jquery/src/data/support.js delete mode 100644 vendors/jquery/src/deferred/exceptionHook.js delete mode 100644 vendors/jquery/src/effects/support.js delete mode 100644 vendors/jquery/src/manipulation/createSafeFragment.js delete mode 100644 vendors/jquery/src/manipulation/var/nodeNames.js delete mode 100644 vendors/jquery/src/manipulation/var/rleadingWhitespace.js delete mode 100644 vendors/jquery/src/support.js delete mode 100644 vendors/jquery/src/var/deletedIds.js create mode 100644 vendors/parsleyjs/dist/i18n/lt.js create mode 100644 vendors/parsleyjs/src/i18n/lt.js create mode 100644 vendors/select2/dist/js/i18n/el.js create mode 100644 vendors/select2/dist/js/i18n/km.js create mode 100644 vendors/select2/docs/browserconfig.xml create mode 100644 vendors/select2/docs/images/android-chrome-36x36.png create mode 100644 vendors/select2/docs/images/android-chrome-48x48.png create mode 100644 vendors/select2/docs/images/android-chrome-72x72.png create mode 100644 vendors/select2/docs/images/apple-touch-icon-57x57.png create mode 100644 vendors/select2/docs/images/apple-touch-icon-60x60.png create mode 100644 vendors/select2/docs/images/apple-touch-icon-72x72.png create mode 100644 vendors/select2/docs/images/apple-touch-icon-precomposed.png create mode 100644 vendors/select2/docs/images/apple-touch-icon.png create mode 100644 vendors/select2/docs/images/favicon-16x16.png create mode 100644 vendors/select2/docs/images/favicon-32x32.png create mode 100644 vendors/select2/docs/images/favicon.ico create mode 100644 vendors/select2/docs/images/manifest.json create mode 100644 vendors/select2/docs/images/mstile-150x150.png create mode 100644 vendors/select2/docs/images/mstile-310x150.png create mode 100644 vendors/select2/docs/images/mstile-70x70.png create mode 100644 vendors/select2/docs/images/safari-pinned-tab.svg create mode 100644 vendors/select2/src/js/select2/i18n/el.js create mode 100644 vendors/select2/src/js/select2/i18n/km.js create mode 100644 vendors/select2/tests/integration/dom-changes.js create mode 100644 vendors/select2/tests/integration/jquery-calls.js create mode 100644 vendors/select2/tests/results/focusing-tests.js delete mode 100644 vendors/select2/tests/vendor/qunit-1.14.0.js rename vendors/select2/tests/vendor/{qunit-1.14.0.css => qunit-1.23.1.css} (69%) create mode 100644 vendors/select2/tests/vendor/qunit-1.23.1.js diff --git a/vendors/Chart.js/.bower.json b/vendors/Chart.js/.bower.json index 24fe5947..f9608e97 100644 --- a/vendors/Chart.js/.bower.json +++ b/vendors/Chart.js/.bower.json @@ -1,8 +1,8 @@ { "name": "Chart.js", - "version": "2.1.0", + "version": "2.1.4", "description": "Simple HTML5 Charts using the canvas element", - "homepage": "https://github.com/nnnick/Chart.js", + "homepage": "https://github.com/chartjs/Chart.js", "author": "nnnick", "license": "MIT", "main": [ @@ -11,11 +11,11 @@ "devDependencies": { "jquery": "~2.1.4" }, - "_release": "2.1.0", + "_release": "2.1.4", "_resolution": { "type": "version", - "tag": "2.1.0", - "commit": "2ee37e12e379ca9b8ad3be7105715bf8c543ead0" + "tag": "v2.1.4", + "commit": "40d76b6a7ba14aeac69b05ad15d713c3402867b2" }, "_source": "https://github.com/nnnick/Chart.js.git", "_target": "^2.0.2", diff --git a/vendors/Chart.js/.editorconfig b/vendors/Chart.js/.editorconfig new file mode 100644 index 00000000..4e0d877e --- /dev/null +++ b/vendors/Chart.js/.editorconfig @@ -0,0 +1,10 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false diff --git a/vendors/Chart.js/.github/ISSUE_TEMPLATE.md b/vendors/Chart.js/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..cb905e6c --- /dev/null +++ b/vendors/Chart.js/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,2 @@ +- [ ] I have read the [guidelines for contributing](https://github.com/chartjs/Chart.js/blob/master/CONTRIBUTING.md) +- [ ] I have included an example of my issue on a website such as [JS Bin](http://jsbin.com/), [JS Fiddle](http://jsfiddle.net/), or [Codepen](http://codepen.io/pen/). ([Template](http://codepen.io/pen?template=JXVYzq)) \ No newline at end of file diff --git a/vendors/Chart.js/.github/PULL_REQUEST_TEMPLATE.md b/vendors/Chart.js/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..b7cc39f1 --- /dev/null +++ b/vendors/Chart.js/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,2 @@ +- [ ] I have read the [guidelines for contributing](https://github.com/chartjs/Chart.js/blob/master/CONTRIBUTING.md) +- [ ] I have included an example of my changes on a website such as [JS Bin](http://jsbin.com/), [JS Fiddle](http://jsfiddle.net/), or [Codepen](http://codepen.io/pen/). ([Template](http://codepen.io/pen?template=JXVYzq)) \ No newline at end of file diff --git a/vendors/Chart.js/.gitignore b/vendors/Chart.js/.gitignore index a3589d29..a79806fd 100644 --- a/vendors/Chart.js/.gitignore +++ b/vendors/Chart.js/.gitignore @@ -9,5 +9,5 @@ docs/index.md bower_components/ coverage/* - +.idea nbproject/* diff --git a/vendors/Chart.js/README.md b/vendors/Chart.js/README.md index 547a92f8..c40df39d 100644 --- a/vendors/Chart.js/README.md +++ b/vendors/Chart.js/README.md @@ -16,7 +16,7 @@ To install via npm / bower: npm install chart.js --save bower install Chart.js --save ``` -CDN: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0/Chart.js +CDN: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js ## Documentation @@ -31,6 +31,8 @@ For support using Chart.js, please post questions with the [`chartjs` tag on Sta ## Building and Testing `gulp build`, `gulp test` +Thanks to [BrowserStack](https://browserstack.com) for allowing our team to test on thousands of browsers. + ## License Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT). diff --git a/vendors/Chart.js/bower.json b/vendors/Chart.js/bower.json index e1bb8c25..1802ae6e 100644 --- a/vendors/Chart.js/bower.json +++ b/vendors/Chart.js/bower.json @@ -1,8 +1,8 @@ { "name": "Chart.js", - "version": "2.1.0", + "version": "2.1.4", "description": "Simple HTML5 Charts using the canvas element", - "homepage": "https://github.com/nnnick/Chart.js", + "homepage": "https://github.com/chartjs/Chart.js", "author": "nnnick", "license": "MIT", "main": [ @@ -11,4 +11,4 @@ "devDependencies": { "jquery": "~2.1.4" } -} +} \ No newline at end of file diff --git a/vendors/Chart.js/dist/Chart.bundle.js b/vendors/Chart.js/dist/Chart.bundle.js index 68d4b054..ec077f95 100644 --- a/vendors/Chart.js/dist/Chart.bundle.js +++ b/vendors/Chart.js/dist/Chart.bundle.js @@ -1,13 +1,721 @@ /*! * Chart.js * http://chartjs.org/ - * Version: 2.0.2 + * Version: 2.1.4 * * Copyright 2016 Nick Downie * Released under the MIT license * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md */ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o lum2) { + return (lum1 + 0.05) / (lum2 + 0.05); + } + return (lum2 + 0.05) / (lum1 + 0.05); + }, + + level: function (color2) { + var contrastRatio = this.contrast(color2); + if (contrastRatio >= 7.1) { + return 'AAA'; + } + + return (contrastRatio >= 4.5) ? 'AA' : ''; + }, + + dark: function () { + // YIQ equation from http://24ways.org/2010/calculating-color-contrast + var rgb = this.values.rgb; + var yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; + return yiq < 128; + }, + + light: function () { + return !this.dark(); + }, + + negate: function () { + var rgb = []; + for (var i = 0; i < 3; i++) { + rgb[i] = 255 - this.values.rgb[i]; + } + this.setValues('rgb', rgb); + return this; + }, + + lighten: function (ratio) { + var hsl = this.values.hsl; + hsl[2] += hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + darken: function (ratio) { + var hsl = this.values.hsl; + hsl[2] -= hsl[2] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + saturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] += hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + desaturate: function (ratio) { + var hsl = this.values.hsl; + hsl[1] -= hsl[1] * ratio; + this.setValues('hsl', hsl); + return this; + }, + + whiten: function (ratio) { + var hwb = this.values.hwb; + hwb[1] += hwb[1] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + blacken: function (ratio) { + var hwb = this.values.hwb; + hwb[2] += hwb[2] * ratio; + this.setValues('hwb', hwb); + return this; + }, + + greyscale: function () { + var rgb = this.values.rgb; + // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale + var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; + this.setValues('rgb', [val, val, val]); + return this; + }, + + clearer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha - (alpha * ratio)); + return this; + }, + + opaquer: function (ratio) { + var alpha = this.values.alpha; + this.setValues('alpha', alpha + (alpha * ratio)); + return this; + }, + + rotate: function (degrees) { + var hsl = this.values.hsl; + var hue = (hsl[0] + degrees) % 360; + hsl[0] = hue < 0 ? 360 + hue : hue; + this.setValues('hsl', hsl); + return this; + }, + + /** + * Ported from sass implementation in C + * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 + */ + mix: function (mixinColor, weight) { + var color1 = this; + var color2 = mixinColor; + var p = weight === undefined ? 0.5 : weight; + + var w = 2 * p - 1; + var a = color1.alpha() - color2.alpha(); + + var w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + + return this + .rgb( + w1 * color1.red() + w2 * color2.red(), + w1 * color1.green() + w2 * color2.green(), + w1 * color1.blue() + w2 * color2.blue() + ) + .alpha(color1.alpha() * p + color2.alpha() * (1 - p)); + }, + + toJSON: function () { + return this.rgb(); + }, + + clone: function () { + // NOTE(SB): using node-clone creates a dependency to Buffer when using browserify, + // making the final build way to big to embed in Chart.js. So let's do it manually, + // assuming that values to clone are 1 dimension arrays containing only numbers, + // except 'alpha' which is a number. + var result = new Color(); + var source = this.values; + var target = result.values; + var value, type; + + for (var prop in source) { + if (source.hasOwnProperty(prop)) { + value = source[prop]; + type = ({}).toString.call(value); + if (type === '[object Array]') { + target[prop] = value.slice(0); + } else if (type === '[object Number]') { + target[prop] = value; + } else { + console.error('unexpected color value:', value); + } + } + } + + return result; + } +}; + +Color.prototype.spaces = { + rgb: ['red', 'green', 'blue'], + hsl: ['hue', 'saturation', 'lightness'], + hsv: ['hue', 'saturation', 'value'], + hwb: ['hue', 'whiteness', 'blackness'], + cmyk: ['cyan', 'magenta', 'yellow', 'black'] +}; + +Color.prototype.maxes = { + rgb: [255, 255, 255], + hsl: [360, 100, 100], + hsv: [360, 100, 100], + hwb: [360, 100, 100], + cmyk: [100, 100, 100, 100] +}; + +Color.prototype.getValues = function (space) { + var values = this.values; + var vals = {}; + + for (var i = 0; i < space.length; i++) { + vals[space.charAt(i)] = values[space][i]; + } + + if (values.alpha !== 1) { + vals.a = values.alpha; + } + + // {r: 255, g: 255, b: 255, a: 0.4} + return vals; +}; + +Color.prototype.setValues = function (space, vals) { + var values = this.values; + var spaces = this.spaces; + var maxes = this.maxes; + var alpha = 1; + var i; + + if (space === 'alpha') { + alpha = vals; + } else if (vals.length) { + // [10, 10, 10] + values[space] = vals.slice(0, space.length); + alpha = vals[space.length]; + } else if (vals[space.charAt(0)] !== undefined) { + // {r: 10, g: 10, b: 10} + for (i = 0; i < space.length; i++) { + values[space][i] = vals[space.charAt(i)]; + } + + alpha = vals.a; + } else if (vals[spaces[space][0]] !== undefined) { + // {red: 10, green: 10, blue: 10} + var chans = spaces[space]; + + for (i = 0; i < space.length; i++) { + values[space][i] = vals[chans[i]]; + } + + alpha = vals.alpha; + } + + values.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha))); + + if (space === 'alpha') { + return false; + } + + var capped; + + // cap values of the space prior converting all values + for (i = 0; i < space.length; i++) { + capped = Math.max(0, Math.min(maxes[space][i], values[space][i])); + values[space][i] = Math.round(capped); + } + + // convert to all the other color spaces + for (var sname in spaces) { + if (sname !== space) { + values[sname] = convert[space][sname](values[space]); + } + } + + return true; +}; + +Color.prototype.setSpace = function (space, args) { + var vals = args[0]; + + if (vals === undefined) { + // color.rgb() + return this.getValues(space); + } + + // color.rgb(10, 10, 10) + if (typeof vals === 'number') { + vals = Array.prototype.slice.call(args); + } + + this.setValues(space, vals); + return this; +}; + +Color.prototype.setChannel = function (space, index, val) { + var svalues = this.values[space]; + if (val === undefined) { + // color.red() + return svalues[index]; + } else if (val === svalues[index]) { + // color.red(color.red()) + return this; + } + + // color.red(100) + svalues[index] = val; + this.setValues(space, svalues); + + return this; +}; + +if (typeof window !== 'undefined') { + window.Color = Color; +} + +module.exports = Color; + +},{"chartjs-color-string":1,"color-convert":4}],3:[function(require,module,exports){ /* MIT license */ module.exports = { @@ -707,7 +1415,7 @@ for (var key in cssKeywords) { reverseKeywords[JSON.stringify(cssKeywords[key])] = key; } -},{}],2:[function(require,module,exports){ +},{}],4:[function(require,module,exports){ var conversions = require("./conversions"); var convert = function() { @@ -800,230 +1508,7 @@ Converter.prototype.getValues = function(space) { }); module.exports = convert; -},{"./conversions":1}],3:[function(require,module,exports){ -/* MIT license */ -var colorNames = require('color-name'); - -module.exports = { - getRgba: getRgba, - getHsla: getHsla, - getRgb: getRgb, - getHsl: getHsl, - getHwb: getHwb, - getAlpha: getAlpha, - - hexString: hexString, - rgbString: rgbString, - rgbaString: rgbaString, - percentString: percentString, - percentaString: percentaString, - hslString: hslString, - hslaString: hslaString, - hwbString: hwbString, - keyword: keyword -} - -function getRgba(string) { - if (!string) { - return; - } - var abbr = /^#([a-fA-F0-9]{3})$/, - hex = /^#([a-fA-F0-9]{6})$/, - rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, - per = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, - keyword = /(\w+)/; - - var rgb = [0, 0, 0], - a = 1, - match = string.match(abbr); - if (match) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i] + match[i], 16); - } - } - else if (match = string.match(hex)) { - match = match[1]; - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16); - } - } - else if (match = string.match(rgba)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = parseInt(match[i + 1]); - } - a = parseFloat(match[4]); - } - else if (match = string.match(per)) { - for (var i = 0; i < rgb.length; i++) { - rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55); - } - a = parseFloat(match[4]); - } - else if (match = string.match(keyword)) { - if (match[1] == "transparent") { - return [0, 0, 0, 0]; - } - rgb = colorNames[match[1]]; - if (!rgb) { - return; - } - } - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = scale(rgb[i], 0, 255); - } - if (!a && a != 0) { - a = 1; - } - else { - a = scale(a, 0, 1); - } - rgb[3] = a; - return rgb; -} - -function getHsla(string) { - if (!string) { - return; - } - var hsl = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hsl); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - s = scale(parseFloat(match[2]), 0, 100), - l = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, s, l, a]; - } -} - -function getHwb(string) { - if (!string) { - return; - } - var hwb = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/; - var match = string.match(hwb); - if (match) { - var alpha = parseFloat(match[4]); - var h = scale(parseInt(match[1]), 0, 360), - w = scale(parseFloat(match[2]), 0, 100), - b = scale(parseFloat(match[3]), 0, 100), - a = scale(isNaN(alpha) ? 1 : alpha, 0, 1); - return [h, w, b, a]; - } -} - -function getRgb(string) { - var rgba = getRgba(string); - return rgba && rgba.slice(0, 3); -} - -function getHsl(string) { - var hsla = getHsla(string); - return hsla && hsla.slice(0, 3); -} - -function getAlpha(string) { - var vals = getRgba(string); - if (vals) { - return vals[3]; - } - else if (vals = getHsla(string)) { - return vals[3]; - } - else if (vals = getHwb(string)) { - return vals[3]; - } -} - -// generators -function hexString(rgb) { - return "#" + hexDouble(rgb[0]) + hexDouble(rgb[1]) - + hexDouble(rgb[2]); -} - -function rgbString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return rgbaString(rgba, alpha); - } - return "rgb(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] + ")"; -} - -function rgbaString(rgba, alpha) { - if (alpha === undefined) { - alpha = (rgba[3] !== undefined ? rgba[3] : 1); - } - return "rgba(" + rgba[0] + ", " + rgba[1] + ", " + rgba[2] - + ", " + alpha + ")"; -} - -function percentString(rgba, alpha) { - if (alpha < 1 || (rgba[3] && rgba[3] < 1)) { - return percentaString(rgba, alpha); - } - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - - return "rgb(" + r + "%, " + g + "%, " + b + "%)"; -} - -function percentaString(rgba, alpha) { - var r = Math.round(rgba[0]/255 * 100), - g = Math.round(rgba[1]/255 * 100), - b = Math.round(rgba[2]/255 * 100); - return "rgba(" + r + "%, " + g + "%, " + b + "%, " + (alpha || rgba[3] || 1) + ")"; -} - -function hslString(hsla, alpha) { - if (alpha < 1 || (hsla[3] && hsla[3] < 1)) { - return hslaString(hsla, alpha); - } - return "hsl(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%)"; -} - -function hslaString(hsla, alpha) { - if (alpha === undefined) { - alpha = (hsla[3] !== undefined ? hsla[3] : 1); - } - return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " - + alpha + ")"; -} - -// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax -// (hwb have alpha optional & 1 is default value) -function hwbString(hwb, alpha) { - if (alpha === undefined) { - alpha = (hwb[3] !== undefined ? hwb[3] : 1); - } - return "hwb(" + hwb[0] + ", " + hwb[1] + "%, " + hwb[2] + "%" - + (alpha !== undefined && alpha !== 1 ? ", " + alpha : "") + ")"; -} - -function keyword(rgb) { - return reverseNames[rgb.slice(0, 3)]; -} - -// helpers -function scale(num, min, max) { - return Math.min(Math.max(min, num), max); -} - -function hexDouble(num) { - var str = num.toString(16).toUpperCase(); - return (str.length < 2) ? "0" + str : str; -} - - -//create a list of reverse color names -var reverseNames = {}; -for (var name in colorNames) { - reverseNames[colorNames[name]] = name; -} - -},{"color-name":4}],4:[function(require,module,exports){ +},{"./conversions":3}],5:[function(require,module,exports){ module.exports = { "aliceblue": [240, 248, 255], "antiquewhite": [250, 235, 215], @@ -1174,433 +1659,14 @@ module.exports = { "yellow": [255, 255, 0], "yellowgreen": [154, 205, 50] }; -},{}],5:[function(require,module,exports){ -/* MIT license */ - -var convert = require("color-convert"), - string = require("color-string"); - -var Color = function(obj) { - if (obj instanceof Color) return obj; - if (!(this instanceof Color)) return new Color(obj); - - this.values = { - rgb: [0, 0, 0], - hsl: [0, 0, 0], - hsv: [0, 0, 0], - hwb: [0, 0, 0], - cmyk: [0, 0, 0, 0], - alpha: 1 - } - - // parse Color() argument - if (typeof obj == "string") { - var vals = string.getRgba(obj); - if (vals) { - this.setValues("rgb", vals); - } else if (vals = string.getHsla(obj)) { - this.setValues("hsl", vals); - } else if (vals = string.getHwb(obj)) { - this.setValues("hwb", vals); - } else { - throw new Error("Unable to parse color from string \"" + obj + "\""); - } - } else if (typeof obj == "object") { - var vals = obj; - if (vals["r"] !== undefined || vals["red"] !== undefined) { - this.setValues("rgb", vals) - } else if (vals["l"] !== undefined || vals["lightness"] !== undefined) { - this.setValues("hsl", vals) - } else if (vals["v"] !== undefined || vals["value"] !== undefined) { - this.setValues("hsv", vals) - } else if (vals["w"] !== undefined || vals["whiteness"] !== undefined) { - this.setValues("hwb", vals) - } else if (vals["c"] !== undefined || vals["cyan"] !== undefined) { - this.setValues("cmyk", vals) - } else { - throw new Error("Unable to parse color from object " + JSON.stringify(obj)); - } - } -} - -Color.prototype = { - rgb: function(vals) { - return this.setSpace("rgb", arguments); - }, - hsl: function(vals) { - return this.setSpace("hsl", arguments); - }, - hsv: function(vals) { - return this.setSpace("hsv", arguments); - }, - hwb: function(vals) { - return this.setSpace("hwb", arguments); - }, - cmyk: function(vals) { - return this.setSpace("cmyk", arguments); - }, - - rgbArray: function() { - return this.values.rgb; - }, - hslArray: function() { - return this.values.hsl; - }, - hsvArray: function() { - return this.values.hsv; - }, - hwbArray: function() { - if (this.values.alpha !== 1) { - return this.values.hwb.concat([this.values.alpha]) - } - return this.values.hwb; - }, - cmykArray: function() { - return this.values.cmyk; - }, - rgbaArray: function() { - var rgb = this.values.rgb; - return rgb.concat([this.values.alpha]); - }, - hslaArray: function() { - var hsl = this.values.hsl; - return hsl.concat([this.values.alpha]); - }, - alpha: function(val) { - if (val === undefined) { - return this.values.alpha; - } - this.setValues("alpha", val); - return this; - }, - - red: function(val) { - return this.setChannel("rgb", 0, val); - }, - green: function(val) { - return this.setChannel("rgb", 1, val); - }, - blue: function(val) { - return this.setChannel("rgb", 2, val); - }, - hue: function(val) { - return this.setChannel("hsl", 0, val); - }, - saturation: function(val) { - return this.setChannel("hsl", 1, val); - }, - lightness: function(val) { - return this.setChannel("hsl", 2, val); - }, - saturationv: function(val) { - return this.setChannel("hsv", 1, val); - }, - whiteness: function(val) { - return this.setChannel("hwb", 1, val); - }, - blackness: function(val) { - return this.setChannel("hwb", 2, val); - }, - value: function(val) { - return this.setChannel("hsv", 2, val); - }, - cyan: function(val) { - return this.setChannel("cmyk", 0, val); - }, - magenta: function(val) { - return this.setChannel("cmyk", 1, val); - }, - yellow: function(val) { - return this.setChannel("cmyk", 2, val); - }, - black: function(val) { - return this.setChannel("cmyk", 3, val); - }, - - hexString: function() { - return string.hexString(this.values.rgb); - }, - rgbString: function() { - return string.rgbString(this.values.rgb, this.values.alpha); - }, - rgbaString: function() { - return string.rgbaString(this.values.rgb, this.values.alpha); - }, - percentString: function() { - return string.percentString(this.values.rgb, this.values.alpha); - }, - hslString: function() { - return string.hslString(this.values.hsl, this.values.alpha); - }, - hslaString: function() { - return string.hslaString(this.values.hsl, this.values.alpha); - }, - hwbString: function() { - return string.hwbString(this.values.hwb, this.values.alpha); - }, - keyword: function() { - return string.keyword(this.values.rgb, this.values.alpha); - }, - - rgbNumber: function() { - return (this.values.rgb[0] << 16) | (this.values.rgb[1] << 8) | this.values.rgb[2]; - }, - - luminosity: function() { - // http://www.w3.org/TR/WCAG20/#relativeluminancedef - var rgb = this.values.rgb; - var lum = []; - for (var i = 0; i < rgb.length; i++) { - var chan = rgb[i] / 255; - lum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4) - } - return 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2]; - }, - - contrast: function(color2) { - // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - var lum1 = this.luminosity(); - var lum2 = color2.luminosity(); - if (lum1 > lum2) { - return (lum1 + 0.05) / (lum2 + 0.05) - }; - return (lum2 + 0.05) / (lum1 + 0.05); - }, - - level: function(color2) { - var contrastRatio = this.contrast(color2); - return (contrastRatio >= 7.1) ? 'AAA' : (contrastRatio >= 4.5) ? 'AA' : ''; - }, - - dark: function() { - // YIQ equation from http://24ways.org/2010/calculating-color-contrast - var rgb = this.values.rgb, - yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000; - return yiq < 128; - }, - - light: function() { - return !this.dark(); - }, - - negate: function() { - var rgb = [] - for (var i = 0; i < 3; i++) { - rgb[i] = 255 - this.values.rgb[i]; - } - this.setValues("rgb", rgb); - return this; - }, - - lighten: function(ratio) { - this.values.hsl[2] += this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - darken: function(ratio) { - this.values.hsl[2] -= this.values.hsl[2] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - saturate: function(ratio) { - this.values.hsl[1] += this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - desaturate: function(ratio) { - this.values.hsl[1] -= this.values.hsl[1] * ratio; - this.setValues("hsl", this.values.hsl); - return this; - }, - - whiten: function(ratio) { - this.values.hwb[1] += this.values.hwb[1] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - blacken: function(ratio) { - this.values.hwb[2] += this.values.hwb[2] * ratio; - this.setValues("hwb", this.values.hwb); - return this; - }, - - greyscale: function() { - var rgb = this.values.rgb; - // http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale - var val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11; - this.setValues("rgb", [val, val, val]); - return this; - }, - - clearer: function(ratio) { - this.setValues("alpha", this.values.alpha - (this.values.alpha * ratio)); - return this; - }, - - opaquer: function(ratio) { - this.setValues("alpha", this.values.alpha + (this.values.alpha * ratio)); - return this; - }, - - rotate: function(degrees) { - var hue = this.values.hsl[0]; - hue = (hue + degrees) % 360; - hue = hue < 0 ? 360 + hue : hue; - this.values.hsl[0] = hue; - this.setValues("hsl", this.values.hsl); - return this; - }, - - mix: function(color2, weight) { - weight = 1 - (weight == null ? 0.5 : weight); - - // algorithm from Sass's mix(). Ratio of first color in mix is - // determined by the alphas of both colors and the weight - var t1 = weight * 2 - 1, - d = this.alpha() - color2.alpha(); - - var weight1 = (((t1 * d == -1) ? t1 : (t1 + d) / (1 + t1 * d)) + 1) / 2; - var weight2 = 1 - weight1; - - var rgb = this.rgbArray(); - var rgb2 = color2.rgbArray(); - - for (var i = 0; i < rgb.length; i++) { - rgb[i] = rgb[i] * weight1 + rgb2[i] * weight2; - } - this.setValues("rgb", rgb); - - var alpha = this.alpha() * weight + color2.alpha() * (1 - weight); - this.setValues("alpha", alpha); - - return this; - }, - - toJSON: function() { - return this.rgb(); - }, - - clone: function() { - return new Color(this.rgb()); - } -} - - -Color.prototype.getValues = function(space) { - var vals = {}; - for (var i = 0; i < space.length; i++) { - vals[space.charAt(i)] = this.values[space][i]; - } - if (this.values.alpha != 1) { - vals["a"] = this.values.alpha; - } - // {r: 255, g: 255, b: 255, a: 0.4} - return vals; -} - -Color.prototype.setValues = function(space, vals) { - var spaces = { - "rgb": ["red", "green", "blue"], - "hsl": ["hue", "saturation", "lightness"], - "hsv": ["hue", "saturation", "value"], - "hwb": ["hue", "whiteness", "blackness"], - "cmyk": ["cyan", "magenta", "yellow", "black"] - }; - - var maxes = { - "rgb": [255, 255, 255], - "hsl": [360, 100, 100], - "hsv": [360, 100, 100], - "hwb": [360, 100, 100], - "cmyk": [100, 100, 100, 100] - }; - - var alpha = 1; - if (space == "alpha") { - alpha = vals; - } else if (vals.length) { - // [10, 10, 10] - this.values[space] = vals.slice(0, space.length); - alpha = vals[space.length]; - } else if (vals[space.charAt(0)] !== undefined) { - // {r: 10, g: 10, b: 10} - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[space.charAt(i)]; - } - alpha = vals.a; - } else if (vals[spaces[space][0]] !== undefined) { - // {red: 10, green: 10, blue: 10} - var chans = spaces[space]; - for (var i = 0; i < space.length; i++) { - this.values[space][i] = vals[chans[i]]; - } - alpha = vals.alpha; - } - this.values.alpha = Math.max(0, Math.min(1, (alpha !== undefined ? alpha : this.values.alpha))); - if (space == "alpha") { - return; - } - - // cap values of the space prior converting all values - for (var i = 0; i < space.length; i++) { - var capped = Math.max(0, Math.min(maxes[space][i], this.values[space][i])); - this.values[space][i] = Math.round(capped); - } - - // convert to all the other color spaces - for (var sname in spaces) { - if (sname != space) { - this.values[sname] = convert[space][sname](this.values[space]) - } - - // cap values - for (var i = 0; i < sname.length; i++) { - var capped = Math.max(0, Math.min(maxes[sname][i], this.values[sname][i])); - this.values[sname][i] = Math.round(capped); - } - } - return true; -} - -Color.prototype.setSpace = function(space, args) { - var vals = args[0]; - if (vals === undefined) { - // color.rgb() - return this.getValues(space); - } - // color.rgb(10, 10, 10) - if (typeof vals == "number") { - vals = Array.prototype.slice.call(args); - } - this.setValues(space, vals); - return this; -} - -Color.prototype.setChannel = function(space, index, val) { - if (val === undefined) { - // color.red() - return this.values[space][index]; - } - // color.red(100) - this.values[space][index] = val; - this.setValues(space, this.values[space]); - return this; -} - -window.Color = module.exports = Color - -},{"color-convert":2,"color-string":3}],6:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ //! moment.js -//! version : 2.10.6 +//! version : 2.13.0 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com -(function (global, factory) { +;(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.moment = factory() @@ -1619,7 +1685,7 @@ window.Color = module.exports = Color } function isArray(input) { - return Object.prototype.toString.call(input) === '[object Array]'; + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; } function isDate(input) { @@ -1672,7 +1738,9 @@ window.Color = module.exports = Color invalidMonth : null, invalidFormat : false, userInvalidated : false, - iso : false + iso : false, + parsedDateParts : [], + meridiem : null }; } @@ -1683,9 +1751,30 @@ window.Color = module.exports = Color return m._pf; } + var some; + if (Array.prototype.some) { + some = Array.prototype.some; + } else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; + } + function valid__isValid(m) { if (m._isValid == null) { var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); m._isValid = !isNaN(m._d.getTime()) && flags.overflow < 0 && !flags.empty && @@ -1693,7 +1782,8 @@ window.Color = module.exports = Color !flags.invalidWeekday && !flags.nullInput && !flags.invalidFormat && - !flags.userInvalidated; + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); if (m._strict) { m._isValid = m._isValid && @@ -1717,39 +1807,45 @@ window.Color = module.exports = Color return m; } + function isUndefined(input) { + return input === void 0; + } + + // Plugins that add properties should also add the key here (null value), + // so we can properly clone ourselves. var momentProperties = utils_hooks__hooks.momentProperties = []; function copyConfig(to, from) { var i, prop, val; - if (typeof from._isAMomentObject !== 'undefined') { + if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; } - if (typeof from._i !== 'undefined') { + if (!isUndefined(from._i)) { to._i = from._i; } - if (typeof from._f !== 'undefined') { + if (!isUndefined(from._f)) { to._f = from._f; } - if (typeof from._l !== 'undefined') { + if (!isUndefined(from._l)) { to._l = from._l; } - if (typeof from._strict !== 'undefined') { + if (!isUndefined(from._strict)) { to._strict = from._strict; } - if (typeof from._tzm !== 'undefined') { + if (!isUndefined(from._tzm)) { to._tzm = from._tzm; } - if (typeof from._isUTC !== 'undefined') { + if (!isUndefined(from._isUTC)) { to._isUTC = from._isUTC; } - if (typeof from._offset !== 'undefined') { + if (!isUndefined(from._offset)) { to._offset = from._offset; } - if (typeof from._pf !== 'undefined') { + if (!isUndefined(from._pf)) { to._pf = getParsingFlags(from); } - if (typeof from._locale !== 'undefined') { + if (!isUndefined(from._locale)) { to._locale = from._locale; } @@ -1757,7 +1853,7 @@ window.Color = module.exports = Color for (i in momentProperties) { prop = momentProperties[i]; val = from[prop]; - if (typeof val !== 'undefined') { + if (!isUndefined(val)) { to[prop] = val; } } @@ -1804,6 +1900,7 @@ window.Color = module.exports = Color return value; } + // compare two arrays, return the number of differences function compareArrays(array1, array2, dontConvert) { var len = Math.min(array1.length, array2.length), lengthDiff = Math.abs(array1.length - array2.length), @@ -1818,9 +1915,108 @@ window.Color = module.exports = Color return diffs + lengthDiff; } - function Locale() { + function warn(msg) { + if (utils_hooks__hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } } + function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (utils_hooks__hooks.deprecationHandler != null) { + utils_hooks__hooks.deprecationHandler(null, msg); + } + if (firstTime) { + warn(msg + '\nArguments: ' + Array.prototype.slice.call(arguments).join(', ') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); + } + + var deprecations = {}; + + function deprecateSimple(name, msg) { + if (utils_hooks__hooks.deprecationHandler != null) { + utils_hooks__hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } + } + + utils_hooks__hooks.suppressDeprecationWarnings = false; + utils_hooks__hooks.deprecationHandler = null; + + function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; + } + + function isObject(input) { + return Object.prototype.toString.call(input) === '[object Object]'; + } + + function locale_set__set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _ordinalParseLenient. + this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source); + } + + function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + return res; + } + + function Locale(config) { + if (config != null) { + this.set(config); + } + } + + var keys; + + if (Object.keys) { + keys = Object.keys; + } else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; + } + + // internal storage for locale config files var locales = {}; var globalLocale; @@ -1858,7 +2054,7 @@ window.Color = module.exports = Color function loadLocale(name) { var oldLocale = null; // TODO: Find a better way to register and load all the locales in Node - if (!locales[name] && typeof module !== 'undefined' && + if (!locales[name] && (typeof module !== 'undefined') && module && module.exports) { try { oldLocale = globalLocale._abbr; @@ -1877,7 +2073,7 @@ window.Color = module.exports = Color function locale_locales__getSetGlobalLocale (key, values) { var data; if (key) { - if (typeof values === 'undefined') { + if (isUndefined(values)) { data = locale_locales__getLocale(key); } else { @@ -1893,11 +2089,25 @@ window.Color = module.exports = Color return globalLocale._abbr; } - function defineLocale (name, values) { - if (values !== null) { - values.abbr = name; - locales[name] = locales[name] || new Locale(); - locales[name].set(values); + function defineLocale (name, config) { + if (config !== null) { + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale'); + config = mergeConfigs(locales[name]._config, config); + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + config = mergeConfigs(locales[config.parentLocale]._config, config); + } else { + // treat as if there is no base config + deprecateSimple('parentLocaleUndefined', + 'specified parentLocale is not defined yet'); + } + } + locales[name] = new Locale(config); // backwards compat for now: also set the locale locale_locales__getSetGlobalLocale(name); @@ -1910,6 +2120,31 @@ window.Color = module.exports = Color } } + function updateLocale(name, config) { + if (config != null) { + var locale; + if (locales[name] != null) { + config = mergeConfigs(locales[name]._config, config); + } + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + locale_locales__getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; + } + // returns locale data function locale_locales__getLocale (key) { var locale; @@ -1934,6 +2169,10 @@ window.Color = module.exports = Color return chooseLocale(key); } + function locale_locales__listLocales() { + return keys(locales); + } + var aliases = {}; function addUnitAlias (unit, shorthand) { @@ -1975,11 +2214,14 @@ window.Color = module.exports = Color } function get_set__get (mom, unit) { - return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit](); + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; } function get_set__set (mom, unit, value) { - return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + if (mom.isValid()) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } } // MOMENTS @@ -1992,7 +2234,7 @@ window.Color = module.exports = Color } } else { units = normalizeUnits(units); - if (typeof this[units] === 'function') { + if (isFunction(this[units])) { return this[units](value); } } @@ -2007,7 +2249,7 @@ window.Color = module.exports = Color Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; } - var formattingTokens = /(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; @@ -2060,7 +2302,7 @@ window.Color = module.exports = Color } return function (mom) { - var output = ''; + var output = '', i; for (i = 0; i < length; i++) { output += array[i] instanceof Function ? array[i].call(mom, format) : array[i]; } @@ -2103,6 +2345,8 @@ window.Color = module.exports = Color var match4 = /\d{4}/; // 0000 - 9999 var match6 = /[+-]?\d{6}/; // -999999 - 999999 var match1to2 = /\d\d?/; // 0 - 99 + var match3to4 = /\d\d\d\d?/; // 999 - 9999 + var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 var match1to3 = /\d{1,3}/; // 0 - 999 var match1to4 = /\d{1,4}/; // 0 - 9999 var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 @@ -2111,23 +2355,19 @@ window.Color = module.exports = Color var matchSigned = /[+-]?\d+/; // -inf - inf var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z + var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123 // any word (or two) characters or numbers including two/three word month in arabic. + // includes scottish gaelic two word and hyphenated months var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i; + var regexes = {}; - function isFunction (sth) { - // https://github.com/moment/moment/issues/2325 - return typeof sth === 'function' && - Object.prototype.toString.call(sth) === '[object Function]'; - } - - function addRegexToken (token, regex, strictRegex) { - regexes[token] = isFunction(regex) ? regex : function (isStrict) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { return (isStrict && strictRegex) ? strictRegex : regex; }; } @@ -2142,9 +2382,13 @@ window.Color = module.exports = Color // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript function unescapeFormat(s) { - return s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { return p1 || p2 || p3 || p4; - }).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); + })); + } + + function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } var tokens = {}; @@ -2184,6 +2428,25 @@ window.Color = module.exports = Color var MINUTE = 4; var SECOND = 5; var MILLISECOND = 6; + var WEEK = 7; + var WEEKDAY = 8; + + var indexOf; + + if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; + } else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; + } function daysInMonth(year, month) { return new Date(Date.UTC(year, month + 1, 0)).getUTCDate(); @@ -2211,8 +2474,12 @@ window.Color = module.exports = Color addRegexToken('M', match1to2); addRegexToken('MM', match1to2, match2); - addRegexToken('MMM', matchWord); - addRegexToken('MMMM', matchWord); + addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); + }); + addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); + }); addParseToken(['M', 'MM'], function (input, array) { array[MONTH] = toInt(input) - 1; @@ -2230,25 +2497,76 @@ window.Color = module.exports = Color // LOCALES + var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/; var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); - function localeMonths (m) { - return this._months[m.month()]; + function localeMonths (m, format) { + return isArray(this._months) ? this._months[m.month()] : + this._months[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; } var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); - function localeMonthsShort (m) { - return this._monthsShort[m.month()]; + function localeMonthsShort (m, format) { + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; + } + + function units_month__handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = create_utc__createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } } function localeMonthsParse (monthName, format, strict) { var i, mom, regex; + if (this._monthsParseExact) { + return units_month__handleStrictParse.call(this, monthName, format, strict); + } + if (!this._monthsParse) { this._monthsParse = []; this._longMonthsParse = []; this._shortMonthsParse = []; } + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse for (i = 0; i < 12; i++) { // make the regex if we don't have it already mom = create_utc__createUTC([2000, i]); @@ -2276,12 +2594,20 @@ window.Color = module.exports = Color function setMonth (mom, value) { var dayOfMonth; - // TODO: Move this out of here! + if (!mom.isValid()) { + // No op + return mom; + } + if (typeof value === 'string') { - value = mom.localeData().monthsParse(value); - // TODO: Another silent failure? - if (typeof value !== 'number') { - return mom; + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (typeof value !== 'number') { + return mom; + } } } @@ -2304,6 +2630,72 @@ window.Color = module.exports = Color return daysInMonth(this.year(), this.month()); } + var defaultMonthsShortRegex = matchWord; + function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } + } + + var defaultMonthsRegex = matchWord; + function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } + } + + function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + } + function checkOverflow (m) { var overflow; var a = m._a; @@ -2321,6 +2713,12 @@ window.Color = module.exports = Color if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { overflow = DATE; } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } getParsingFlags(m).overflow = overflow; } @@ -2328,51 +2726,39 @@ window.Color = module.exports = Color return m; } - function warn(msg) { - if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) { - console.warn('Deprecation warning: ' + msg); - } - } + // iso 8601 regex + // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) + var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; + var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/; - function deprecate(msg, fn) { - var firstTime = true; - - return extend(function () { - if (firstTime) { - warn(msg + '\n' + (new Error()).stack); - firstTime = false; - } - return fn.apply(this, arguments); - }, fn); - } - - var deprecations = {}; - - function deprecateSimple(name, msg) { - if (!deprecations[name]) { - warn(msg); - deprecations[name] = true; - } - } - - utils_hooks__hooks.suppressDeprecationWarnings = false; - - var from_string__isoRegex = /^\s*(?:[+-]\d{6}|\d{4})-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; var isoDates = [ - ['YYYYYY-MM-DD', /[+-]\d{6}-\d{2}-\d{2}/], - ['YYYY-MM-DD', /\d{4}-\d{2}-\d{2}/], - ['GGGG-[W]WW-E', /\d{4}-W\d{2}-\d/], - ['GGGG-[W]WW', /\d{4}-W\d{2}/], - ['YYYY-DDD', /\d{4}-\d{3}/] + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] ]; // iso time formats and regexes var isoTimes = [ - ['HH:mm:ss.SSSS', /(T| )\d\d:\d\d:\d\d\.\d+/], - ['HH:mm:ss', /(T| )\d\d:\d\d:\d\d/], - ['HH:mm', /(T| )\d\d:\d\d/], - ['HH', /(T| )\d\d/] + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] ]; var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; @@ -2381,26 +2767,49 @@ window.Color = module.exports = Color function configFromISO(config) { var i, l, string = config._i, - match = from_string__isoRegex.exec(string); + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; if (match) { getParsingFlags(config).iso = true; + for (i = 0, l = isoDates.length; i < l; i++) { - if (isoDates[i][1].exec(string)) { - config._f = isoDates[i][0]; + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; break; } } - for (i = 0, l = isoTimes.length; i < l; i++) { - if (isoTimes[i][1].exec(string)) { - // match[6] should be 'T' or space - config._f += (match[6] || ' ') + isoTimes[i][0]; - break; + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; } } - if (string.match(matchOffset)) { - config._f += 'Z'; + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); configFromStringAndFormat(config); } else { config._isValid = false; @@ -2438,8 +2847,8 @@ window.Color = module.exports = Color //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply var date = new Date(y, m, d, h, M, s, ms); - //the date constructor doesn't accept years < 1970 - if (y < 1970) { + //the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { date.setFullYear(y); } return date; @@ -2447,12 +2856,21 @@ window.Color = module.exports = Color function createUTCDate (y) { var date = new Date(Date.UTC.apply(null, arguments)); - if (y < 1970) { + + //the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { date.setUTCFullYear(y); } return date; } + // FORMATTING + + addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; + }); + addFormatToken(0, ['YY', 2], 0, function () { return this.year() % 100; }); @@ -2480,6 +2898,9 @@ window.Color = module.exports = Color addParseToken('YY', function (input, array) { array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input); }); + addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); + }); // HELPERS @@ -2499,130 +2920,72 @@ window.Color = module.exports = Color // MOMENTS - var getSetYear = makeGetSet('FullYear', false); + var getSetYear = makeGetSet('FullYear', true); function getIsLeapYear () { return isLeapYear(this.year()); } - addFormatToken('w', ['ww', 2], 'wo', 'week'); - addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + // start-of-first-week - start-of-year + function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; - // ALIASES - - addUnitAlias('week', 'w'); - addUnitAlias('isoWeek', 'W'); - - // PARSING - - addRegexToken('w', match1to2); - addRegexToken('ww', match1to2, match2); - addRegexToken('W', match1to2); - addRegexToken('WW', match1to2, match2); - - addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { - week[token.substr(0, 1)] = toInt(input); - }); - - // HELPERS - - // firstDayOfWeek 0 = sun, 6 = sat - // the day of the week that starts the week - // (usually sunday or monday) - // firstDayOfWeekOfYear 0 = sun, 6 = sat - // the first week is the week that contains the first - // of this day of the week - // (eg. ISO weeks use thursday (4)) - function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) { - var end = firstDayOfWeekOfYear - firstDayOfWeek, - daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(), - adjustedMoment; - - - if (daysToDayOfWeek > end) { - daysToDayOfWeek -= 7; - } - - if (daysToDayOfWeek < end - 7) { - daysToDayOfWeek += 7; - } - - adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd'); - return { - week: Math.ceil(adjustedMoment.dayOfYear() / 7), - year: adjustedMoment.year() - }; + return -fwdlw + fwd - 1; } - // LOCALES - - function localeWeek (mom) { - return weekOfYear(mom, this._week.dow, this._week.doy).week; - } - - var defaultLocaleWeek = { - dow : 0, // Sunday is the first day of the week. - doy : 6 // The week that contains Jan 1st is the first week of the year. - }; - - function localeFirstDayOfWeek () { - return this._week.dow; - } - - function localeFirstDayOfYear () { - return this._week.doy; - } - - // MOMENTS - - function getSetWeek (input) { - var week = this.localeData().week(this); - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - function getSetISOWeek (input) { - var week = weekOfYear(this, 1, 4).week; - return input == null ? week : this.add((input - week) * 7, 'd'); - } - - addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); - - // ALIASES - - addUnitAlias('dayOfYear', 'DDD'); - - // PARSING - - addRegexToken('DDD', match1to3); - addRegexToken('DDDD', match3); - addParseToken(['DDD', 'DDDD'], function (input, array, config) { - config._dayOfYear = toInt(input); - }); - - // HELPERS - //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday - function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) { - var week1Jan = 6 + firstDayOfWeek - firstDayOfWeekOfYear, janX = createUTCDate(year, 0, 1 + week1Jan), d = janX.getUTCDay(), dayOfYear; - if (d < firstDayOfWeek) { - d += 7; + function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; } - weekday = weekday != null ? 1 * weekday : firstDayOfWeek; - - dayOfYear = 1 + week1Jan + 7 * (week - 1) - d + weekday; - return { - year: dayOfYear > 0 ? year : year - 1, - dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear + year: resYear, + dayOfYear: resDayOfYear }; } - // MOMENTS + function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; - function getSetDayOfYear (input) { - var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; - return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; + } + + function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; } // Pick the first defined of two or three arguments. @@ -2637,11 +3000,12 @@ window.Color = module.exports = Color } function currentDateArray(config) { - var now = new Date(); + // hooks is actually the exported moment object + var nowValue = new Date(utils_hooks__hooks.now()); if (config._useUTC) { - return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()]; + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; } - return [now.getFullYear(), now.getMonth(), now.getDate()]; + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; } // convert an array to a date. @@ -2711,7 +3075,7 @@ window.Color = module.exports = Color } function dayOfYearFromWeekInfo(config) { - var w, weekYear, week, weekday, dow, doy, temp; + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; w = config._w; if (w.GG != null || w.W != null || w.E != null) { @@ -2725,6 +3089,9 @@ window.Color = module.exports = Color weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year); week = defaults(w.W, 1); weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } } else { dow = config._locale._week.dow; doy = config._locale._week.doy; @@ -2735,23 +3102,32 @@ window.Color = module.exports = Color if (w.d != null) { // weekday -- low day numbers are considered next week weekday = w.d; - if (weekday < dow) { - ++week; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; } } else if (w.e != null) { // local weekday -- counting starts from begining of week weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } } else { // default to begining of week weekday = dow; } } - temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow); - - config._a[YEAR] = temp.year; - config._dayOfYear = temp.dayOfYear; + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } } + // constant that refers to the ISO standard utils_hooks__hooks.ISO_8601 = function () {}; // date from string and format string @@ -2776,6 +3152,8 @@ window.Color = module.exports = Color for (i = 0; i < tokens.length; i++) { token = tokens[i]; parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); if (parsedInput) { skipped = string.substr(0, string.indexOf(parsedInput)); if (skipped.length > 0) { @@ -2811,6 +3189,9 @@ window.Color = module.exports = Color config._a[HOUR] > 0) { getParsingFlags(config).bigHour = undefined; } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; // handle meridiem config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); @@ -2844,6 +3225,7 @@ window.Color = module.exports = Color } } + // date from string and array of format strings function configFromStringAndArray(config) { var tempConfig, bestMoment, @@ -2894,7 +3276,9 @@ window.Color = module.exports = Color } var i = normalizeObjectUnits(config._i); - config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond]; + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); configFromArray(config); } @@ -2936,15 +3320,19 @@ window.Color = module.exports = Color configFromInput(config); } + if (!valid__isValid(config)) { + config._d = null; + } + return config; } function configFromInput(config) { var input = config._i; if (input === undefined) { - config._d = new Date(); + config._d = new Date(utils_hooks__hooks.now()); } else if (isDate(input)) { - config._d = new Date(+input); + config._d = new Date(input.valueOf()); } else if (typeof input === 'string') { configFromString(config); } else if (isArray(input)) { @@ -2986,18 +3374,26 @@ window.Color = module.exports = Color } var prototypeMin = deprecate( - 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', + 'moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', function () { var other = local__createLocal.apply(null, arguments); - return other < this ? this : other; + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return valid__createInvalid(); + } } ); var prototypeMax = deprecate( - 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548', + 'moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548', function () { var other = local__createLocal.apply(null, arguments); - return other > this ? this : other; + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return valid__createInvalid(); + } } ); @@ -3036,6 +3432,10 @@ window.Color = module.exports = Color return pickBy('isAfter', args); } + var now = function () { + return Date.now ? Date.now() : +(new Date()); + }; + function Duration (duration) { var normalizedInput = normalizeObjectUnits(duration), years = normalizedInput.year || 0, @@ -3052,7 +3452,7 @@ window.Color = module.exports = Color this._milliseconds = +milliseconds + seconds * 1e3 + // 1000 minutes * 6e4 + // 1000 * 60 - hours * 36e5; // 1000 * 60 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 // Because of dateAddRemove treats 24 hours as different from a // day when working around DST, we need to store them separately this._days = +days + @@ -3075,6 +3475,8 @@ window.Color = module.exports = Color return obj instanceof Duration; } + // FORMATTING + function offset (token, separator) { addFormatToken(token, 0, 0, function () { var offset = this.utcOffset(); @@ -3092,11 +3494,11 @@ window.Color = module.exports = Color // PARSING - addRegexToken('Z', matchOffset); - addRegexToken('ZZ', matchOffset); + addRegexToken('Z', matchShortOffset); + addRegexToken('ZZ', matchShortOffset); addParseToken(['Z', 'ZZ'], function (input, array, config) { config._useUTC = true; - config._tzm = offsetFromString(input); + config._tzm = offsetFromString(matchShortOffset, input); }); // HELPERS @@ -3106,8 +3508,8 @@ window.Color = module.exports = Color // '-1530' > ['-15', '30'] var chunkOffset = /([\+\-]|\d\d)/gi; - function offsetFromString(string) { - var matches = ((string || '').match(matchOffset) || []); + function offsetFromString(matcher, string) { + var matches = ((string || '').match(matcher) || []); var chunk = matches[matches.length - 1] || []; var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; var minutes = +(parts[1] * 60) + toInt(parts[2]); @@ -3120,9 +3522,9 @@ window.Color = module.exports = Color var res, diff; if (model._isUTC) { res = model.clone(); - diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : local__createLocal(input).valueOf()) - res.valueOf(); // Use low-level api, because this fn is low-level api. - res._d.setTime(+res._d + diff); + res._d.setTime(res._d.valueOf() + diff); utils_hooks__hooks.updateOffset(res, false); return res; } else { @@ -3157,11 +3559,13 @@ window.Color = module.exports = Color function getSetOffset (input, keepLocalTime) { var offset = this._offset || 0, localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } if (input != null) { if (typeof input === 'string') { - input = offsetFromString(input); - } - if (Math.abs(input) < 16) { + input = offsetFromString(matchShortOffset, input); + } else if (Math.abs(input) < 16) { input = input * 60; } if (!this._isUTC && keepLocalTime) { @@ -3221,12 +3625,15 @@ window.Color = module.exports = Color if (this._tzm) { this.utcOffset(this._tzm); } else if (typeof this._i === 'string') { - this.utcOffset(offsetFromString(this._i)); + this.utcOffset(offsetFromString(matchOffset, this._i)); } return this; } function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } input = input ? local__createLocal(input).utcOffset() : 0; return (this.utcOffset() - input) % 60 === 0; @@ -3240,7 +3647,7 @@ window.Color = module.exports = Color } function isDaylightSavingTimeShifted () { - if (typeof this._isDSTShifted !== 'undefined') { + if (!isUndefined(this._isDSTShifted)) { return this._isDSTShifted; } @@ -3261,22 +3668,24 @@ window.Color = module.exports = Color } function isLocal () { - return !this._isUTC; + return this.isValid() ? !this._isUTC : false; } function isUtcOffset () { - return this._isUTC; + return this.isValid() ? this._isUTC : false; } function isUtc () { - return this._isUTC && this._offset === 0; + return this.isValid() ? this._isUTC && this._offset === 0 : false; } - var aspNetRegex = /(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/; + // ASP.NET json date format regex + var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere - var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/; + // and further modified to allow for strings containing both week and day + var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/; function create__createDuration (input, key) { var duration = input, @@ -3309,16 +3718,16 @@ window.Color = module.exports = Color s : toInt(match[SECOND]) * sign, ms : toInt(match[MILLISECOND]) * sign }; - } else if (!!(match = create__isoRegex.exec(input))) { + } else if (!!(match = isoRegex.exec(input))) { sign = (match[1] === '-') ? -1 : 1; duration = { y : parseIso(match[2], sign), M : parseIso(match[3], sign), - d : parseIso(match[4], sign), - h : parseIso(match[5], sign), - m : parseIso(match[6], sign), - s : parseIso(match[7], sign), - w : parseIso(match[8], sign) + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) }; } else if (duration == null) {// checks for null or undefined duration = {}; @@ -3366,6 +3775,10 @@ window.Color = module.exports = Color function momentsDifference(base, other) { var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + other = cloneWithOffset(other, base); if (base.isBefore(other)) { res = positiveMomentsDifference(base, other); @@ -3378,6 +3791,15 @@ window.Color = module.exports = Color return res; } + function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } + } + + // TODO: remove 'name' arg after deprecation is removed function createAdder(direction, name) { return function (val, period) { var dur, tmp; @@ -3396,12 +3818,18 @@ window.Color = module.exports = Color function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) { var milliseconds = duration._milliseconds, - days = duration._days, - months = duration._months; + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + updateOffset = updateOffset == null ? true : updateOffset; if (milliseconds) { - mom._d.setTime(+mom._d + milliseconds * isAdding); + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); } if (days) { get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding); @@ -3429,7 +3857,10 @@ window.Color = module.exports = Color diff < 1 ? 'sameDay' : diff < 2 ? 'nextDay' : diff < 7 ? 'nextWeek' : 'sameElse'; - return this.format(formats && formats[format] || this.localeData().calendar(format, this, local__createLocal(now))); + + var output = formats && (isFunction(formats[format]) ? formats[format]() : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, local__createLocal(now))); } function clone () { @@ -3437,50 +3868,77 @@ window.Color = module.exports = Color } function isAfter (input, units) { - var inputMs; - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); if (units === 'millisecond') { - input = isMoment(input) ? input : local__createLocal(input); - return +this > +input; + return this.valueOf() > localInput.valueOf(); } else { - inputMs = isMoment(input) ? +input : +local__createLocal(input); - return inputMs < +this.clone().startOf(units); + return localInput.valueOf() < this.clone().startOf(units).valueOf(); } } function isBefore (input, units) { - var inputMs; - units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond'); + var localInput = isMoment(input) ? input : local__createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); if (units === 'millisecond') { - input = isMoment(input) ? input : local__createLocal(input); - return +this < +input; + return this.valueOf() < localInput.valueOf(); } else { - inputMs = isMoment(input) ? +input : +local__createLocal(input); - return +this.clone().endOf(units) < inputMs; + return this.clone().endOf(units).valueOf() < localInput.valueOf(); } } - function isBetween (from, to, units) { - return this.isAfter(from, units) && this.isBefore(to, units); + function isBetween (from, to, units, inclusivity) { + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && + (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); } function isSame (input, units) { - var inputMs; + var localInput = isMoment(input) ? input : local__createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } units = normalizeUnits(units || 'millisecond'); if (units === 'millisecond') { - input = isMoment(input) ? input : local__createLocal(input); - return +this === +input; + return this.valueOf() === localInput.valueOf(); } else { - inputMs = +local__createLocal(input); - return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units)); + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); } } + function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); + } + + function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); + } + function diff (input, units, asFloat) { - var that = cloneWithOffset(input, this), - zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4, + var that, + zoneDelta, delta, output; + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + units = normalizeUnits(units); if (units === 'year' || units === 'month' || units === 'quarter') { @@ -3519,10 +3977,12 @@ window.Color = module.exports = Color adjust = (b - anchor) / (anchor2 - anchor); } - return -(wholeMonthDiff + adjust); + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; } utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; + utils_hooks__hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; function toString () { return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); @@ -3531,7 +3991,7 @@ window.Color = module.exports = Color function moment_format__toISOString () { var m = this.clone().utc(); if (0 < m.year() && m.year() <= 9999) { - if ('function' === typeof Date.prototype.toISOString) { + if (isFunction(Date.prototype.toISOString)) { // native implementation is ~50x faster, use it when we can return this.toDate().toISOString(); } else { @@ -3543,15 +4003,21 @@ window.Color = module.exports = Color } function format (inputString) { - var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat); + if (!inputString) { + inputString = this.isUtc() ? utils_hooks__hooks.defaultFormatUtc : utils_hooks__hooks.defaultFormat; + } + var output = formatMoment(this, inputString); return this.localeData().postformat(output); } function from (time, withoutSuffix) { - if (!this.isValid()) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { return this.localeData().invalidDate(); } - return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); } function fromNow (withoutSuffix) { @@ -3559,16 +4025,22 @@ window.Color = module.exports = Color } function to (time, withoutSuffix) { - if (!this.isValid()) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + local__createLocal(time).isValid())) { + return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { return this.localeData().invalidDate(); } - return create__createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); } function toNow (withoutSuffix) { return this.to(local__createLocal(), withoutSuffix); } + // If passed a locale key, it will set the locale for this + // instance. Otherwise, it will return the locale configuration + // variables for this instance. function locale (key) { var newLocaleData; @@ -3613,6 +4085,7 @@ window.Color = module.exports = Color case 'week': case 'isoWeek': case 'day': + case 'date': this.hours(0); /* falls through */ case 'hour': @@ -3646,19 +4119,25 @@ window.Color = module.exports = Color if (units === undefined || units === 'millisecond') { return this; } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); } function to_type__valueOf () { - return +this._d - ((this._offset || 0) * 60000); + return this._d.valueOf() - ((this._offset || 0) * 60000); } function unix () { - return Math.floor(+this / 1000); + return Math.floor(this.valueOf() / 1000); } function toDate () { - return this._offset ? new Date(+this) : this._d; + return this._offset ? new Date(this.valueOf()) : this._d; } function toArray () { @@ -3679,6 +4158,11 @@ window.Color = module.exports = Color }; } + function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; + } + function moment_valid__isValid () { return valid__isValid(this); } @@ -3691,6 +4175,18 @@ window.Color = module.exports = Color return getParsingFlags(this).overflow; } + function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; + } + + // FORMATTING + addFormatToken(0, ['gg', 2], 0, function () { return this.weekYear() % 100; }); @@ -3732,22 +4228,20 @@ window.Color = module.exports = Color week[token] = utils_hooks__hooks.parseTwoDigitYear(input); }); - // HELPERS - - function weeksInYear(year, dow, doy) { - return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week; - } - // MOMENTS function getSetWeekYear (input) { - var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year; - return input == null ? year : this.add((input - year), 'y'); + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); } function getSetISOWeekYear (input) { - var year = weekOfYear(this, 1, 4).year; - return input == null ? year : this.add((input - year), 'y'); + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); } function getISOWeeksInYear () { @@ -3759,7 +4253,32 @@ window.Color = module.exports = Color return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); } - addFormatToken('Q', 0, 0, 'quarter'); + function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } + } + + function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; + } + + // FORMATTING + + addFormatToken('Q', 0, 'Qo', 'quarter'); // ALIASES @@ -3778,6 +4297,62 @@ window.Color = module.exports = Color return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); } + // FORMATTING + + addFormatToken('w', ['ww', 2], 'wo', 'week'); + addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + + // ALIASES + + addUnitAlias('week', 'w'); + addUnitAlias('isoWeek', 'W'); + + // PARSING + + addRegexToken('w', match1to2); + addRegexToken('ww', match1to2, match2); + addRegexToken('W', match1to2); + addRegexToken('WW', match1to2, match2); + + addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + }); + + // HELPERS + + // LOCALES + + function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; + } + + var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. + }; + + function localeFirstDayOfWeek () { + return this._week.dow; + } + + function localeFirstDayOfYear () { + return this._week.doy; + } + + // MOMENTS + + function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); + } + + // FORMATTING + addFormatToken('D', ['DD', 2], 'Do', 'date'); // ALIASES @@ -3801,6 +4376,8 @@ window.Color = module.exports = Color var getSetDayOfMonth = makeGetSet('Date', true); + // FORMATTING + addFormatToken('d', 0, 'do', 'day'); addFormatToken('dd', 0, 0, function (format) { @@ -3829,12 +4406,18 @@ window.Color = module.exports = Color addRegexToken('d', match1to2); addRegexToken('e', match1to2); addRegexToken('E', match1to2); - addRegexToken('dd', matchWord); - addRegexToken('ddd', matchWord); - addRegexToken('dddd', matchWord); + addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); + }); + addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); + }); + addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); + }); - addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) { - var weekday = config._locale.weekdaysParse(input); + addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); // if we didn't get a weekday name, mark the date as invalid if (weekday != null) { week.d = weekday; @@ -3869,8 +4452,9 @@ window.Color = module.exports = Color // LOCALES var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); - function localeWeekdays (m) { - return this._weekdays[m.day()]; + function localeWeekdays (m, format) { + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; } var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); @@ -3883,20 +4467,105 @@ window.Color = module.exports = Color return this._weekdaysMin[m.day()]; } - function localeWeekdaysParse (weekdayName) { + function day_of_week__handleStrictParse(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = create_utc__createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } + } + + function localeWeekdaysParse (weekdayName, format, strict) { var i, mom, regex; - this._weekdaysParse = this._weekdaysParse || []; + if (this._weekdaysParseExact) { + return day_of_week__handleStrictParse.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } for (i = 0; i < 7; i++) { // make the regex if we don't have it already + + mom = create_utc__createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + } if (!this._weekdaysParse[i]) { - mom = local__createLocal([2000, 1]).day(i); regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); } // test the regex - if (this._weekdaysParse[i].test(weekdayName)) { + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { return i; } } @@ -3905,6 +4574,9 @@ window.Color = module.exports = Color // MOMENTS function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); if (input != null) { input = parseWeekday(input, this.localeData()); @@ -3915,20 +4587,171 @@ window.Color = module.exports = Color } function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; return input == null ? weekday : this.add(input - weekday, 'd'); } function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } // behaves the same as moment#day except // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) // as a setter, sunday should belong to the previous week. return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7); } - addFormatToken('H', ['HH', 2], 0, 'hour'); - addFormatToken('h', ['hh', 2], 0, function () { + var defaultWeekdaysRegex = matchWord; + function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } + } + + var defaultWeekdaysShortRegex = matchWord; + function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } + } + + var defaultWeekdaysMinRegex = matchWord; + function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } + } + + + function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = create_utc__createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); + } + + // FORMATTING + + addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + + // ALIASES + + addUnitAlias('dayOfYear', 'DDD'); + + // PARSING + + addRegexToken('DDD', match1to3); + addRegexToken('DDDD', match3); + addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); + }); + + // HELPERS + + // MOMENTS + + function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); + } + + // FORMATTING + + function hFormat() { return this.hours() % 12 || 12; + } + + function kFormat() { + return this.hours() || 24; + } + + addFormatToken('H', ['HH', 2], 0, 'hour'); + addFormatToken('h', ['hh', 2], 0, hFormat); + addFormatToken('k', ['kk', 2], 0, kFormat); + + addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); + }); + + addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); + }); + + addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); + }); + + addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); }); function meridiem (token, lowercase) { @@ -3957,6 +4780,11 @@ window.Color = module.exports = Color addRegexToken('HH', match1to2, match2); addRegexToken('hh', match1to2, match2); + addRegexToken('hmm', match3to4); + addRegexToken('hmmss', match5to6); + addRegexToken('Hmm', match3to4); + addRegexToken('Hmmss', match5to6); + addParseToken(['H', 'HH'], HOUR); addParseToken(['a', 'A'], function (input, array, config) { config._isPm = config._locale.isPM(input); @@ -3966,6 +4794,32 @@ window.Color = module.exports = Color array[HOUR] = toInt(input); getParsingFlags(config).bigHour = true; }); + addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; + }); + addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + }); + addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + }); // LOCALES @@ -3993,6 +4847,8 @@ window.Color = module.exports = Color // this rule. var getSetHour = makeGetSet('Hours', true); + // FORMATTING + addFormatToken('m', ['mm', 2], 0, 'minute'); // ALIASES @@ -4009,6 +4865,8 @@ window.Color = module.exports = Color var getSetMinute = makeGetSet('Minutes', false); + // FORMATTING + addFormatToken('s', ['ss', 2], 0, 'second'); // ALIASES @@ -4025,6 +4883,8 @@ window.Color = module.exports = Color var getSetSecond = makeGetSet('Seconds', false); + // FORMATTING + addFormatToken('S', 0, 0, function () { return ~~(this.millisecond() / 100); }); @@ -4080,6 +4940,8 @@ window.Color = module.exports = Color var getSetMillisecond = makeGetSet('Milliseconds', false); + // FORMATTING + addFormatToken('z', 0, 0, 'zoneAbbr'); addFormatToken('zz', 0, 0, 'zoneName'); @@ -4095,40 +4957,43 @@ window.Color = module.exports = Color var momentPrototype__proto = Moment.prototype; - momentPrototype__proto.add = add_subtract__add; - momentPrototype__proto.calendar = moment_calendar__calendar; - momentPrototype__proto.clone = clone; - momentPrototype__proto.diff = diff; - momentPrototype__proto.endOf = endOf; - momentPrototype__proto.format = format; - momentPrototype__proto.from = from; - momentPrototype__proto.fromNow = fromNow; - momentPrototype__proto.to = to; - momentPrototype__proto.toNow = toNow; - momentPrototype__proto.get = getSet; - momentPrototype__proto.invalidAt = invalidAt; - momentPrototype__proto.isAfter = isAfter; - momentPrototype__proto.isBefore = isBefore; - momentPrototype__proto.isBetween = isBetween; - momentPrototype__proto.isSame = isSame; - momentPrototype__proto.isValid = moment_valid__isValid; - momentPrototype__proto.lang = lang; - momentPrototype__proto.locale = locale; - momentPrototype__proto.localeData = localeData; - momentPrototype__proto.max = prototypeMax; - momentPrototype__proto.min = prototypeMin; - momentPrototype__proto.parsingFlags = parsingFlags; - momentPrototype__proto.set = getSet; - momentPrototype__proto.startOf = startOf; - momentPrototype__proto.subtract = add_subtract__subtract; - momentPrototype__proto.toArray = toArray; - momentPrototype__proto.toObject = toObject; - momentPrototype__proto.toDate = toDate; - momentPrototype__proto.toISOString = moment_format__toISOString; - momentPrototype__proto.toJSON = moment_format__toISOString; - momentPrototype__proto.toString = toString; - momentPrototype__proto.unix = unix; - momentPrototype__proto.valueOf = to_type__valueOf; + momentPrototype__proto.add = add_subtract__add; + momentPrototype__proto.calendar = moment_calendar__calendar; + momentPrototype__proto.clone = clone; + momentPrototype__proto.diff = diff; + momentPrototype__proto.endOf = endOf; + momentPrototype__proto.format = format; + momentPrototype__proto.from = from; + momentPrototype__proto.fromNow = fromNow; + momentPrototype__proto.to = to; + momentPrototype__proto.toNow = toNow; + momentPrototype__proto.get = getSet; + momentPrototype__proto.invalidAt = invalidAt; + momentPrototype__proto.isAfter = isAfter; + momentPrototype__proto.isBefore = isBefore; + momentPrototype__proto.isBetween = isBetween; + momentPrototype__proto.isSame = isSame; + momentPrototype__proto.isSameOrAfter = isSameOrAfter; + momentPrototype__proto.isSameOrBefore = isSameOrBefore; + momentPrototype__proto.isValid = moment_valid__isValid; + momentPrototype__proto.lang = lang; + momentPrototype__proto.locale = locale; + momentPrototype__proto.localeData = localeData; + momentPrototype__proto.max = prototypeMax; + momentPrototype__proto.min = prototypeMin; + momentPrototype__proto.parsingFlags = parsingFlags; + momentPrototype__proto.set = getSet; + momentPrototype__proto.startOf = startOf; + momentPrototype__proto.subtract = add_subtract__subtract; + momentPrototype__proto.toArray = toArray; + momentPrototype__proto.toObject = toObject; + momentPrototype__proto.toDate = toDate; + momentPrototype__proto.toISOString = moment_format__toISOString; + momentPrototype__proto.toJSON = toJSON; + momentPrototype__proto.toString = toString; + momentPrototype__proto.unix = unix; + momentPrototype__proto.valueOf = to_type__valueOf; + momentPrototype__proto.creationData = creationData; // Year momentPrototype__proto.year = getSetYear; @@ -4214,7 +5079,7 @@ window.Color = module.exports = Color function locale_calendar__calendar (key, mom, now) { var output = this._calendar[key]; - return typeof output === 'function' ? output.call(mom, now) : output; + return isFunction(output) ? output.call(mom, now) : output; } var defaultLongDateFormat = { @@ -4276,29 +5141,14 @@ window.Color = module.exports = Color function relative__relativeTime (number, withoutSuffix, string, isFuture) { var output = this._relativeTime[string]; - return (typeof output === 'function') ? + return (isFunction(output)) ? output(number, withoutSuffix, string, isFuture) : output.replace(/%d/i, number); } function pastFuture (diff, output) { var format = this._relativeTime[diff > 0 ? 'future' : 'past']; - return typeof format === 'function' ? format(output) : format.replace(/%s/i, output); - } - - function locale_set__set (config) { - var prop, i; - for (i in config) { - prop = config[i]; - if (typeof prop === 'function') { - this[i] = prop; - } else { - this['_' + i] = prop; - } - } - // Lenient ordinal parsing accepts just a number in addition to - // number + (possibly) stuff coming from _ordinalParseLenient. - this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + (/\d{1,2}/).source); + return isFunction(format) ? format(output) : format.replace(/%s/i, output); } var prototype__proto = Locale.prototype; @@ -4320,11 +5170,15 @@ window.Color = module.exports = Color prototype__proto.set = locale_set__set; // Month - prototype__proto.months = localeMonths; - prototype__proto._months = defaultLocaleMonths; - prototype__proto.monthsShort = localeMonthsShort; - prototype__proto._monthsShort = defaultLocaleMonthsShort; - prototype__proto.monthsParse = localeMonthsParse; + prototype__proto.months = localeMonths; + prototype__proto._months = defaultLocaleMonths; + prototype__proto.monthsShort = localeMonthsShort; + prototype__proto._monthsShort = defaultLocaleMonthsShort; + prototype__proto.monthsParse = localeMonthsParse; + prototype__proto._monthsRegex = defaultMonthsRegex; + prototype__proto.monthsRegex = monthsRegex; + prototype__proto._monthsShortRegex = defaultMonthsShortRegex; + prototype__proto.monthsShortRegex = monthsShortRegex; // Week prototype__proto.week = localeWeek; @@ -4341,6 +5195,13 @@ window.Color = module.exports = Color prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort; prototype__proto.weekdaysParse = localeWeekdaysParse; + prototype__proto._weekdaysRegex = defaultWeekdaysRegex; + prototype__proto.weekdaysRegex = weekdaysRegex; + prototype__proto._weekdaysShortRegex = defaultWeekdaysShortRegex; + prototype__proto.weekdaysShortRegex = weekdaysShortRegex; + prototype__proto._weekdaysMinRegex = defaultWeekdaysMinRegex; + prototype__proto.weekdaysMinRegex = weekdaysMinRegex; + // Hours prototype__proto.isPM = localeIsPM; prototype__proto._meridiemParse = defaultLocaleMeridiemParse; @@ -4352,7 +5213,7 @@ window.Color = module.exports = Color return locale[field](utc, format); } - function list (format, index, field, count, setter) { + function listMonthsImpl (format, index, field) { if (typeof format === 'number') { index = format; format = undefined; @@ -4361,35 +5222,79 @@ window.Color = module.exports = Color format = format || ''; if (index != null) { - return lists__get(format, index, field, setter); + return lists__get(format, index, field, 'month'); } var i; var out = []; - for (i = 0; i < count; i++) { - out[i] = lists__get(format, i, field, setter); + for (i = 0; i < 12; i++) { + out[i] = lists__get(format, i, field, 'month'); + } + return out; + } + + // () + // (5) + // (fmt, 5) + // (fmt) + // (true) + // (true, 5) + // (true, fmt, 5) + // (true, fmt) + function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (typeof format === 'number') { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (typeof format === 'number') { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = locale_locales__getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return lists__get(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = lists__get(format, (i + shift) % 7, field, 'day'); } return out; } function lists__listMonths (format, index) { - return list(format, index, 'months', 12, 'month'); + return listMonthsImpl(format, index, 'months'); } function lists__listMonthsShort (format, index) { - return list(format, index, 'monthsShort', 12, 'month'); + return listMonthsImpl(format, index, 'monthsShort'); } - function lists__listWeekdays (format, index) { - return list(format, index, 'weekdays', 7, 'day'); + function lists__listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); } - function lists__listWeekdaysShort (format, index) { - return list(format, index, 'weekdaysShort', 7, 'day'); + function lists__listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); } - function lists__listWeekdaysMin (format, index) { - return list(format, index, 'weekdaysMin', 7, 'day'); + function lists__listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); } locale_locales__getSetGlobalLocale('en', { @@ -4612,15 +5517,15 @@ window.Color = module.exports = Color var years = round(duration.as('y')); var a = seconds < thresholds.s && ['s', seconds] || - minutes === 1 && ['m'] || + minutes <= 1 && ['m'] || minutes < thresholds.m && ['mm', minutes] || - hours === 1 && ['h'] || + hours <= 1 && ['h'] || hours < thresholds.h && ['hh', hours] || - days === 1 && ['d'] || + days <= 1 && ['d'] || days < thresholds.d && ['dd', days] || - months === 1 && ['M'] || + months <= 1 && ['M'] || months < thresholds.M && ['MM', months] || - years === 1 && ['y'] || ['yy', years]; + years <= 1 && ['y'] || ['yy', years]; a[2] = withoutSuffix; a[3] = +posNegDuration > 0; @@ -4741,6 +5646,8 @@ window.Color = module.exports = Color // Side effect imports + // FORMATTING + addFormatToken('X', 0, 0, 'unix'); addFormatToken('x', 0, 0, 'valueOf'); @@ -4758,13 +5665,14 @@ window.Color = module.exports = Color // Side effect imports - utils_hooks__hooks.version = '2.10.6'; + utils_hooks__hooks.version = '2.13.0'; setHookCallback(local__createLocal); utils_hooks__hooks.fn = momentPrototype; utils_hooks__hooks.min = min; utils_hooks__hooks.max = max; + utils_hooks__hooks.now = now; utils_hooks__hooks.utc = create_utc__createUTC; utils_hooks__hooks.unix = moment__createUnix; utils_hooks__hooks.months = lists__listMonths; @@ -4780,9 +5688,12 @@ window.Color = module.exports = Color utils_hooks__hooks.monthsShort = lists__listMonthsShort; utils_hooks__hooks.weekdaysMin = lists__listWeekdaysMin; utils_hooks__hooks.defineLocale = defineLocale; + utils_hooks__hooks.updateLocale = updateLocale; + utils_hooks__hooks.locales = locale_locales__listLocales; utils_hooks__hooks.weekdaysShort = lists__listWeekdaysShort; utils_hooks__hooks.normalizeUnits = normalizeUnits; utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold; + utils_hooks__hooks.prototype = momentPrototype; var _moment = utils_hooks__hooks; @@ -4790,742 +5701,701 @@ window.Color = module.exports = Color })); },{}],7:[function(require,module,exports){ -var Chart = require('./core/core.js')(); - -require('./core/core.helpers')(Chart); -require('./core/core.element')(Chart); -require('./core/core.animation')(Chart); -require('./core/core.controller')(Chart); -require('./core/core.datasetController')(Chart); -require('./core/core.layoutService')(Chart); -require('./core/core.legend')(Chart); -require('./core/core.plugin.js')(Chart); -require('./core/core.scale')(Chart); -require('./core/core.scaleService')(Chart); -require('./core/core.title')(Chart); -require('./core/core.tooltip')(Chart); - -require('./controllers/controller.bar')(Chart); -require('./controllers/controller.bubble')(Chart); -require('./controllers/controller.doughnut')(Chart); -require('./controllers/controller.line')(Chart); -require('./controllers/controller.polarArea')(Chart); -require('./controllers/controller.radar')(Chart); - -require('./scales/scale.category')(Chart); -require('./scales/scale.linear')(Chart); -require('./scales/scale.logarithmic')(Chart); -require('./scales/scale.radialLinear')(Chart); -require('./scales/scale.time')(Chart); - -require('./elements/element.arc')(Chart); -require('./elements/element.line')(Chart); -require('./elements/element.point')(Chart); -require('./elements/element.rectangle')(Chart); - -require('./charts/Chart.Bar')(Chart); -require('./charts/Chart.Bubble')(Chart); -require('./charts/Chart.Doughnut')(Chart); -require('./charts/Chart.Line')(Chart); -require('./charts/Chart.PolarArea')(Chart); -require('./charts/Chart.Radar')(Chart); -require('./charts/Chart.Scatter')(Chart); - -window.Chart = module.exports = Chart; +var Chart = require('./core/core.js')(); + +require('./core/core.helpers')(Chart); +require('./core/core.element')(Chart); +require('./core/core.animation')(Chart); +require('./core/core.controller')(Chart); +require('./core/core.datasetController')(Chart); +require('./core/core.layoutService')(Chart); +require('./core/core.legend')(Chart); +require('./core/core.plugin.js')(Chart); +require('./core/core.scale')(Chart); +require('./core/core.scaleService')(Chart); +require('./core/core.title')(Chart); +require('./core/core.tooltip')(Chart); + +require('./elements/element.arc')(Chart); +require('./elements/element.line')(Chart); +require('./elements/element.point')(Chart); +require('./elements/element.rectangle')(Chart); + +require('./scales/scale.category')(Chart); +require('./scales/scale.linear')(Chart); +require('./scales/scale.logarithmic')(Chart); +require('./scales/scale.radialLinear')(Chart); +require('./scales/scale.time')(Chart); + +// Controllers must be loaded after elements +// See Chart.core.datasetController.dataElementType +require('./controllers/controller.bar')(Chart); +require('./controllers/controller.bubble')(Chart); +require('./controllers/controller.doughnut')(Chart); +require('./controllers/controller.line')(Chart); +require('./controllers/controller.polarArea')(Chart); +require('./controllers/controller.radar')(Chart); + +require('./charts/Chart.Bar')(Chart); +require('./charts/Chart.Bubble')(Chart); +require('./charts/Chart.Doughnut')(Chart); +require('./charts/Chart.Line')(Chart); +require('./charts/Chart.PolarArea')(Chart); +require('./charts/Chart.Radar')(Chart); +require('./charts/Chart.Scatter')(Chart); + +window.Chart = module.exports = Chart; },{"./charts/Chart.Bar":8,"./charts/Chart.Bubble":9,"./charts/Chart.Doughnut":10,"./charts/Chart.Line":11,"./charts/Chart.PolarArea":12,"./charts/Chart.Radar":13,"./charts/Chart.Scatter":14,"./controllers/controller.bar":15,"./controllers/controller.bubble":16,"./controllers/controller.doughnut":17,"./controllers/controller.line":18,"./controllers/controller.polarArea":19,"./controllers/controller.radar":20,"./core/core.animation":21,"./core/core.controller":22,"./core/core.datasetController":23,"./core/core.element":24,"./core/core.helpers":25,"./core/core.js":26,"./core/core.layoutService":27,"./core/core.legend":28,"./core/core.plugin.js":29,"./core/core.scale":30,"./core/core.scaleService":31,"./core/core.title":32,"./core/core.tooltip":33,"./elements/element.arc":34,"./elements/element.line":35,"./elements/element.point":36,"./elements/element.rectangle":37,"./scales/scale.category":38,"./scales/scale.linear":39,"./scales/scale.logarithmic":40,"./scales/scale.radialLinear":41,"./scales/scale.time":42}],8:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bar = function(context, config) { - config.type = 'bar'; - - return new Chart(context, config); - }; - +"use strict"; + +module.exports = function(Chart) { + + Chart.Bar = function(context, config) { + config.type = 'bar'; + + return new Chart(context, config); + }; + }; },{}],9:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Bubble = function(context, config) { - config.type = 'bubble'; - return new Chart(context, config); - }; - +"use strict"; + +module.exports = function(Chart) { + + Chart.Bubble = function(context, config) { + config.type = 'bubble'; + return new Chart(context, config); + }; + }; },{}],10:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Doughnut = function(context, config) { - config.type = 'doughnut'; - - return new Chart(context, config); - }; - +"use strict"; + +module.exports = function(Chart) { + + Chart.Doughnut = function(context, config) { + config.type = 'doughnut'; + + return new Chart(context, config); + }; + }; },{}],11:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.Line = function(context, config) { - config.type = 'line'; - - return new Chart(context, config); - }; - +"use strict"; + +module.exports = function(Chart) { + + Chart.Line = function(context, config) { + config.type = 'line'; + + return new Chart(context, config); + }; + }; },{}],12:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - Chart.PolarArea = function(context, config) { - config.type = 'polarArea'; - - return new Chart(context, config); - }; - +"use strict"; + +module.exports = function(Chart) { + + Chart.PolarArea = function(context, config) { + config.type = 'polarArea'; + + return new Chart(context, config); + }; + }; },{}],13:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - aspectRatio: 1 - }; - - Chart.Radar = function(context, config) { - config.options = helpers.configMerge(defaultConfig, config.options); - config.type = 'radar'; - - return new Chart(context, config); - }; - -}; +"use strict"; + +module.exports = function(Chart) { + + Chart.Radar = function(context, config) { + config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options); + config.type = 'radar'; + + return new Chart(context, config); + }; + +}; },{}],14:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var defaultConfig = { - hover: { - mode: 'single' - }, - - scales: { - xAxes: [{ - type: "linear", // scatter should not use a category axis - position: "bottom", - id: "x-axis-1" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-1" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')'; - } - } - } - }; - - // Register the default config for this type - Chart.defaults.scatter = defaultConfig; - - // Scatter charts use line controllers - Chart.controllers.scatter = Chart.controllers.line; - - Chart.Scatter = function(context, config) { - config.type = 'scatter'; - return new Chart(context, config); - }; - -}; -},{}],15:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bar = { - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - - // Specific to Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // grid line settings - gridLines: { - offsetGridLines: true - } - }], - yAxes: [{ - type: "linear" - }] - } - }; - - Chart.controllers.bar = Chart.DatasetController.extend({ - initialize: function(chart, datasetIndex) { - Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex); - - // Use this to indicate that this is a bar dataset. - this.getMeta().bar = true; - }, - // Get the number of datasets that display bars. We use this to correctly calculate the bar width - getBarCount: function getBarCount() { - var barCount = 0; - helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { - var meta = this.chart.getDatasetMeta(datasetIndex); - if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) { - ++barCount; - } - }, this); - return barCount; - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var rectangle = new Chart.elements.Rectangle({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - var numBars = this.getBarCount(); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, rectangle); - this.updateElement(rectangle, index, true, numBars); - }, - - update: function update(reset) { - var numBars = this.getBarCount(); - - helpers.each(this.getMeta().data, function(rectangle, index) { - this.updateElement(rectangle, index, reset, numBars); - }, this); - }, - - updateElement: function updateElement(rectangle, index, reset, numBars) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var yScalePoint; - - if (yScale.min < 0 && yScale.max < 0) { - // all less than 0. use the top - yScalePoint = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - yScalePoint = yScale.getPixelForValue(yScale.min); - } else { - yScalePoint = yScale.getPixelForValue(0); - } - - helpers.extend(rectangle, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - - // Desired view properties - _model: { - x: this.calculateBarX(index, this.index), - y: reset ? yScalePoint : this.calculateBarY(index, this.index), - - // Tooltip - label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, - - // Appearance - base: reset ? yScalePoint : this.calculateBarBase(this.index, index), - width: this.calculateBarWidth(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) - } - }); - rectangle.pivot(); - }, - - calculateBarBase: function(datasetIndex, index) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var base = 0; - - if (yScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; - - if (value < 0) { - for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - var negDSMeta = this.chart.getDatasetMeta(i); - if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { - base += negDS.data[index] < 0 ? negDS.data[index] : 0; - } - } - } else { - for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - var posDSMeta = this.chart.getDatasetMeta(j); - if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(j)) { - base += posDS.data[index] > 0 ? posDS.data[index] : 0; - } - } - } - - return yScale.getPixelForValue(base); - } - - base = yScale.getPixelForValue(yScale.min); - - if (yScale.beginAtZero || ((yScale.min <= 0 && yScale.max >= 0) || (yScale.min >= 0 && yScale.max <= 0))) { - base = yScale.getPixelForValue(0, 0); - //base += yScale.options.gridLines.lineWidth; - } else if (yScale.min < 0 && yScale.max < 0) { - // All values are negative. Use the top as the base - base = yScale.getPixelForValue(yScale.max); - } - - return base; - - }, - - getRuler: function() { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - var datasetCount = this.getBarCount(); - - var tickWidth = (function() { - var min = xScale.getPixelForTick(1) - xScale.getPixelForTick(0); - for (var i = 2; i < this.getDataset().data.length; i++) { - min = Math.min(xScale.getPixelForTick(i) - xScale.getPixelForTick(i - 1), min); - } - return min; - }).call(this); - var categoryWidth = tickWidth * xScale.options.categoryPercentage; - var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2; - var fullBarWidth = categoryWidth / datasetCount; - - if (xScale.ticks.length !== this.chart.data.labels.length) { - var perc = xScale.ticks.length / this.chart.data.labels.length; - fullBarWidth = fullBarWidth * perc; - } - - var barWidth = fullBarWidth * xScale.options.barPercentage; - var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage); - - return { - datasetCount: datasetCount, - tickWidth: tickWidth, - categoryWidth: categoryWidth, - categorySpacing: categorySpacing, - fullBarWidth: fullBarWidth, - barWidth: barWidth, - barSpacing: barSpacing - }; - }, - - calculateBarWidth: function() { - var xScale = this.getScaleForId(this.getMeta().xAxisID); - var ruler = this.getRuler(); - return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; - }, - - // Get bar index from the given dataset index accounting for the fact that not all bars are visible - getBarIndex: function(datasetIndex) { - var barIndex = 0; - var meta, j; - - for (j = 0; j < datasetIndex; ++j) { - meta = this.chart.getDatasetMeta(j); - if (meta.bar && this.chart.isDatasetVisible(j)) { - ++barIndex; - } - } - - return barIndex; - }, - - calculateBarX: function(index, datasetIndex) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var barIndex = this.getBarIndex(datasetIndex); - - var ruler = this.getRuler(); - var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); - leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0; - - if (xScale.options.stacked) { - return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing; - } - - return leftTick + - (ruler.barWidth / 2) + - ruler.categorySpacing + - (ruler.barWidth * barIndex) + - (ruler.barSpacing / 2) + - (ruler.barSpacing * barIndex); - }, - - calculateBarY: function(index, datasetIndex) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var value = this.getDataset().data[index]; - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); - if (dsMeta.bar && dsMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - } - - return yScale.getPixelForValue(value); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(rectangle, index) { - var d = this.getDataset().data[index]; - if (d !== null && d !== undefined && !isNaN(d)) { - rectangle.transition(easingDecimal).draw(); - } - }, this); - }, - - setHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.hoverBackgroundColor ? rectangle.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(rectangle._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.hoverBorderColor ? rectangle.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(rectangle._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.hoverBorderWidth ? rectangle.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); - }, - - removeHoverStyle: function(rectangle) { - var dataset = this.chart.data.datasets[rectangle._datasetIndex]; - var index = rectangle._index; - - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); - } - - }); - - - // including horizontalBar in the bar file, instead of a file of its own - // it extends bar (like pie extends doughnut) - Chart.defaults.horizontalBar = { +"use strict"; + +module.exports = function(Chart) { + + var defaultConfig = { hover: { - mode: "label" - }, - + mode: 'single' + }, + scales: { xAxes: [{ - type: "linear", - position: "bottom" + type: "linear", // scatter should not use a category axis + position: "bottom", + id: "x-axis-1" // need an ID so datasets can reference the scale }], yAxes: [{ - position: "left", - type: "category", - - // Specific to Horizontal Bar Controller - categoryPercentage: 0.8, - barPercentage: 0.9, - - // grid line settings + type: "linear", + position: "left", + id: "y-axis-1" + }] + }, + + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(tooltipItem, data) { + return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')'; + } + } + } + }; + + // Register the default config for this type + Chart.defaults.scatter = defaultConfig; + + // Scatter charts use line controllers + Chart.controllers.scatter = Chart.controllers.line; + + Chart.Scatter = function(context, config) { + config.type = 'scatter'; + return new Chart(context, config); + }; + +}; +},{}],15:[function(require,module,exports){ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.bar = { + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "category", + + // Specific to Bar Controller + categoryPercentage: 0.8, + barPercentage: 0.9, + + // grid line settings gridLines: { offsetGridLines: true } - }] + }], + yAxes: [{ + type: "linear" + }] + } + }; + + Chart.controllers.bar = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Rectangle, + + initialize: function(chart, datasetIndex) { + Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex); + + // Use this to indicate that this is a bar dataset. + this.getMeta().bar = true; }, - }; - + + // Get the number of datasets that display bars. We use this to correctly calculate the bar width + getBarCount: function getBarCount() { + var barCount = 0; + helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) { + var meta = this.chart.getDatasetMeta(datasetIndex); + if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) { + ++barCount; + } + }, this); + return barCount; + }, + + update: function update(reset) { + helpers.each(this.getMeta().data, function(rectangle, index) { + this.updateElement(rectangle, index, reset); + }, this); + }, + + updateElement: function updateElement(rectangle, index, reset) { + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var yScale = this.getScaleForId(meta.yAxisID); + var scaleBase = yScale.getBasePixel(); + var rectangleElementOptions = this.chart.options.elements.rectangle; + var custom = rectangle.custom || {}; + var dataset = this.getDataset(); + + helpers.extend(rectangle, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: this.index, + _index: index, + + // Desired view properties + _model: { + x: this.calculateBarX(index, this.index), + y: reset ? scaleBase : this.calculateBarY(index, this.index), + + // Tooltip + label: this.chart.data.labels[index], + datasetLabel: dataset.label, + + // Appearance + base: reset ? scaleBase : this.calculateBarBase(this.index, index), + width: this.calculateBarWidth(index), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + } + }); + rectangle.pivot(); + }, + + calculateBarBase: function(datasetIndex, index) { + var meta = this.getMeta(); + var yScale = this.getScaleForId(meta.yAxisID); + var base = 0; + + if (yScale.options.stacked) { + var chart = this.chart; + var datasets = chart.data.datasets; + var value = datasets[datasetIndex].data[index]; + + if (value < 0) { + for (var i = 0; i < datasetIndex; i++) { + var negDS = datasets[i]; + var negDSMeta = chart.getDatasetMeta(i); + if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { + base += negDS.data[index] < 0 ? negDS.data[index] : 0; + } + } + } else { + for (var j = 0; j < datasetIndex; j++) { + var posDS = datasets[j]; + var posDSMeta = chart.getDatasetMeta(j); + if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) { + base += posDS.data[index] > 0 ? posDS.data[index] : 0; + } + } + } + + return yScale.getPixelForValue(base); + } + + return yScale.getBasePixel(); + }, + + getRuler: function(index) { + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var datasetCount = this.getBarCount(); + + var tickWidth; + + if (xScale.options.type === 'category') { + tickWidth = xScale.getPixelForTick(index + 1) - xScale.getPixelForTick(index); + } else { + // Average width + tickWidth = xScale.width / xScale.ticks.length; + } + var categoryWidth = tickWidth * xScale.options.categoryPercentage; + var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2; + var fullBarWidth = categoryWidth / datasetCount; + + if (xScale.ticks.length !== this.chart.data.labels.length) { + var perc = xScale.ticks.length / this.chart.data.labels.length; + fullBarWidth = fullBarWidth * perc; + } + + var barWidth = fullBarWidth * xScale.options.barPercentage; + var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage); + + return { + datasetCount: datasetCount, + tickWidth: tickWidth, + categoryWidth: categoryWidth, + categorySpacing: categorySpacing, + fullBarWidth: fullBarWidth, + barWidth: barWidth, + barSpacing: barSpacing + }; + }, + + calculateBarWidth: function(index) { + var xScale = this.getScaleForId(this.getMeta().xAxisID); + var ruler = this.getRuler(index); + return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; + }, + + // Get bar index from the given dataset index accounting for the fact that not all bars are visible + getBarIndex: function(datasetIndex) { + var barIndex = 0; + var meta, j; + + for (j = 0; j < datasetIndex; ++j) { + meta = this.chart.getDatasetMeta(j); + if (meta.bar && this.chart.isDatasetVisible(j)) { + ++barIndex; + } + } + + return barIndex; + }, + + calculateBarX: function(index, datasetIndex) { + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var barIndex = this.getBarIndex(datasetIndex); + + var ruler = this.getRuler(index); + var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); + leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0; + + if (xScale.options.stacked) { + return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing; + } + + return leftTick + + (ruler.barWidth / 2) + + ruler.categorySpacing + + (ruler.barWidth * barIndex) + + (ruler.barSpacing / 2) + + (ruler.barSpacing * barIndex); + }, + + calculateBarY: function(index, datasetIndex) { + var meta = this.getMeta(); + var yScale = this.getScaleForId(meta.yAxisID); + var value = this.getDataset().data[index]; + + if (yScale.options.stacked) { + + var sumPos = 0, + sumNeg = 0; + + for (var i = 0; i < datasetIndex; i++) { + var ds = this.chart.data.datasets[i]; + var dsMeta = this.chart.getDatasetMeta(i); + if (dsMeta.bar && dsMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { + if (ds.data[index] < 0) { + sumNeg += ds.data[index] || 0; + } else { + sumPos += ds.data[index] || 0; + } + } + } + + if (value < 0) { + return yScale.getPixelForValue(sumNeg + value); + } else { + return yScale.getPixelForValue(sumPos + value); + } + } + + return yScale.getPixelForValue(value); + }, + + draw: function(ease) { + var easingDecimal = ease || 1; + helpers.each(this.getMeta().data, function(rectangle, index) { + var d = this.getDataset().data[index]; + if (d !== null && d !== undefined && !isNaN(d)) { + rectangle.transition(easingDecimal).draw(); + } + }, this); + }, + + setHoverStyle: function(rectangle) { + var dataset = this.chart.data.datasets[rectangle._datasetIndex]; + var index = rectangle._index; + + var custom = rectangle.custom || {}; + var model = rectangle._model; + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); + }, + + removeHoverStyle: function(rectangle) { + var dataset = this.chart.data.datasets[rectangle._datasetIndex]; + var index = rectangle._index; + var custom = rectangle.custom || {}; + var model = rectangle._model; + var rectangleElementOptions = this.chart.options.elements.rectangle; + + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); + } + + }); + + + // including horizontalBar in the bar file, instead of a file of its own + // it extends bar (like pie extends doughnut) + Chart.defaults.horizontalBar = { + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "linear", + position: "bottom" + }], + yAxes: [{ + position: "left", + type: "category", + + // Specific to Horizontal Bar Controller + categoryPercentage: 0.8, + barPercentage: 0.9, + + // grid line settings + gridLines: { + offsetGridLines: true + } + }] + }, + elements: { + rectangle: { + borderSkipped: 'left' + } + }, + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Pick first xLabel for now + var title = ''; + + if (tooltipItems.length > 0) { + if (tooltipItems[0].yLabel) { + title = tooltipItems[0].yLabel; + } else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) { + title = data.labels[tooltipItems[0].index]; + } + } + + return title; + }, + label: function(tooltipItem, data) { + var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; + return datasetLabel + ': ' + tooltipItem.xLabel; + } + } + } + }; + Chart.controllers.horizontalBar = Chart.controllers.bar.extend({ updateElement: function updateElement(rectangle, index, reset, numBars) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var xScalePoint; - - if (xScale.min < 0 && xScale.max < 0) { - // all less than 0. use the right - xScalePoint = xScale.getPixelForValue(xScale.max); - } else if (xScale.min > 0 && xScale.max > 0) { - xScalePoint = xScale.getPixelForValue(xScale.min); - } else { - xScalePoint = xScale.getPixelForValue(0); - } - - helpers.extend(rectangle, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - // Desired view properties + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var yScale = this.getScaleForId(meta.yAxisID); + var scaleBase = xScale.getBasePixel(); + var custom = rectangle.custom || {}; + var dataset = this.getDataset(); + var rectangleElementOptions = this.chart.options.elements.rectangle; + + helpers.extend(rectangle, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: this.index, + _index: index, + + // Desired view properties _model: { - x: reset ? xScalePoint : this.calculateBarX(index, this.index), - y: this.calculateBarY(index, this.index), - - // Tooltip - label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, - - // Appearance - base: reset ? xScalePoint : this.calculateBarBase(this.index, index), - height: this.calculateBarHeight(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) - }, - + x: reset ? scaleBase : this.calculateBarX(index, this.index), + y: this.calculateBarY(index, this.index), + + // Tooltip + label: this.chart.data.labels[index], + datasetLabel: dataset.label, + + // Appearance + base: reset ? scaleBase : this.calculateBarBase(this.index, index), + height: this.calculateBarHeight(index), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + }, + draw: function () { - - var ctx = this._chart.ctx; - var vm = this._view; - - var halfHeight = vm.height / 2, - topY = vm.y - halfHeight, - bottomY = vm.y + halfHeight, - right = vm.base - (vm.base - vm.x), - halfStroke = vm.borderWidth / 2; - - // Canvas doesn't allow us to stroke inside the width so we can - // adjust the sizes to fit if we're setting a stroke on the line + + var ctx = this._chart.ctx; + var vm = this._view; + + var halfHeight = vm.height / 2, + topY = vm.y - halfHeight, + bottomY = vm.y + halfHeight, + right = vm.base - (vm.base - vm.x), + halfStroke = vm.borderWidth / 2; + + // Canvas doesn't allow us to stroke inside the width so we can + // adjust the sizes to fit if we're setting a stroke on the line if (vm.borderWidth) { - topY += halfStroke; - bottomY -= halfStroke; + topY += halfStroke; + bottomY -= halfStroke; right += halfStroke; - } - - ctx.beginPath(); - - ctx.fillStyle = vm.backgroundColor; - ctx.strokeStyle = vm.borderColor; - ctx.lineWidth = vm.borderWidth; - - // Corner points, from bottom-left to bottom-right clockwise - // | 1 2 | - // | 0 3 | - var corners = [ - [vm.base, bottomY], - [vm.base, topY], - [right, topY], - [right, bottomY] - ]; - - // Find first (starting) corner with fallback to 'bottom' - var borders = ['bottom', 'left', 'top', 'right']; - var startCorner = borders.indexOf(vm.borderSkipped, 0); - if (startCorner === -1) - startCorner = 0; - + } + + ctx.beginPath(); + + ctx.fillStyle = vm.backgroundColor; + ctx.strokeStyle = vm.borderColor; + ctx.lineWidth = vm.borderWidth; + + // Corner points, from bottom-left to bottom-right clockwise + // | 1 2 | + // | 0 3 | + var corners = [ + [vm.base, bottomY], + [vm.base, topY], + [right, topY], + [right, bottomY] + ]; + + // Find first (starting) corner with fallback to 'bottom' + var borders = ['bottom', 'left', 'top', 'right']; + var startCorner = borders.indexOf(vm.borderSkipped, 0); + if (startCorner === -1) + startCorner = 0; + function cornerAt(index) { return corners[(startCorner + index) % 4]; - } - - // Draw rectangle from 'startCorner' - ctx.moveTo.apply(ctx, cornerAt(0)); - for (var i = 1; i < 4; i++) - ctx.lineTo.apply(ctx, cornerAt(i)); - - ctx.fill(); + } + + // Draw rectangle from 'startCorner' + ctx.moveTo.apply(ctx, cornerAt(0)); + for (var i = 1; i < 4; i++) + ctx.lineTo.apply(ctx, cornerAt(i)); + + ctx.fill(); if (vm.borderWidth) { ctx.stroke(); } - }, - + }, + inRange: function (mouseX, mouseY) { - var vm = this._view; - var inRange = false; - + var vm = this._view; + var inRange = false; + if (vm) { if (vm.x < vm.base) { inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base); } else { inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x); } - } - + } + return inRange; } - }); - + }); + rectangle.pivot(); - }, - + }, + calculateBarBase: function (datasetIndex, index) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var base = 0; - + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var base = 0; + if (xScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; - + + var value = this.chart.data.datasets[datasetIndex].data[index]; + if (value < 0) { for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - var negDSMeta = this.chart.getDatasetMeta(i); + var negDS = this.chart.data.datasets[i]; + var negDSMeta = this.chart.getDatasetMeta(i); if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) { base += negDS.data[index] < 0 ? negDS.data[index] : 0; } } } else { for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - var posDSMeta = this.chart.getDatasetMeta(j); + var posDS = this.chart.data.datasets[j]; + var posDSMeta = this.chart.getDatasetMeta(j); if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(j)) { base += posDS.data[index] > 0 ? posDS.data[index] : 0; } } - } - + } + return xScale.getPixelForValue(base); - } - - base = xScale.getPixelForValue(xScale.min); - - if (xScale.beginAtZero || ((xScale.min <= 0 && xScale.max >= 0) || (xScale.min >= 0 && xScale.max <= 0))) { - base = xScale.getPixelForValue(0, 0); - } else if (xScale.min < 0 && xScale.max < 0) { - // All values are negative. Use the right as the base - base = xScale.getPixelForValue(xScale.max); - } - - return base; - }, - - getRuler: function () { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - var datasetCount = this.getBarCount(); - - var tickHeight = (function () { - var min = yScale.getPixelForTick(1) - yScale.getPixelForTick(0); - for (var i = 2; i < this.getDataset().data.length; i++) { - min = Math.min(yScale.getPixelForTick(i) - yScale.getPixelForTick(i - 1), min); - } - return min; - }).call(this); - var categoryHeight = tickHeight * yScale.options.categoryPercentage; - var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2; - var fullBarHeight = categoryHeight / datasetCount; - + } + + return xScale.getBasePixel(); + }, + + getRuler: function (index) { + var meta = this.getMeta(); + var yScale = this.getScaleForId(meta.yAxisID); + var datasetCount = this.getBarCount(); + + var tickHeight; + if (yScale.options.type === 'category') { + tickHeight = yScale.getPixelForTick(index + 1) - yScale.getPixelForTick(index); + } else { + // Average width + tickHeight = yScale.width / yScale.ticks.length; + } + var categoryHeight = tickHeight * yScale.options.categoryPercentage; + var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2; + var fullBarHeight = categoryHeight / datasetCount; + if (yScale.ticks.length !== this.chart.data.labels.length) { - var perc = yScale.ticks.length / this.chart.data.labels.length; + var perc = yScale.ticks.length / this.chart.data.labels.length; fullBarHeight = fullBarHeight * perc; - } - - var barHeight = fullBarHeight * yScale.options.barPercentage; - var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage); - + } + + var barHeight = fullBarHeight * yScale.options.barPercentage; + var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage); + return { - datasetCount: datasetCount, - tickHeight: tickHeight, - categoryHeight: categoryHeight, - categorySpacing: categorySpacing, - fullBarHeight: fullBarHeight, - barHeight: barHeight, + datasetCount: datasetCount, + tickHeight: tickHeight, + categoryHeight: categoryHeight, + categorySpacing: categorySpacing, + fullBarHeight: fullBarHeight, + barHeight: barHeight, barSpacing: barSpacing, }; - }, - - calculateBarHeight: function () { - var yScale = this.getScaleForId(this.getMeta().yAxisID); - var ruler = this.getRuler(); + }, + + calculateBarHeight: function (index) { + var yScale = this.getScaleForId(this.getMeta().yAxisID); + var ruler = this.getRuler(index); return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight; - }, - + }, + calculateBarX: function (index, datasetIndex) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - var value = this.getDataset().data[index]; - + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var value = this.getDataset().data[index]; + if (xScale.options.stacked) { - var sumPos = 0, - sumNeg = 0; - + var sumPos = 0, + sumNeg = 0; + for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); + var ds = this.chart.data.datasets[i]; + var dsMeta = this.chart.getDatasetMeta(i); if (dsMeta.bar && dsMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) { if (ds.data[index] < 0) { sumNeg += ds.data[index] || 0; @@ -5533,7435 +6403,7544 @@ module.exports = function(Chart) { sumPos += ds.data[index] || 0; } } - } - + } + if (value < 0) { return xScale.getPixelForValue(sumNeg + value); } else { return xScale.getPixelForValue(sumPos + value); - } - } - + } + } + return xScale.getPixelForValue(value); - }, - + }, + calculateBarY: function (index, datasetIndex) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var barIndex = this.getBarIndex(datasetIndex); - - var ruler = this.getRuler(); - var topTick = yScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); - topTick -= this.chart.isCombo ? (ruler.tickHeight / 2) : 0; - + var meta = this.getMeta(); + var yScale = this.getScaleForId(meta.yAxisID); + var barIndex = this.getBarIndex(datasetIndex); + + var ruler = this.getRuler(index); + var topTick = yScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo); + topTick -= this.chart.isCombo ? (ruler.tickHeight / 2) : 0; + if (yScale.options.stacked) { return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing; - } - - return topTick + - (ruler.barHeight / 2) + - ruler.categorySpacing + - (ruler.barHeight * barIndex) + - (ruler.barSpacing / 2) + + } + + return topTick + + (ruler.barHeight / 2) + + ruler.categorySpacing + + (ruler.barHeight * barIndex) + + (ruler.barSpacing / 2) + (ruler.barSpacing * barIndex); } - }); -}; + }); +}; },{}],16:[function(require,module,exports){ -"use strict"; +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.bubble = { + hover: { + mode: "single" + }, + + scales: { + xAxes: [{ + type: "linear", // bubble should probably use a linear scale by default + position: "bottom", + id: "x-axis-0" // need an ID so datasets can reference the scale + }], + yAxes: [{ + type: "linear", + position: "left", + id: "y-axis-0" + }] + }, + + tooltips: { + callbacks: { + title: function(tooltipItems, data) { + // Title doesn't make sense for scatter since we format the data as a point + return ''; + }, + label: function(tooltipItem, data) { + var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; + var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')'; + } + } + } + }; + + Chart.controllers.bubble = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Point, + + update: function update(reset) { + var meta = this.getMeta(); + var points = meta.data; + + // Update Points + helpers.each(points, function(point, index) { + this.updateElement(point, index, reset); + }, this); + }, + + updateElement: function(point, index, reset) { + var meta = this.getMeta(); + var xScale = this.getScaleForId(meta.xAxisID); + var yScale = this.getScaleForId(meta.yAxisID); + + var custom = point.custom || {}; + var dataset = this.getDataset(); + var data = dataset.data[index]; + var pointElementOptions = this.chart.options.elements.point; + + helpers.extend(point, { + // Utility + _xScale: xScale, + _yScale: yScale, + _datasetIndex: this.index, + _index: index, + + // Desired view properties + _model: { + x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, this.index, this.chart.isCombo), + y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, this.index), + // Appearance + radius: reset ? 0 : custom.radius ? custom.radius : this.getRadius(data), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, pointElementOptions.backgroundColor), + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, pointElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, pointElementOptions.borderWidth), + + // Tooltip + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) + } + }); + + var model = point._model; + model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y)); + + point.pivot(); + }, + + getRadius: function(value) { + return value.r || this.chart.options.elements.point.radius; + }, + + setHoverStyle: function(point) { + // Point + var dataset = this.chart.data.datasets[point._datasetIndex]; + var index = point._index; + var custom = point.custom || {}; + var model = point._model; + + model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); + }, + + removeHoverStyle: function(point) { + var dataset = this.chart.data.datasets[point._datasetIndex]; + var index = point._index; + var custom = point.custom || {}; + var model = point._model; + var pointElementOptions = this.chart.options.elements.point; + + model.radius = custom.radius ? custom.radius : this.getRadius(dataset.data[point._index]); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, pointElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, pointElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, pointElementOptions.borderWidth); + } + }); +}; -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.bubble = { - hover: { - mode: "single" - }, - - scales: { - xAxes: [{ - type: "linear", // bubble should probably use a linear scale by default - position: "bottom", - id: "x-axis-0" // need an ID so datasets can reference the scale - }], - yAxes: [{ - type: "linear", - position: "left", - id: "y-axis-0" - }] - }, - - tooltips: { - callbacks: { - title: function(tooltipItems, data) { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - }, - label: function(tooltipItem, data) { - var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || ''; - var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')'; - } - } - } - }; - - - Chart.controllers.bubble = Chart.DatasetController.extend({ - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var points = meta.data; - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - }, - - updateElement: function(point, index, reset) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - helpers.extend(point, { - // Utility - _chart: this.chart.chart, - _xScale: xScale, - _yScale: yScale, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index), - // Appearance - radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - - point.pivot(); - }, - - getRadius: function(value) { - return value.r || this.chart.options.elements.point.radius; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - - // Transition and Draw the Points - helpers.each(this.getMeta().data, function(point, index) { - point.transition(easingDecimal); - point.draw(); - }); - - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; },{}],17:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.doughnut = { - animation: { - //Boolean - Whether we animate the rotation of the Doughnut - animateRotate: true, - //Boolean - Whether we animate scaling the Doughnut from the centre - animateScale: false - }, - aspectRatio: 1, - hover: { - mode: 'single' - }, - legendCallback: function(chart) { - var text = []; - text.push('
    '); - - if (chart.data.datasets.length) { - for (var i = 0; i < chart.data.datasets[0].data.length; ++i) { - text.push('
  • '); - if (chart.data.labels[i]) { - text.push(chart.data.labels[i]); - } - text.push('
  • '); - } - } - - text.push('
'); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor); - var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor); - var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }, this); - } else { - return []; - } - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - //The percentage of the chart that we cut out of the middle. - cutoutPercentage: 50, - - //The rotation of the chart, where the first data arc begins. - rotation: Math.PI * -0.5, - - //The total circumference of the chart. - circumference: Math.PI * 2.0, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; - } - } - } - }; - - Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut); - helpers.extend(Chart.defaults.pie, { - cutoutPercentage: 0 - }); - - - Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index, colorForNewElement) { - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - if (colorForNewElement && helpers.isArray(this.getDataset().backgroundColor)) { - this.getDataset().backgroundColor.splice(index, 0, colorForNewElement); - } - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, arc); - this.updateElement(arc, index, true); - }, - - // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly - getRingIndex: function getRingIndex(datasetIndex) { - var ringIndex = 0; - - for (var j = 0; j < datasetIndex; ++j) { - if (this.chart.isDatasetVisible(j)) { - ++ringIndex; - } - } - - return ringIndex; - }, - - update: function update(reset) { - var availableWidth = this.chart.chartArea.right - this.chart.chartArea.left - this.chart.options.elements.arc.borderWidth; - var availableHeight = this.chart.chartArea.bottom - this.chart.chartArea.top - this.chart.options.elements.arc.borderWidth; - var minSize = Math.min(availableWidth, availableHeight); - var offset = {x: 0, y: 0}; - - // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc - if (this.chart.options.circumference < Math.PI * 2.0) { - var startAngle = this.chart.options.rotation % (Math.PI * 2.0); - startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); - var endAngle = startAngle + this.chart.options.circumference; - var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; - var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; - var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); - var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); - var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); - var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); - var cutout = this.chart.options.cutoutPercentage / 100.0; - var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; - var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; - var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; - minSize = Math.min(availableWidth / size.width, availableHeight / size.height); - offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; - } - - this.chart.outerRadius = Math.max(minSize / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount(); - this.chart.offsetX = offset.x * this.chart.outerRadius; - this.chart.offsetY = offset.y * this.chart.outerRadius; - - this.getMeta().total = this.calculateTotal(); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index)); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - helpers.each(this.getMeta().data, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - - updateElement: function(arc, index, reset) { - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - var startAngle = this.chart.options.rotation; // non reset case handled later - var endAngle = this.chart.options.rotation; // non reset case handled later - var circumference = reset && this.chart.options.animation.animateRotate ? 0 : arc.hidden? 0 : this.calculateCircumference(this.getDataset().data[index]) * (this.chart.options.circumference / (2.0 * Math.PI)); - var innerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.innerRadius; - var outerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.outerRadius; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - - // Desired view properties - _model: { - x: centerX + this.chart.offsetX, - y: centerY + this.chart.offsetY, - startAngle: startAngle, - endAngle: endAngle, - circumference: circumference, - outerRadius: outerRadius, - innerRadius: innerRadius, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index]) - } - }); - - // Set correct angles if not resetting - if (!reset || !this.chart.options.animation.animateRotate) { - - if (index === 0) { - arc._model.startAngle = this.chart.options.rotation; - } else { - arc._model.startAngle = this.getMeta().data[index - 1]._model.endAngle; - } - - arc._model.endAngle = arc._model.startAngle + arc._model.circumference; - } - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - calculateTotal: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var total = 0; - var value; - - helpers.each(meta.data, function(element, index) { - value = dataset.data[index]; - if (!isNaN(value) && !element.hidden) { - total += Math.abs(value); - } - }); - - return total; - }, - - calculateCircumference: function(value) { - var total = this.getMeta().total; - if (total > 0 && !isNaN(value)) { - return (Math.PI * 2.0) * (value / total); - } else { - return 0; - } - } - }); -}; +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers, + defaults = Chart.defaults; + + defaults.doughnut = { + animation: { + //Boolean - Whether we animate the rotation of the Doughnut + animateRotate: true, + //Boolean - Whether we animate scaling the Doughnut from the centre + animateScale: false + }, + aspectRatio: 1, + hover: { + mode: 'single' + }, + legendCallback: function(chart) { + var text = []; + text.push('
    '); + + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + + if (datasets.length) { + for (var i = 0; i < datasets[0].data.length; ++i) { + text.push('
  • '); + if (labels[i]) { + text.push(labels[i]); + } + text.push('
  • '); + } + } + + text.push('
'); + return text.join(""); + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var ds = data.datasets[0]; + var arc = meta.data[i]; + var custom = arc.custom || {}; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var arcOpts = chart.options.elements.arc; + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + + return { + text: label, + fillStyle: fill, + strokeStyle: stroke, + lineWidth: bw, + hidden: isNaN(ds.data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } else { + return []; + } + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + //The percentage of the chart that we cut out of the middle. + cutoutPercentage: 50, + + //The rotation of the chart, where the first data arc begins. + rotation: Math.PI * -0.5, + + //The total circumference of the chart. + circumference: Math.PI * 2.0, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index]; + } + } + } + }; + + defaults.pie = helpers.clone(defaults.doughnut); + helpers.extend(defaults.pie, { + cutoutPercentage: 0 + }); + + + Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Arc, + + linkScales: helpers.noop, + + // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly + getRingIndex: function getRingIndex(datasetIndex) { + var ringIndex = 0; + + for (var j = 0; j < datasetIndex; ++j) { + if (this.chart.isDatasetVisible(j)) { + ++ringIndex; + } + } + + return ringIndex; + }, + + update: function update(reset) { + var _this = this; + var chart = _this.chart, + chartArea = chart.chartArea, + opts = chart.options, + arcOpts = opts.elements.arc, + availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth, + availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth, + minSize = Math.min(availableWidth, availableHeight), + offset = { + x: 0, + y: 0 + }, + meta = _this.getMeta(), + cutoutPercentage = opts.cutoutPercentage, + circumference = opts.circumference; + + // If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc + if (circumference < Math.PI * 2.0) { + var startAngle = opts.rotation % (Math.PI * 2.0); + startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0); + var endAngle = startAngle + circumference; + var start = {x: Math.cos(startAngle), y: Math.sin(startAngle)}; + var end = {x: Math.cos(endAngle), y: Math.sin(endAngle)}; + var contains0 = (startAngle <= 0 && 0 <= endAngle) || (startAngle <= Math.PI * 2.0 && Math.PI * 2.0 <= endAngle); + var contains90 = (startAngle <= Math.PI * 0.5 && Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 2.5 && Math.PI * 2.5 <= endAngle); + var contains180 = (startAngle <= -Math.PI && -Math.PI <= endAngle) || (startAngle <= Math.PI && Math.PI <= endAngle); + var contains270 = (startAngle <= -Math.PI * 0.5 && -Math.PI * 0.5 <= endAngle) || (startAngle <= Math.PI * 1.5 && Math.PI * 1.5 <= endAngle); + var cutout = cutoutPercentage / 100.0; + var min = {x: contains180 ? -1 : Math.min(start.x * (start.x < 0 ? 1 : cutout), end.x * (end.x < 0 ? 1 : cutout)), y: contains270 ? -1 : Math.min(start.y * (start.y < 0 ? 1 : cutout), end.y * (end.y < 0 ? 1 : cutout))}; + var max = {x: contains0 ? 1 : Math.max(start.x * (start.x > 0 ? 1 : cutout), end.x * (end.x > 0 ? 1 : cutout)), y: contains90 ? 1 : Math.max(start.y * (start.y > 0 ? 1 : cutout), end.y * (end.y > 0 ? 1 : cutout))}; + var size = {width: (max.x - min.x) * 0.5, height: (max.y - min.y) * 0.5}; + minSize = Math.min(availableWidth / size.width, availableHeight / size.height); + offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5}; + } + + chart.outerRadius = Math.max(minSize / 2, 0); + chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + chart.offsetX = offset.x * chart.outerRadius; + chart.offsetY = offset.y * chart.outerRadius; + + meta.total = _this.calculateTotal(); + + _this.outerRadius = chart.outerRadius - (chart.radiusLength * _this.getRingIndex(_this.index)); + _this.innerRadius = _this.outerRadius - chart.radiusLength; + + helpers.each(meta.data, function(arc, index) { + _this.updateElement(arc, index, reset); + }); + }, + + updateElement: function(arc, index, reset) { + var _this = this; + var chart = _this.chart, + chartArea = chart.chartArea, + opts = chart.options, + animationOpts = opts.animation, + arcOpts = opts.elements.arc, + centerX = (chartArea.left + chartArea.right) / 2, + centerY = (chartArea.top + chartArea.bottom) / 2, + startAngle = opts.rotation, // non reset case handled later + endAngle = opts.rotation, // non reset case handled later + dataset = _this.getDataset(), + circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : _this.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)), + innerRadius = reset && animationOpts.animateScale ? 0 : _this.innerRadius, + outerRadius = reset && animationOpts.animateScale ? 0 : _this.outerRadius, + custom = arc.custom || {}, + valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + + helpers.extend(arc, { + // Utility + _datasetIndex: _this.index, + _index: index, + + // Desired view properties + _model: { + x: centerX + chart.offsetX, + y: centerY + chart.offsetY, + startAngle: startAngle, + endAngle: endAngle, + circumference: circumference, + outerRadius: outerRadius, + innerRadius: innerRadius, + label: valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index]) + } + }); + + var model = arc._model; + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor); + model.hoverBackgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, arcOpts.hoverBackgroundColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth); + model.borderColor = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor); + + // Set correct angles if not resetting + if (!reset || !animationOpts.animateRotate) { + if (index === 0) { + model.startAngle = opts.rotation; + } else { + model.startAngle = _this.getMeta().data[index - 1]._model.endAngle; + } + + model.endAngle = model.startAngle + model.circumference; + } + + arc.pivot(); + }, + + removeHoverStyle: function(arc) { + Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); + }, + + calculateTotal: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var total = 0; + var value; + + helpers.each(meta.data, function(element, index) { + value = dataset.data[index]; + if (!isNaN(value) && !element.hidden) { + total += Math.abs(value); + } + }); + + return total; + }, + + calculateCircumference: function(value) { + var total = this.getMeta().total; + if (total > 0 && !isNaN(value)) { + return (Math.PI * 2.0) * (value / total); + } else { + return 0; + } + } + }); +}; },{}],18:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.line = { - showLines: true, - - hover: { - mode: "label" - }, - - scales: { - xAxes: [{ - type: "category", - id: 'x-axis-0' - }], - yAxes: [{ - type: "linear", - id: 'y-axis-0' - }] - } - }; - - - Chart.controllers.line = Chart.DatasetController.extend({ - addElements: function() { - var meta = this.getMeta(); - meta.dataset = meta.dataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: meta.data - }); - - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - - // Make sure bezier control points are updated - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var line = meta.dataset; - var points = meta.data; - - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Update Line - if (this.chart.options.showLines) { - // Utility - line._scale = yScale; - line._datasetIndex = this.index; - // Data - line._children = points; - // Model - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined)) - { - this.getDataset().lineTension = this.getDataset().tension; - } - - line._model = { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - // Scale - scaleTop: yScale.top, - scaleBottom: yScale.bottom, - scaleZero: scaleBase - }; - line.pivot(); - } - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) - this.updateBezierControlPoints(); - }, - - getPointBackgroundColor: function(point, index) { - var backgroundColor = this.chart.options.elements.point.backgroundColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.backgroundColor) { - backgroundColor = point.custom.backgroundColor; - } else if (dataset.pointBackgroundColor) { - backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); - } else if (dataset.backgroundColor) { - backgroundColor = dataset.backgroundColor; - } - - return backgroundColor; - }, - getPointBorderColor: function(point, index) { - var borderColor = this.chart.options.elements.point.borderColor; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderColor) { - borderColor = point.custom.borderColor; - } else if (dataset.pointBorderColor) { - borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor); - } else if (dataset.borderColor) { - borderColor = dataset.borderColor; - } - - return borderColor; - }, - getPointBorderWidth: function(point, index) { - var borderWidth = this.chart.options.elements.point.borderWidth; - var dataset = this.getDataset(); - - if (point.custom && point.custom.borderWidth !== undefined) { - borderWidth = point.custom.borderWidth; - } else if (dataset.pointBorderWidth !== undefined) { - borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); - } else if (dataset.borderWidth !== undefined) { - borderWidth = dataset.borderWidth; - } - - return borderWidth; - }, - - updateElement: function(point, index, reset) { - var meta = this.getMeta(); - var yScale = this.getScaleForId(meta.yAxisID); - var xScale = this.getScaleForId(meta.xAxisID); - var scaleBase; - - if (yScale.min < 0 && yScale.max < 0) { - scaleBase = yScale.getPixelForValue(yScale.max); - } else if (yScale.min > 0 && yScale.max > 0) { - scaleBase = yScale.getPixelForValue(yScale.min); - } else { - scaleBase = yScale.getPixelForValue(0); - } - - // Utility - point._chart = this.chart.chart; - point._xScale = xScale; - point._yScale = yScale; - point._datasetIndex = this.index; - point._index = index; - - // Desired view properties - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined)) - { - this.getDataset().pointRadius = this.getDataset().radius; - } - if ((this.getDataset().hitRadius !== undefined) && (this.getDataset().pointHitRadius === undefined)) - { - this.getDataset().pointHitRadius = this.getDataset().hitRadius; - } - - point._model = { - x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo), - // Appearance - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - backgroundColor: this.getPointBackgroundColor(point, index), - borderColor: this.getPointBorderColor(point, index), - borderWidth: this.getPointBorderWidth(point, index), - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointHitRadius, index, this.chart.options.elements.point.hitRadius) - }; - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - - calculatePointY: function(value, index, datasetIndex, isCombo) { - var meta = this.getMeta(); - var xScale = this.getScaleForId(meta.xAxisID); - var yScale = this.getScaleForId(meta.yAxisID); - - if (yScale.options.stacked) { - - var sumPos = 0, - sumNeg = 0; - - for (var i = 0; i < datasetIndex; i++) { - var ds = this.chart.data.datasets[i]; - var dsMeta = this.chart.getDatasetMeta(i); - if (dsMeta.type === 'line' && this.chart.isDatasetVisible(i)) { - if (ds.data[index] < 0) { - sumNeg += ds.data[index] || 0; - } else { - sumPos += ds.data[index] || 0; - } - } - } - - if (value < 0) { - return yScale.getPixelForValue(sumNeg + value); - } else { - return yScale.getPixelForValue(sumPos + value); - } - } - - return yScale.getPixelForValue(value); - }, - - updateBezierControlPoints: function() { - // Update bezier control points - var meta = this.getMeta(); - helpers.each(meta.data, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(meta.data, index)._model, - point._model, - helpers.nextItem(meta.data, index)._model, - meta.dataset._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var meta = this.getMeta(); - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(meta.data, function(point) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - if (this.chart.options.showLines) - meta.dataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(meta.data, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined)) - { - this.getDataset().pointRadius = this.getDataset().radius; - } - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = this.getPointBackgroundColor(point, index); - point._model.borderColor = this.getPointBorderColor(point, index); - point._model.borderWidth = this.getPointBorderWidth(point, index); - } - }); -}; +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.line = { + showLines: true, + + hover: { + mode: "label" + }, + + scales: { + xAxes: [{ + type: "category", + id: 'x-axis-0' + }], + yAxes: [{ + type: "linear", + id: 'y-axis-0' + }] + } + }; + + Chart.controllers.line = Chart.DatasetController.extend({ + + datasetElementType: Chart.elements.Line, + + dataElementType: Chart.elements.Point, + + addElementAndReset: function(index) { + var me = this; + var options = me.chart.options; + + Chart.DatasetController.prototype.addElementAndReset.call(me, index); + + // Make sure bezier control points are updated + if (options.showLines && options.elements.line.tension !== 0) { + me.updateBezierControlPoints(); + } + }, + + update: function update(reset) { + var me = this; + var meta = me.getMeta(); + var line = meta.dataset; + var points = meta.data || []; + var options = me.chart.options; + var lineElementOptions = options.elements.line; + var scale = me.getScaleForId(meta.yAxisID); + var i, ilen, dataset, custom; + + // Update Line + if (options.showLines) { + dataset = me.getDataset(); + custom = line.custom || {}; + + // Compatibility: If the properties are defined with only the old name, use those values + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { + dataset.lineTension = dataset.tension; + } + + // Utility + line._scale = scale; + line._datasetIndex = me.index; + // Data + line._children = points; + // Model + line._model = { + // Appearance + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), + // Scale + scaleTop: scale.top, + scaleBottom: scale.bottom, + scaleZero: scale.getBasePixel() + }; + + line.pivot(); + } + + // Update Points + for (i=0, ilen=points.length; i'); - - if (chart.data.datasets.length) { - for (var i = 0; i < chart.data.datasets[0].data.length; ++i) { - text.push('
  • '); - if (chart.data.labels[i]) { - text.push(chart.data.labels[i]); - } - text.push('
  • '); - } - } - - text.push(''); - return text.join(""); - }, - legend: { - labels: { - generateLabels: function(chart) { - var data = chart.data; - if (data.labels.length && data.datasets.length) { - return data.labels.map(function(label, i) { - var meta = chart.getDatasetMeta(0); - var ds = data.datasets[0]; - var arc = meta.data[i]; - var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor); - var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor); - var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth); - - return { - text: label, - fillStyle: fill, - strokeStyle: stroke, - lineWidth: bw, - hidden: isNaN(ds.data[i]) || meta.data[i].hidden, - - // Extra data used for toggling the correct item - index: i - }; - }, this); - } else { - return []; - } - } - }, - - onClick: function(e, legendItem) { - var index = legendItem.index; - var chart = this.chart; - var i, ilen, meta; - - for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { - meta = chart.getDatasetMeta(i); - meta.data[index].hidden = !meta.data[index].hidden; - } - - chart.update(); - } - }, - - // Need to override these to give a nice default - tooltips: { - callbacks: { - title: function() { - return ''; - }, - label: function(tooltipItem, data) { - return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel; - } - } - } - }; - - Chart.controllers.polarArea = Chart.DatasetController.extend({ - linkScales: function() { - // no scales for doughnut - }, - - addElements: function() { - var meta = this.getMeta(); - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - }, this); - }, - - addElementAndReset: function(index) { - var arc = new Chart.elements.Arc({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, arc); - this.updateElement(arc, index, true); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top); - this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0); - this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); - this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount(); - - this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); - this.innerRadius = this.outerRadius - this.chart.radiusLength; - - meta.count = this.countVisibleElements(); - - helpers.each(meta.data, function(arc, index) { - this.updateElement(arc, index, reset); - }, this); - }, - - updateElement: function(arc, index, reset) { - var circumference = this.calculateCircumference(this.getDataset().data[index]); - var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2; - var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2; - - // If there is NaN data before us, we need to calculate the starting angle correctly. - // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data - var visibleCount = 0; - var meta = this.getMeta(); - for (var i = 0; i < index; ++i) { - if (!isNaN(this.getDataset().data[i]) && !meta.data[i].hidden) { - ++visibleCount; - } - } - - var distance = arc.hidden? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]); - var startAngle = (-0.5 * Math.PI) + (circumference * visibleCount); - var endAngle = startAngle + (arc.hidden? 0 : circumference); - - var resetModel = { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: this.chart.options.animation.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]), - startAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : startAngle, - endAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - }; - - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: reset ? resetModel : { - x: centerX, - y: centerY, - innerRadius: 0, - outerRadius: distance, - startAngle: startAngle, - endAngle: endAngle, - - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) - } - }); - - arc.pivot(); - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - helpers.each(this.getMeta().data, function(arc, index) { - arc.transition(easingDecimal).draw(); - }); - }, - - setHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth); - }, - - removeHoverStyle: function(arc) { - var dataset = this.chart.data.datasets[arc._datasetIndex]; - var index = arc._index; - - arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); - arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); - arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); - }, - - countVisibleElements: function() { - var dataset = this.getDataset(); - var meta = this.getMeta(); - var count = 0; - - helpers.each(meta.data, function(element, index) { - if (!isNaN(dataset.data[index]) && !element.hidden) { - count++; - } - }); - - return count; - }, - - calculateCircumference: function(value) { - var count = this.getMeta().count; - if (count > 0 && !isNaN(value)) { - return (2 * Math.PI) / count; - } else { - return 0; - } - } - }); -}; +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.polarArea = { + + scale: { + type: "radialLinear", + lineArc: true // so that lines are circular + }, + + //Boolean - Whether to animate the rotation of the chart + animation: { + animateRotate: true, + animateScale: true + }, + + aspectRatio: 1, + legendCallback: function(chart) { + var text = []; + text.push('
      '); + + var data = chart.data; + var datasets = data.datasets; + var labels = data.labels; + + if (datasets.length) { + for (var i = 0; i < datasets[0].data.length; ++i) { + text.push('
    • '); + if (labels[i]) { + text.push(labels[i]); + } + text.push('
    • '); + } + } + + text.push('
    '); + return text.join(""); + }, + legend: { + labels: { + generateLabels: function(chart) { + var data = chart.data; + if (data.labels.length && data.datasets.length) { + return data.labels.map(function(label, i) { + var meta = chart.getDatasetMeta(0); + var ds = data.datasets[0]; + var arc = meta.data[i]; + var custom = arc.custom || {}; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var arcOpts = chart.options.elements.arc; + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + + return { + text: label, + fillStyle: fill, + strokeStyle: stroke, + lineWidth: bw, + hidden: isNaN(ds.data[i]) || meta.data[i].hidden, + + // Extra data used for toggling the correct item + index: i + }; + }); + } else { + return []; + } + } + }, + + onClick: function(e, legendItem) { + var index = legendItem.index; + var chart = this.chart; + var i, ilen, meta; + + for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) { + meta = chart.getDatasetMeta(i); + meta.data[index].hidden = !meta.data[index].hidden; + } + + chart.update(); + } + }, + + // Need to override these to give a nice default + tooltips: { + callbacks: { + title: function() { + return ''; + }, + label: function(tooltipItem, data) { + return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel; + } + } + } + }; + + Chart.controllers.polarArea = Chart.DatasetController.extend({ + + dataElementType: Chart.elements.Arc, + + linkScales: helpers.noop, + + update: function update(reset) { + var _this = this; + var chart = _this.chart; + var chartArea = chart.chartArea; + var meta = this.getMeta(); + var opts = chart.options; + var arcOpts = opts.elements.arc; + var minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top); + chart.outerRadius = Math.max((minSize - arcOpts.borderWidth / 2) / 2, 0); + chart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0); + chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount(); + + _this.outerRadius = chart.outerRadius - (chart.radiusLength * _this.index); + _this.innerRadius = _this.outerRadius - chart.radiusLength; + + meta.count = _this.countVisibleElements(); + + helpers.each(meta.data, function(arc, index) { + _this.updateElement(arc, index, reset); + }); + }, + + updateElement: function(arc, index, reset) { + var _this = this; + var chart = _this.chart; + var chartArea = chart.chartArea; + var dataset = _this.getDataset(); + var opts = chart.options; + var animationOpts = opts.animation; + var arcOpts = opts.elements.arc; + var custom = arc.custom || {}; + var scale = chart.scale; + var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; + var labels = chart.data.labels; + + var circumference = _this.calculateCircumference(dataset.data[index]); + var centerX = (chartArea.left + chartArea.right) / 2; + var centerY = (chartArea.top + chartArea.bottom) / 2; + + // If there is NaN data before us, we need to calculate the starting angle correctly. + // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data + var visibleCount = 0; + var meta = _this.getMeta(); + for (var i = 0; i < index; ++i) { + if (!isNaN(dataset.data[i]) && !meta.data[i].hidden) { + ++visibleCount; + } + } + + var distance = arc.hidden? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]); + var startAngle = (-0.5 * Math.PI) + (circumference * visibleCount); + var endAngle = startAngle + (arc.hidden? 0 : circumference); + + var resetModel = { + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius: animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]), + startAngle: animationOpts.animateRotate ? Math.PI * -0.5 : startAngle, + endAngle: animationOpts.animateRotate ? Math.PI * -0.5 : endAngle, + + backgroundColor: custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), + + label: getValueAtIndexOrDefault(labels, index, labels[index]) + }; + + helpers.extend(arc, { + // Utility + _datasetIndex: _this.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: reset ? resetModel : { + x: centerX, + y: centerY, + innerRadius: 0, + outerRadius: distance, + startAngle: startAngle, + endAngle: endAngle, + + backgroundColor: custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), + + label: getValueAtIndexOrDefault(labels, index, labels[index]) + } + }); + + arc.pivot(); + }, + + removeHoverStyle: function(arc) { + Chart.DatasetController.prototype.removeHoverStyle.call(this, arc, this.chart.options.elements.arc); + }, + + countVisibleElements: function() { + var dataset = this.getDataset(); + var meta = this.getMeta(); + var count = 0; + + helpers.each(meta.data, function(element, index) { + if (!isNaN(dataset.data[index]) && !element.hidden) { + count++; + } + }); + + return count; + }, + + calculateCircumference: function(value) { + var count = this.getMeta().count; + if (count > 0 && !isNaN(value)) { + return (2 * Math.PI) / count; + } else { + return 0; + } + } + }); +}; },{}],20:[function(require,module,exports){ -"use strict"; +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.radar = { + scale: { + type: "radialLinear" + }, + elements: { + line: { + tension: 0 // no bezier in radar + } + } + }; + + Chart.controllers.radar = Chart.DatasetController.extend({ + + datasetElementType: Chart.elements.Line, + + dataElementType: Chart.elements.Point, + + linkScales: helpers.noop, + + addElementAndReset: function(index) { + Chart.DatasetController.prototype.addElementAndReset.call(this, index); + + // Make sure bezier control points are updated + this.updateBezierControlPoints(); + }, + + update: function update(reset) { + var meta = this.getMeta(); + var line = meta.dataset; + var points = meta.data; + var custom = line.custom || {}; + var dataset = this.getDataset(); + var lineElementOptions = this.chart.options.elements.line; + var scale = this.chart.scale; + + // Compatibility: If the properties are defined with only the old name, use those values + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { + dataset.lineTension = dataset.tension; + } + + helpers.extend(meta.dataset, { + // Utility + _datasetIndex: this.index, + // Data + _children: points, + _loop: true, + // Model + _model: { + // Appearance + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), + + // Scale + scaleTop: scale.top, + scaleBottom: scale.bottom, + scaleZero: scale.getBasePosition() + } + }); + + meta.dataset.pivot(); + + // Update Points + helpers.each(points, function(point, index) { + this.updateElement(point, index, reset); + }, this); + + + // Update bezier control points + this.updateBezierControlPoints(); + }, + updateElement: function(point, index, reset) { + var custom = point.custom || {}; + var dataset = this.getDataset(); + var scale = this.chart.scale; + var pointElementOptions = this.chart.options.elements.point; + var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); + + helpers.extend(point, { + // Utility + _datasetIndex: this.index, + _index: index, + _scale: scale, + + // Desired view properties + _model: { + x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales + y: reset ? scale.yCenter : pointPosition.y, + + // Appearance + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, this.chart.options.elements.line.tension), + radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor), + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth), + pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle), + + // Tooltip + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) + } + }); + + point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); + }, + updateBezierControlPoints: function() { + var chartArea = this.chart.chartArea; + var meta = this.getMeta(); + + helpers.each(meta.data, function(point, index) { + var model = point._model; + var controlPoints = helpers.splineCurve( + helpers.previousItem(meta.data, index, true)._model, + model, + helpers.nextItem(meta.data, index, true)._model, + model.tension + ); + + // Prevent the bezier going outside of the bounds of the graph + model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left); + model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top); + + model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left); + model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top); + + // Now pivot the point for animation + point.pivot(); + }, this); + }, + + draw: function(ease) { + var meta = this.getMeta(); + var easingDecimal = ease || 1; + + // Transition Point Locations + helpers.each(meta.data, function(point, index) { + point.transition(easingDecimal); + }); + + // Transition and Draw the line + meta.dataset.transition(easingDecimal).draw(); + + // Draw the points + helpers.each(meta.data, function(point) { + point.draw(); + }); + }, + + setHoverStyle: function(point) { + // Point + var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; + var index = point._index; + var model = point._model; + + model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); + }, + + removeHoverStyle: function(point) { + var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; + var index = point._index; + var model = point._model; + var pointElementOptions = this.chart.options.elements.point; + + model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth); + } + }); +}; -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - - Chart.defaults.radar = { - scale: { - type: "radialLinear" - }, - elements: { - line: { - tension: 0 // no bezier in radar - } - } - }; - - Chart.controllers.radar = Chart.DatasetController.extend({ - linkScales: function() { - // No need. Single scale only - }, - - addElements: function() { - var meta = this.getMeta(); - - meta.dataset = meta.dataset || new Chart.elements.Line({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _points: meta.data, - _loop: true - }); - - helpers.each(this.getDataset().data, function(value, index) { - meta.data[index] = meta.data[index] || new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, - _model: { - x: 0, //xScale.getPixelForValue(null, index, true), - y: 0 //this.chartArea.bottom, - } - }); - }, this); - }, - addElementAndReset: function(index) { - var point = new Chart.elements.Point({ - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index - }); - - // Add to the points array and reset it - this.getMeta().data.splice(index, 0, point); - this.updateElement(point, index, true); - - // Make sure bezier control points are updated - this.updateBezierControlPoints(); - }, - - update: function update(reset) { - var meta = this.getMeta(); - var line = meta.dataset; - var points = meta.data; - - var scale = this.chart.scale; - var scaleBase; - - if (scale.min < 0 && scale.max < 0) { - scaleBase = scale.getPointPositionForValue(0, scale.max); - } else if (scale.min > 0 && scale.max > 0) { - scaleBase = scale.getPointPositionForValue(0, scale.min); - } else { - scaleBase = scale.getPointPositionForValue(0, 0); - } - - // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined)) - { - this.getDataset().lineTension = this.getDataset().tension; - } - - helpers.extend(meta.dataset, { - // Utility - _datasetIndex: this.index, - // Data - _children: points, - // Model - _model: { - // Appearance - tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension), - backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor), - borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth), - borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), - borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), - borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), - borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), - - // Scale - scaleTop: scale.top, - scaleBottom: scale.bottom, - scaleZero: scaleBase - } - }); - - meta.dataset.pivot(); - - // Update Points - helpers.each(points, function(point, index) { - this.updateElement(point, index, reset); - }, this); - - - // Update bezier control points - this.updateBezierControlPoints(); - }, - updateElement: function(point, index, reset) { - var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]); - - helpers.extend(point, { - // Utility - _datasetIndex: this.index, - _index: index, - _scale: this.chart.scale, - - // Desired view properties - _model: { - x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales - y: reset ? this.chart.scale.yCenter : pointPosition.y, - - // Appearance - tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension), - radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), - - // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) - } - }); - - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); - }, - updateBezierControlPoints: function() { - var meta = this.getMeta(); - helpers.each(meta.data, function(point, index) { - var controlPoints = helpers.splineCurve( - helpers.previousItem(meta.data, index, true)._model, - point._model, - helpers.nextItem(meta.data, index, true)._model, - point._model.tension - ); - - // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); - - // Now pivot the point for animation - point.pivot(); - }, this); - }, - - draw: function(ease) { - var meta = this.getMeta(); - var easingDecimal = ease || 1; - - // Transition Point Locations - helpers.each(meta.data, function(point, index) { - point.transition(easingDecimal); - }); - - // Transition and Draw the line - meta.dataset.transition(easingDecimal).draw(); - - // Draw the points - helpers.each(meta.data, function(point) { - point.draw(); - }); - }, - - setHoverStyle: function(point) { - // Point - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); - }, - - removeHoverStyle: function(point) { - var dataset = this.chart.data.datasets[point._datasetIndex]; - var index = point._index; - - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth); - } - }); -}; },{}],21:[function(require,module,exports){ -/*global window: false */ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - - Chart.defaults.global.animation = { - duration: 1000, - easing: "easeOutQuart", - onProgress: helpers.noop, - onComplete: helpers.noop - }; - - Chart.Animation = Chart.Element.extend({ - currentStep: null, // the current animation step - numSteps: 60, // default number of steps - easing: "", // the easing to use for this animation - render: null, // render function used by the animation service - - onAnimationProgress: null, // user specified callback to fire on each step of the animation - onAnimationComplete: null // user specified callback to fire when the animation finishes - }); - - Chart.animationService = { - frameDuration: 17, - animations: [], - dropFrames: 0, - request: null, - addAnimation: function(chartInstance, animationObject, duration, lazy) { - - if (!lazy) { - chartInstance.animating = true; - } - - for (var index = 0; index < this.animations.length; ++index) { - if (this.animations[index].chartInstance === chartInstance) { - // replacing an in progress animation - this.animations[index].animationObject = animationObject; - return; - } - } - - this.animations.push({ - chartInstance: chartInstance, - animationObject: animationObject - }); - - // If there are no animations queued, manually kickstart a digest, for lack of a better word - if (this.animations.length === 1) { - this.requestAnimationFrame(); - } - }, - // Cancel the animation for a given chart instance - cancelAnimation: function(chartInstance) { - var index = helpers.findIndex(this.animations, function(animationWrapper) { - return animationWrapper.chartInstance === chartInstance; - }); - - if (index !== -1) { - this.animations.splice(index, 1); - chartInstance.animating = false; - } - }, - requestAnimationFrame: function() { - var me = this; - if (me.request === null) { - // Skip animation frame requests until the active one is executed. - // This can happen when processing mouse events, e.g. 'mousemove' - // and 'mouseout' events will trigger multiple renders. - me.request = helpers.requestAnimFrame.call(window, function() { - me.request = null; - me.startDigest(); - }); - } - }, - startDigest: function() { - - var startTime = Date.now(); - var framesToDrop = 0; - - if (this.dropFrames > 1) { - framesToDrop = Math.floor(this.dropFrames); - this.dropFrames = this.dropFrames % 1; - } - - var i = 0; - while (i < this.animations.length) { - if (this.animations[i].animationObject.currentStep === null) { - this.animations[i].animationObject.currentStep = 0; - } - - this.animations[i].animationObject.currentStep += 1 + framesToDrop; - - if (this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps) { - this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps; - } - - this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject); - if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) { - this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]); - } - - if (this.animations[i].animationObject.currentStep === this.animations[i].animationObject.numSteps) { - if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) { - this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]); - } - - // executed the last frame. Remove the animation. - this.animations[i].chartInstance.animating = false; - - this.animations.splice(i, 1); - } else { - ++i; - } - } - - var endTime = Date.now(); - var dropFrames = (endTime - startTime) / this.frameDuration; - - this.dropFrames += dropFrames; - - // Do we have more stuff to animate? - if (this.animations.length > 0) { - this.requestAnimationFrame(); - } - } - }; +/*global window: false */ +"use strict"; + +module.exports = function(Chart) { + + var helpers = Chart.helpers; + + Chart.defaults.global.animation = { + duration: 1000, + easing: "easeOutQuart", + onProgress: helpers.noop, + onComplete: helpers.noop + }; + + Chart.Animation = Chart.Element.extend({ + currentStep: null, // the current animation step + numSteps: 60, // default number of steps + easing: "", // the easing to use for this animation + render: null, // render function used by the animation service + + onAnimationProgress: null, // user specified callback to fire on each step of the animation + onAnimationComplete: null // user specified callback to fire when the animation finishes + }); + + Chart.animationService = { + frameDuration: 17, + animations: [], + dropFrames: 0, + request: null, + addAnimation: function(chartInstance, animationObject, duration, lazy) { + + if (!lazy) { + chartInstance.animating = true; + } + + for (var index = 0; index < this.animations.length; ++index) { + if (this.animations[index].chartInstance === chartInstance) { + // replacing an in progress animation + this.animations[index].animationObject = animationObject; + return; + } + } + + this.animations.push({ + chartInstance: chartInstance, + animationObject: animationObject + }); + + // If there are no animations queued, manually kickstart a digest, for lack of a better word + if (this.animations.length === 1) { + this.requestAnimationFrame(); + } + }, + // Cancel the animation for a given chart instance + cancelAnimation: function(chartInstance) { + var index = helpers.findIndex(this.animations, function(animationWrapper) { + return animationWrapper.chartInstance === chartInstance; + }); + + if (index !== -1) { + this.animations.splice(index, 1); + chartInstance.animating = false; + } + }, + requestAnimationFrame: function() { + var me = this; + if (me.request === null) { + // Skip animation frame requests until the active one is executed. + // This can happen when processing mouse events, e.g. 'mousemove' + // and 'mouseout' events will trigger multiple renders. + me.request = helpers.requestAnimFrame.call(window, function() { + me.request = null; + me.startDigest(); + }); + } + }, + startDigest: function() { + + var startTime = Date.now(); + var framesToDrop = 0; + + if (this.dropFrames > 1) { + framesToDrop = Math.floor(this.dropFrames); + this.dropFrames = this.dropFrames % 1; + } + + var i = 0; + while (i < this.animations.length) { + if (this.animations[i].animationObject.currentStep === null) { + this.animations[i].animationObject.currentStep = 0; + } + + this.animations[i].animationObject.currentStep += 1 + framesToDrop; + + if (this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps) { + this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps; + } + + this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject); + if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) { + this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]); + } + + if (this.animations[i].animationObject.currentStep === this.animations[i].animationObject.numSteps) { + if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) { + this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]); + } + + // executed the last frame. Remove the animation. + this.animations[i].chartInstance.animating = false; + + this.animations.splice(i, 1); + } else { + ++i; + } + } + + var endTime = Date.now(); + var dropFrames = (endTime - startTime) / this.frameDuration; + + this.dropFrames += dropFrames; + + // Do we have more stuff to animate? + if (this.animations.length > 0) { + this.requestAnimationFrame(); + } + } + }; }; },{}],22:[function(require,module,exports){ -"use strict"; - -module.exports = function(Chart) { - - var helpers = Chart.helpers; - //Create a dictionary of chart types, to allow for extension of existing types - Chart.types = {}; - - //Store a reference to each instance - allowing us to globally resize chart instances on window resize. - //Destroy method on the chart will remove the instance of the chart from this reference. - Chart.instances = {}; - - // Controllers available for dataset visualization eg. bar, line, slice, etc. - Chart.controllers = {}; - - // The main controller of a chart - Chart.Controller = function(instance) { - - this.chart = instance; - this.config = instance.config; - this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {}); - this.id = helpers.uid(); - - Object.defineProperty(this, 'data', { - get: function() { - return this.config.data; - } - }); - - //Add the chart instance to the global namespace - Chart.instances[this.id] = this; - - if (this.options.responsive) { - // Silent resize before chart draws - this.resize(true); - } - - this.initialize(); - - return this; - }; - - helpers.extend(Chart.Controller.prototype, { - - initialize: function initialize() { - // Before init plugin notification - Chart.pluginService.notifyPlugins('beforeInit', [this]); - - this.bindEvents(); - - // Make sure controllers are built first so that each dataset is bound to an axis before the scales - // are built - this.ensureScalesHaveIDs(); - this.buildOrUpdateControllers(); - this.buildScales(); - this.buildSurroundingItems(); - this.updateLayout(); - this.resetElements(); - this.initToolTip(); - this.update(); - - // After init plugin notification - Chart.pluginService.notifyPlugins('afterInit', [this]); - - return this; - }, - - clear: function clear() { - helpers.clear(this.chart); - return this; - }, - - stop: function stop() { - // Stops any current animation loop occuring - Chart.animationService.cancelAnimation(this); - return this; - }, - - resize: function resize(silent) { - var canvas = this.chart.canvas; - var newWidth = helpers.getMaximumWidth(this.chart.canvas); - var newHeight = (this.options.maintainAspectRatio && isNaN(this.chart.aspectRatio) === false && isFinite(this.chart.aspectRatio) && this.chart.aspectRatio !== 0) ? newWidth / this.chart.aspectRatio : helpers.getMaximumHeight(this.chart.canvas); - - var sizeChanged = this.chart.width !== newWidth || this.chart.height !== newHeight; - - if (!sizeChanged) - return this; - - canvas.width = this.chart.width = newWidth; - canvas.height = this.chart.height = newHeight; - - helpers.retinaScale(this.chart); - - if (!silent) { - this.stop(); - this.update(this.options.responsiveAnimationDuration); - } - - return this; - }, - ensureScalesHaveIDs: function ensureScalesHaveIDs() { - var defaultXAxisID = 'x-axis-'; - var defaultYAxisID = 'y-axis-'; - - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - xAxisOptions.id = xAxisOptions.id || (defaultXAxisID + index); - }); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - yAxisOptions.id = yAxisOptions.id || (defaultYAxisID + index); - }); - } - } - }, - buildScales: function buildScales() { - // Map of scale ID to scale object so we can lookup later - this.scales = {}; - - // Build the x axes - if (this.options.scales) { - if (this.options.scales.xAxes && this.options.scales.xAxes.length) { - helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) { - var xType = helpers.getValueOrDefault(xAxisOptions.type, 'category'); - var ScaleClass = Chart.scaleService.getScaleConstructor(xType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: xAxisOptions, - chart: this, - id: xAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - - if (this.options.scales.yAxes && this.options.scales.yAxes.length) { - // Build the y axes - helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) { - var yType = helpers.getValueOrDefault(yAxisOptions.type, 'linear'); - var ScaleClass = Chart.scaleService.getScaleConstructor(yType); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: yAxisOptions, - chart: this, - id: yAxisOptions.id - }); - - this.scales[scale.id] = scale; - } - }, this); - } - } - if (this.options.scale) { - // Build radial axes - var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type); - if (ScaleClass) { - var scale = new ScaleClass({ - ctx: this.chart.ctx, - options: this.options.scale, - chart: this - }); - - this.scale = scale; - - this.scales.radialScale = scale; - } - } - - Chart.scaleService.addScalesToLayout(this); - }, - - buildSurroundingItems: function() { - if (this.options.title) { - this.titleBlock = new Chart.Title({ - ctx: this.chart.ctx, - options: this.options.title, - chart: this - }); - - Chart.layoutService.addBox(this, this.titleBlock); - } - - if (this.options.legend) { - this.legend = new Chart.Legend({ - ctx: this.chart.ctx, - options: this.options.legend, - chart: this - }); - - Chart.layoutService.addBox(this, this.legend); - } - }, - - updateLayout: function() { - Chart.layoutService.update(this, this.chart.width, this.chart.height); - }, - - buildOrUpdateControllers: function buildOrUpdateControllers() { - var types = []; - var newControllers = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - var meta = this.getDatasetMeta(datasetIndex); - if (!meta.type) { - meta.type = dataset.type || this.config.type; - } - - types.push(meta.type); - - if (meta.controller) { - meta.controller.updateIndex(datasetIndex); - } else { - meta.controller = new Chart.controllers[meta.type](this, datasetIndex); - newControllers.push(meta.controller); - } - }, this); - - if (types.length > 1) { - for (var i = 1; i < types.length; i++) { - if (types[i] !== types[i - 1]) { - this.isCombo = true; - break; - } - } - } - - return newControllers; - }, - - resetElements: function resetElements() { - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.reset(); - }, this); - }, - - update: function update(animationDuration, lazy) { - Chart.pluginService.notifyPlugins('beforeUpdate', [this]); - - // In case the entire data object changed - this.tooltip._data = this.data; - - // Make sure dataset controllers are updated and new controllers are reset - var newControllers = this.buildOrUpdateControllers(); - - // Make sure all dataset controllers have correct meta data counts - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements(); - }, this); - - Chart.layoutService.update(this, this.chart.width, this.chart.height); - - // Can only reset the new controllers after the scales have been updated - helpers.each(newControllers, function(controller) { - controller.reset(); - }); - - // This will loop through any data and do the appropriate element update for the type - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - this.getDatasetMeta(datasetIndex).controller.update(); - }, this); - - this.render(animationDuration, lazy); - - Chart.pluginService.notifyPlugins('afterUpdate', [this]); - }, - - render: function render(duration, lazy) { - Chart.pluginService.notifyPlugins('beforeRender', [this]); - - if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) { - var animation = new Chart.Animation(); - animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps - animation.easing = this.options.animation.easing; - - // render function - animation.render = function(chartInstance, animationObject) { - var easingFunction = helpers.easingEffects[animationObject.easing]; - var stepDecimal = animationObject.currentStep / animationObject.numSteps; - var easeDecimal = easingFunction(stepDecimal); - - chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep); - }; - - // user events - animation.onAnimationProgress = this.options.animation.onProgress; - animation.onAnimationComplete = this.options.animation.onComplete; - - Chart.animationService.addAnimation(this, animation, duration, lazy); - } else { - this.draw(); - if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) { - this.options.animation.onComplete.call(this); - } - } - return this; - }, - - draw: function(ease) { - var easingDecimal = ease || 1; - this.clear(); - - Chart.pluginService.notifyPlugins('beforeDraw', [this, easingDecimal]); - - // Draw all the scales - helpers.each(this.boxes, function(box) { - box.draw(this.chartArea); - }, this); - if (this.scale) { - this.scale.draw(); - } - - // Clip out the chart area so that anything outside does not draw. This is necessary for zoom and pan to function - this.chart.ctx.save(); - this.chart.ctx.beginPath(); - this.chart.ctx.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top); - this.chart.ctx.clip(); - - // Draw each dataset via its respective controller (reversed to support proper line stacking) - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - this.getDatasetMeta(datasetIndex).controller.draw(ease); - } - }, this, true); - - // Restore from the clipping operation - this.chart.ctx.restore(); - - // Finally draw the tooltip - this.tooltip.transition(easingDecimal).draw(); - - Chart.pluginService.notifyPlugins('afterDraw', [this, easingDecimal]); - }, - - // Get the single element that was clicked on - // @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw - getElementAtEvent: function(e) { - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - var meta = this.getDatasetMeta(datasetIndex); - helpers.each(meta.data, function(element, index) { - if (element.inRange(eventPosition.x, eventPosition.y)) { - elementsArray.push(element); - return elementsArray; - } - }); - } - }, this); - - return elementsArray; - }, - - getElementsAtEvent: function(e) { - var eventPosition = helpers.getRelativePosition(e, this.chart); - var elementsArray = []; - - var found = (function() { - if (this.data.datasets) { - for (var i = 0; i < this.data.datasets.length; i++) { - var meta = this.getDatasetMeta(i); - if (this.isDatasetVisible(i)) { - for (var j = 0; j < meta.data.length; j++) { - if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) { - return meta.data[j]; - } - } - } - } - } - }).call(this); - - if (!found) { - return elementsArray; - } - - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - if (this.isDatasetVisible(datasetIndex)) { - var meta = this.getDatasetMeta(datasetIndex); - elementsArray.push(meta.data[found._index]); - } - }, this); - - return elementsArray; - }, - - getDatasetAtEvent: function(e) { - var elementsArray = this.getElementAtEvent(e); - - if (elementsArray.length > 0) { - elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data; - } - - return elementsArray; - }, - - getDatasetMeta: function(datasetIndex) { - var dataset = this.data.datasets[datasetIndex]; - if (!dataset._meta) { - dataset._meta = {}; - } - - var meta = dataset._meta[this.id]; - if (!meta) { - meta = dataset._meta[this.id] = { - type: null, - data: [], - dataset: null, - controller: null, - hidden: null, // See isDatasetVisible() comment - xAxisID: null, - yAxisID: null - }; - } - - return meta; - }, - - getVisibleDatasetCount: function() { - var count = 0; - for (var i = 0, ilen = this.data.datasets.length; i