├── codecov.yml ├── LICENSE ├── .gitignore ├── data ├── skills.rda └── skillsByName.rda ├── tests ├── testthat.R └── testthat │ ├── test-runExampleApp.R │ ├── test-setRadarScale.R │ ├── test-colourMatrix.R │ └── test-chartJSRadar.R ├── inst ├── figs │ ├── readmePlot01.jpg │ ├── readmePlot02.jpg │ └── readmePlot03.jpg ├── htmlwidgets │ ├── chartJSRadar.yaml │ ├── lib │ │ └── chart.js │ │ │ ├── .bower.json │ │ │ ├── LICENSE.md │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ └── dist │ │ │ └── Chart.min.js │ └── chartJSRadar.js ├── shiny-examples │ ├── basic │ │ ├── server.R │ │ └── ui.R │ └── options │ │ ├── ui.R │ │ └── server.R ├── minimal.html └── test.html ├── .Rbuildignore ├── .travis.yml ├── NAMESPACE ├── man ├── chartJSRadarOutput.Rd ├── colourMatrix.Rd ├── renderChartJSRadar.Rd ├── skills.Rd ├── runExampleApp.Rd ├── chartJSRadar_html.Rd ├── setRadarScale.Rd ├── skillsByName.Rd └── chartJSRadar.Rd ├── cran-comments.md ├── NEWS.md ├── appveyor.yml ├── R ├── data.R ├── colourMatrix.R ├── runExample.R └── chartJSRadar.R ├── DESCRIPTION ├── vignettes └── preparingData.Rmd └── README.md /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2013-2016 2 | COPYRIGHT HOLDER: Mango Solutions, Nick Downie 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | inst/doc 5 | radarchart.Rproj 6 | -------------------------------------------------------------------------------- /data/skills.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/radarchart/master/data/skills.rda -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(radarchart) 3 | 4 | test_check("radarchart") 5 | -------------------------------------------------------------------------------- /data/skillsByName.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/radarchart/master/data/skillsByName.rda -------------------------------------------------------------------------------- /inst/figs/readmePlot01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/radarchart/master/inst/figs/readmePlot01.jpg -------------------------------------------------------------------------------- /inst/figs/readmePlot02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/radarchart/master/inst/figs/readmePlot02.jpg -------------------------------------------------------------------------------- /inst/figs/readmePlot03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MangoTheCat/radarchart/master/inst/figs/readmePlot03.jpg -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | \.travis\.yml$ 4 | \.bower\.json$ 5 | \.bowerrc$ 6 | ^appveyor\.yml$ 7 | ^cran-comments\.md$ 8 | ^codecov\.yml$ 9 | -------------------------------------------------------------------------------- /inst/htmlwidgets/chartJSRadar.yaml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: chart.js 3 | version: 2.5.0 4 | src: htmlwidgets/lib/chart.js 5 | script: ./dist/Chart.min.js 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: R 2 | cache: packages 3 | warnings_are_errors: true 4 | sudo: false 5 | r_packages: 6 | - covr 7 | 8 | after_success: 9 | - Rscript -e 'library(covr); codecov()' 10 | -------------------------------------------------------------------------------- /tests/testthat/test-runExampleApp.R: -------------------------------------------------------------------------------- 1 | context("runExampleApp") 2 | 3 | test_that("None existant apps", { 4 | 5 | expect_error(runExampleApp("beans")) 6 | 7 | expect_error(runExampleApp(17)) 8 | 9 | }) -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(chartJSRadar) 4 | export(chartJSRadarOutput) 5 | export(chartJSRadar_html) 6 | export(renderChartJSRadar) 7 | export(runExampleApp) 8 | import(htmltools) 9 | import(htmlwidgets) 10 | -------------------------------------------------------------------------------- /inst/shiny-examples/basic/server.R: -------------------------------------------------------------------------------- 1 | library(radarchart) 2 | 3 | shinyServer(function(input, output) { 4 | output$radar <- renderChartJSRadar({ 5 | 6 | chartJSRadar(skills[, c("Label", input$selectedPeople)], 7 | maxScale = 10, showToolTipLabel=TRUE) 8 | }) 9 | }) -------------------------------------------------------------------------------- /tests/testthat/test-setRadarScale.R: -------------------------------------------------------------------------------- 1 | context("Radar Scale") 2 | 3 | test_that("setRadarscale returns correct structure", { 4 | 5 | tStart <- 2 6 | tMax <- 15 7 | tStep <- 5 8 | 9 | scale <- setRadarScale(tMax, tStep, tStart) 10 | 11 | expect_identical(scale$ticks$min, tStart) 12 | expect_identical(scale$ticks$max, tMax) 13 | expect_identical(scale$ticks$stepSize, tStep) 14 | }) 15 | -------------------------------------------------------------------------------- /inst/shiny-examples/basic/ui.R: -------------------------------------------------------------------------------- 1 | library(radarchart) 2 | 3 | shinyUI(pageWithSidebar( 4 | headerPanel('Radarchart Shiny Example'), 5 | sidebarPanel( 6 | checkboxGroupInput('selectedPeople', 'Who to include', 7 | names(radarchart::skills)[-1], selected="Rich") 8 | ), 9 | mainPanel( 10 | chartJSRadarOutput("radar", width = "450", height = "300"), width = 7 11 | ) 12 | )) 13 | -------------------------------------------------------------------------------- /man/chartJSRadarOutput.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chartJSRadar.R 3 | \name{chartJSRadarOutput} 4 | \alias{chartJSRadarOutput} 5 | \title{Widget output function for use in Shiny} 6 | \usage{ 7 | chartJSRadarOutput(outputId, width = "450", height = "300") 8 | } 9 | \arguments{ 10 | \item{outputId}{output variable to read from} 11 | 12 | \item{width}{Must be valid CSS unit} 13 | 14 | \item{height}{Must be valid CSS unit} 15 | } 16 | \description{ 17 | Widget output function for use in Shiny 18 | } 19 | 20 | -------------------------------------------------------------------------------- /man/colourMatrix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/colourMatrix.R 3 | \name{colourMatrix} 4 | \alias{colourMatrix} 5 | \title{Check and prep the colour matrix} 6 | \usage{ 7 | colourMatrix(colMatrix) 8 | } 9 | \arguments{ 10 | \item{colMatrix}{A 3 x n matrix of integers between 0-255} 11 | } 12 | \value{ 13 | The checked and prepped matrix of the same size 14 | } 15 | \description{ 16 | Check and prep the colour matrix 17 | } 18 | \examples{ 19 | radarchart:::colourMatrix(diag(255, nrow=3)) 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/chart.js/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js", 3 | "description": "Simple HTML5 charts using the canvas element.", 4 | "homepage": "http://www.chartjs.org", 5 | "license": "MIT", 6 | "version": "2.4.0", 7 | "main": "./dist/Chart.js", 8 | "_release": "2.4.0", 9 | "_resolution": { 10 | "type": "version", 11 | "tag": "v2.4.0", 12 | "commit": "324a82b78b12f0c409723071b621ae64b22c812f" 13 | }, 14 | "_source": "https://github.com/chartjs/Chart.js.git", 15 | "_target": "~2.4.0", 16 | "_originalSource": "chart.js", 17 | "_direct": true 18 | } -------------------------------------------------------------------------------- /man/renderChartJSRadar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chartJSRadar.R 3 | \name{renderChartJSRadar} 4 | \alias{renderChartJSRadar} 5 | \title{Widget render function for use in Shiny} 6 | \usage{ 7 | renderChartJSRadar(expr, env = parent.frame(), quoted = FALSE) 8 | } 9 | \arguments{ 10 | \item{expr}{expression passed to \link[htmlwidgets]{shinyRenderWidget}} 11 | 12 | \item{env}{environment in which to evaluate expression} 13 | 14 | \item{quoted}{Logical. Is expression quoted?} 15 | } 16 | \description{ 17 | Widget render function for use in Shiny 18 | } 19 | 20 | -------------------------------------------------------------------------------- /man/skills.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{skills} 5 | \alias{skills} 6 | \title{Skills in a team} 7 | \format{A data frame with 6 rows and 4 columns 8 | \describe{ 9 | \item{Label}{The axis label for chartJSRadar} 10 | \item{Aimee}{Vector of skills for Aimee} 11 | \item{Andy}{Vector of skills for Andy} 12 | \item{Rich}{Vector of skills for Rich} 13 | }} 14 | \source{ 15 | Simulated 16 | } 17 | \usage{ 18 | skills 19 | } 20 | \description{ 21 | A dataset containing the skills vectors for three people 22 | } 23 | \keyword{datasets} 24 | 25 | -------------------------------------------------------------------------------- /man/runExampleApp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/runExample.R 3 | \name{runExampleApp} 4 | \alias{runExampleApp} 5 | \title{Run an example Shiny app} 6 | \usage{ 7 | runExampleApp(example) 8 | } 9 | \arguments{ 10 | \item{example}{the name of the example. Choose from "basic" or "options".} 11 | } 12 | \description{ 13 | The radarchart package contains a number of demo Shiny apps to illustrate how 14 | to use the plots. The code is in \code{inst/shiny-examples/} and running this 15 | function will allow quick access to the apps. 16 | } 17 | \examples{ 18 | \dontrun{ 19 | runExample("basic") 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /man/chartJSRadar_html.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chartJSRadar.R 3 | \name{chartJSRadar_html} 4 | \alias{chartJSRadar_html} 5 | \title{Tell htmltools where to output the chart} 6 | \usage{ 7 | chartJSRadar_html(id, style, class, width, height, ...) 8 | } 9 | \arguments{ 10 | \item{id}{The id of the target object} 11 | 12 | \item{style}{css stylings} 13 | 14 | \item{class}{class of the target} 15 | 16 | \item{width}{width of target} 17 | 18 | \item{height}{height of target} 19 | 20 | \item{...}{extra arguments currently unused} 21 | } 22 | \description{ 23 | Tell htmltools where to output the chart 24 | } 25 | 26 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## Updated in this version 2 | 3 | * Fixed DESCRIPTION file quotes 4 | * Upgraded to latest chart.js version 2.4.0 5 | * Added titles and legends as requested 6 | 7 | ## Test environments 8 | 9 | * local OS X install, R 3.2.3 10 | * ubuntu 12.04 (on travis-ci), R 3.3.2 11 | * linux-x86_64-centos6-epel (r-hub) 12 | * Windows Server 2008 R2 SP1, R-release, 32/64 bit (r-hub) 13 | 14 | ## R CMD check results 15 | 16 | 0 errors | 0 warnings | 2 notes 17 | 18 | Note about MIT license. Both this package and Chart.js are MIT. 19 | 20 | Note about README.md requiring pandoc (is this for the images?) 21 | 22 | ## Reverse dependencies 23 | 24 | There are no reverse dependencies. 25 | 26 | -------------------------------------------------------------------------------- /man/setRadarScale.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chartJSRadar.R 3 | \name{setRadarScale} 4 | \alias{setRadarScale} 5 | \title{Autoscale the radar plot} 6 | \usage{ 7 | setRadarScale(maxScale = NULL, scaleStepWidth = NULL, scaleStartValue = 0) 8 | } 9 | \arguments{ 10 | \item{maxScale}{Numeric length 1. Desired max limit} 11 | 12 | \item{scaleStepWidth}{Numeric length 1. Spacing between rings} 13 | 14 | \item{scaleStartValue}{Numeric length 1. Value of the centre} 15 | } 16 | \value{ 17 | A list containing the scale options for chartjs 18 | } 19 | \description{ 20 | Autoscale the radar plot 21 | } 22 | \examples{ 23 | \dontrun{ 24 | setRadarScale(15, 3) 25 | setRadarScale(15, 5, 2) 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | ### 0.3.0 2 | 3 | - Upgrade to chart.js v2.4.0 4 | - Allows titles with `main` option 5 | - Allows legends 6 | 7 | ### 0.2.0 8 | 9 | - Plots with no data will render (with no data) [issue 5](https://github.com/MangoTheCat/radarchart/issues/5) 10 | - Change Shiny defaults so the canvas isn't huge [issue 3](https://github.com/MangoTheCat/radarchart/issues/3) 11 | - Added basic shiny example 12 | - Added options shiny example 13 | - runExample function to easily access the shiny apps 14 | 15 | ### 0.1.2 16 | 17 | Fix test error with new htmlwidgets version 18 | 19 | ## 0.1.1 20 | 21 | First CRAN release 22 | 23 | ### 0.0.2 24 | 25 | - Data frame input accepted. 26 | - colMatrix now aligned to `col2rgb` output (transpose of previous version). 27 | 28 | ### 0.0.1 29 | 30 | First GitHub release. 31 | -------------------------------------------------------------------------------- /tests/testthat/test-colourMatrix.R: -------------------------------------------------------------------------------- 1 | context("Colours") 2 | 3 | test_that("colourMatrix error checks", { 4 | 5 | # Needs a matrix input 6 | expect_error(colourMatrix(c("red", "green"))) 7 | # A numeric matrix 8 | expect_error(colourMatrix(matrix(c("red", "green")))) 9 | 10 | 11 | }) 12 | 13 | test_that("colourMatrix transformations", { 14 | 15 | testMat <- matrix(c(1000, 50, 20, 200, 988,400), nrow = 3) 16 | 17 | expect_warning(colourMatrix(testMat)) 18 | 19 | # If it doesn't have 3 rows it's warns 20 | expect_warning(colourMatrix(t(testMat))) 21 | 22 | # This checks for rounding 23 | outMat <- suppressWarnings(colourMatrix(testMat)) 24 | expectMat <- structure(c(255, 12, 5, 51, 251, 102), .Dim = c(3L, 2L)) 25 | 26 | expect_equal(outMat, expectMat) 27 | 28 | }) -------------------------------------------------------------------------------- /man/skillsByName.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{skillsByName} 5 | \alias{skillsByName} 6 | \title{Rotated version of skills data} 7 | \format{A data frame with 6 rows and 4 columns 8 | \describe{ 9 | \item{Name}{Name of the team member} 10 | \item{Communicator}{Their Communicator score: 0-10} 11 | \item{Data Wangler}{Their Data Wangler score: 0-10} 12 | \item{Modeller}{Their Modeller score: 0-10} 13 | \item{Programmer}{Their Programmer score: 0-10} 14 | \item{Technologist}{Their Technologist score: 0-10} 15 | \item{Visualizer}{Their Visualizer score: 0-10} 16 | }} 17 | \source{ 18 | Simulated 19 | } 20 | \usage{ 21 | skillsByName 22 | } 23 | \description{ 24 | A dataset containing the skills vectors for three people but by row rather 25 | than column. This data set is used to show how to rotate the data into a 26 | format accepted by \code{\link{chartJSRadar}}. 27 | } 28 | \keyword{datasets} 29 | 30 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # DO NOT CHANGE the "init" and "install" sections below 2 | 3 | # Download script file from GitHub 4 | init: 5 | ps: | 6 | $ErrorActionPreference = "Stop" 7 | Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1" 8 | Import-Module '..\appveyor-tool.ps1' 9 | 10 | install: 11 | ps: Bootstrap 12 | 13 | # Adapt as necessary starting from here 14 | 15 | build_script: 16 | - travis-tool.sh install_deps 17 | 18 | test_script: 19 | - travis-tool.sh run_tests 20 | 21 | on_failure: 22 | - 7z a failure.zip *.Rcheck\* 23 | - appveyor PushArtifact failure.zip 24 | 25 | artifacts: 26 | - path: '*.Rcheck\**\*.log' 27 | name: Logs 28 | 29 | - path: '*.Rcheck\**\*.out' 30 | name: Logs 31 | 32 | - path: '*.Rcheck\**\*.fail' 33 | name: Logs 34 | 35 | - path: '*.Rcheck\**\*.Rout' 36 | name: Logs 37 | 38 | - path: '\*_*.tar.gz' 39 | name: Bits 40 | 41 | - path: '\*_*.zip' 42 | name: Bits 43 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/chart.js/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2017 Nick Downie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /inst/minimal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Radar Chart Test 6 | 7 | 8 | 9 | 10 | 11 | 12 | 43 | 44 | -------------------------------------------------------------------------------- /R/data.R: -------------------------------------------------------------------------------- 1 | #' Skills in a team 2 | #' 3 | #' A dataset containing the skills vectors for three people 4 | #' 5 | #' @format A data frame with 6 rows and 4 columns 6 | #' \describe{ 7 | #' \item{Label}{The axis label for chartJSRadar} 8 | #' \item{Aimee}{Vector of skills for Aimee} 9 | #' \item{Andy}{Vector of skills for Andy} 10 | #' \item{Rich}{Vector of skills for Rich} 11 | #' } 12 | #' @source Simulated 13 | "skills" 14 | 15 | #' Rotated version of skills data 16 | #' 17 | #' A dataset containing the skills vectors for three people but by row rather 18 | #' than column. This data set is used to show how to rotate the data into a 19 | #' format accepted by \code{\link{chartJSRadar}}. 20 | #' 21 | #' @format A data frame with 6 rows and 4 columns 22 | #' \describe{ 23 | #' \item{Name}{Name of the team member} 24 | #' \item{Communicator}{Their Communicator score: 0-10} 25 | #' \item{Data Wangler}{Their Data Wangler score: 0-10} 26 | #' \item{Modeller}{Their Modeller score: 0-10} 27 | #' \item{Programmer}{Their Programmer score: 0-10} 28 | #' \item{Technologist}{Their Technologist score: 0-10} 29 | #' \item{Visualizer}{Their Visualizer score: 0-10} 30 | #' } 31 | #' @source Simulated 32 | "skillsByName" -------------------------------------------------------------------------------- /R/colourMatrix.R: -------------------------------------------------------------------------------- 1 | 2 | #' Check and prep the colour matrix 3 | #' 4 | #' @param colMatrix A 3 x n matrix of integers between 0-255 5 | #' 6 | #' @return The checked and prepped matrix of the same size 7 | #' 8 | #' @examples 9 | #' radarchart:::colourMatrix(diag(255, nrow=3)) 10 | #' 11 | colourMatrix <- function(colMatrix) { 12 | 13 | # Colours. Perhaps replace with proper palette 14 | if (is.null(colMatrix)) { 15 | colMatrix <- grDevices::col2rgb(c("red", "green", "blue", "yellow", 16 | "magenta", "cyan", "orange", "purple", "pink")) 17 | } else { 18 | 19 | stopifnot(is.numeric(colMatrix)) 20 | stopifnot(is.matrix(colMatrix)) 21 | 22 | if(nrow(colMatrix) != 3 & ncol(colMatrix)==3) { 23 | warning("3 columns and ", nrow(colMatrix), "rows. Do you need to transform the matrix - t(colMatrix)?") 24 | } 25 | 26 | if (any(colMatrix<0)) stop("colMatrix can't have negative values") 27 | 28 | # Check the range 29 | if (max(colMatrix) > 255) { 30 | colMatrix <- 255 * colMatrix / max(colMatrix) 31 | warning("colMatrix has values larger than 255, scaling by largest value") 32 | } 33 | 34 | # Make sure it's integer 35 | colMatrix <- floor(colMatrix) 36 | } 37 | 38 | colMatrix 39 | } -------------------------------------------------------------------------------- /R/runExample.R: -------------------------------------------------------------------------------- 1 | 2 | #' Run an example Shiny app 3 | #' 4 | #' The radarchart package contains a number of demo Shiny apps to illustrate how 5 | #' to use the plots. The code is in \code{inst/shiny-examples/} and running this 6 | #' function will allow quick access to the apps. 7 | #' 8 | #' @param example the name of the example. Choose from "basic" or "options". 9 | #' 10 | #' @export 11 | #' 12 | #' @examples 13 | #' \dontrun{ 14 | #' runExample("basic") 15 | #' } 16 | runExampleApp <- function(example) { 17 | 18 | # Check for Shiny: 19 | if (!requireNamespace("shiny", quietly = TRUE)) { 20 | stop("The package: \"shiny\" is needed to run these examples. Please install.", 21 | call. = FALSE) 22 | } 23 | 24 | # Check the input 25 | stopifnot(is.vector(example)) 26 | stopifnot(is.character(example)) 27 | stopifnot(length(example) == 1) 28 | 29 | # All directories in there assumed to be apps 30 | # Will this be OK for people with locked down systems? 31 | #availApps <- c("basic", "options") 32 | availApps <- dir(system.file("shiny-examples", package = "radarchart")) 33 | 34 | 35 | # Check the app exists 36 | if (!(example %in% availApps)) { 37 | stop("example must be one of: ", paste(availApps, collapse = ", ")) 38 | } 39 | 40 | # Run it 41 | shiny::runApp(system.file("shiny-examples", example, package = "radarchart")) 42 | } 43 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: radarchart 2 | Title: Radar Chart from 'Chart.js' 3 | Version: 0.3.1.9000 4 | Authors@R: c(person("Doug", "Ashton", email = "dashton@mango-solutions.com", role = c("aut", "cre")), 5 | person("Shane", "Porter", email = "sporter@mango-solutions.com", role = c("aut")), 6 | person("Adeel", "Khan", email = "AdeelK@gwu.edu", role = c("ctb")), 7 | person("Nick", "Downie", role = c("ctb"), comment = "chart.js library"), 8 | person("Tanner", "Linsley", role = c("ctb"), comment = "chart.js library"), 9 | person("William", "Entriken", role = c("ctb"), comment = "chart.js library")) 10 | Description: Create interactive radar charts using the 'Chart.js' 'JavaScript' library 11 | and the 'htmlwidgets' package. 'Chart.js' is a 12 | lightweight library that supports several types of simple chart using the 'HTML5' 13 | canvas element. This package provides an R interface specifically to the 14 | radar chart, sometimes called a spider chart, for visualising multivariate data. 15 | Depends: 16 | R (>= 3.1.2) 17 | License: MIT + file LICENSE 18 | LazyData: true 19 | URL: https://github.com/mangothecat/radarchart 20 | BugReports: https://github.com/mangothecat/radarchart/issues 21 | Imports: 22 | htmlwidgets, 23 | htmltools, 24 | grDevices 25 | RoxygenNote: 5.0.1 26 | Suggests: testthat, 27 | knitr, 28 | rmarkdown, 29 | tidyr, 30 | shiny, 31 | covr 32 | VignetteBuilder: knitr 33 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/chart.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chart.js", 3 | "homepage": "http://www.chartjs.org", 4 | "description": "Simple HTML5 charts using the canvas element.", 5 | "version": "2.4.0", 6 | "license": "MIT", 7 | "main": "src/chart.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/chartjs/Chart.js.git" 11 | }, 12 | "devDependencies": { 13 | "browserify": "^13.0.0", 14 | "browserify-istanbul": "^0.2.1", 15 | "bundle-collapser": "^1.2.1", 16 | "coveralls": "^2.11.6", 17 | "gulp": "3.9.x", 18 | "gulp-concat": "~2.1.x", 19 | "gulp-connect": "~2.0.5", 20 | "gulp-eslint": "^3.0.0", 21 | "gulp-file": "^0.3.0", 22 | "gulp-html-validator": "^0.0.2", 23 | "gulp-insert": "~0.5.0", 24 | "gulp-karma": "0.0.4", 25 | "gulp-replace": "^0.5.4", 26 | "gulp-size": "~0.4.0", 27 | "gulp-streamify": "^1.0.2", 28 | "gulp-uglify": "~0.2.x", 29 | "gulp-util": "~2.2.x", 30 | "gulp-zip": "~3.2.0", 31 | "jasmine": "^2.3.2", 32 | "jasmine-core": "^2.3.4", 33 | "karma": "^0.12.37", 34 | "karma-browserify": "^5.0.1", 35 | "karma-chrome-launcher": "^0.2.0", 36 | "karma-coverage": "^0.5.1", 37 | "karma-firefox-launcher": "^0.1.6", 38 | "karma-jasmine": "^0.3.6", 39 | "karma-jasmine-html-reporter": "^0.1.8", 40 | "merge-stream": "^1.0.0", 41 | "vinyl-source-stream": "^1.1.0", 42 | "watchify": "^3.7.0", 43 | "yargs": "^5.0.0" 44 | }, 45 | "spm": { 46 | "main": "Chart.js" 47 | }, 48 | "dependencies": { 49 | "chartjs-color": "^2.0.0", 50 | "moment": "^2.10.6" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /vignettes/preparingData.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Preparing Data for `radarchart`" 3 | author: "Doug Ashton" 4 | date: "`r Sys.Date()`" 5 | output: rmarkdown::html_vignette 6 | vignette: > 7 | %\VignetteIndexEntry{Preparing Data} 8 | %\VignetteEngine{knitr::rmarkdown} 9 | %\VignetteEncoding{UTF-8} 10 | --- 11 | 12 | The `radarchart` package expects data to be in a format whereby each row corresponds to an axis on the chart (or a `Label`) and each column is a set of scores. An example is the built in data set, `skills`. 13 | 14 | ```{r} 15 | library(radarchart) 16 | skills 17 | ``` 18 | 19 | In many cases your data will have a column for each axis, and each row is a set of observations. In the `skills` example we might build up a spreadsheet where each row is a person and each column a skill. 20 | 21 | ```{r} 22 | skillsByName 23 | ``` 24 | 25 | In order to use this data set with `radarchart` we need to *rotate* it. This can be done with packages such as `tidyr`. 26 | 27 | ```{r, tidyR} 28 | library(tidyr) 29 | skillsByLabel <- gather(skillsByName, key=Label, value=Score, -Name) %>% 30 | spread(key=Name, value=Score) 31 | skillsByLabel 32 | ``` 33 | 34 | If you don't want to have a dependency on `tidyr` then you can do the same thing using a few lines of base `R` code. 35 | 36 | ```{r, baseR} 37 | skillsByLabel <- as.data.frame(t(skillsByName[,-1])) 38 | names(skillsByLabel) <- skillsByName$Name 39 | skillsByLabel <- cbind(Label=row.names(skillsByLabel), skillsByLabel) 40 | row.names(skillsByLabel) <- NULL 41 | ``` 42 | 43 | This rotated data set is now ready for use with `radarchart`. 44 | 45 | ```{r, eval=FALSE} 46 | chartJSRadar(scores = skillsByLabel, maxScale = 10) 47 | ``` 48 | -------------------------------------------------------------------------------- /inst/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Radar Chart Test 6 | 7 | 8 | 9 | 10 | 11 | 12 | 56 | 57 | -------------------------------------------------------------------------------- /inst/htmlwidgets/chartJSRadar.js: -------------------------------------------------------------------------------- 1 | HTMLWidgets.widget({ 2 | 3 | name: 'chartJSRadar', 4 | type: 'output', 5 | 6 | factory: function(el, width, height) { 7 | 8 | var ctx = el.getContext("2d"); 9 | var instance = new Chart(ctx, {type: 'radar'}); 10 | 11 | return { 12 | renderValue: function(x) { 13 | 14 | if (instance.config.data.datasets.length===0) { 15 | // Add data for the first time 16 | instance.config.data = x.data; 17 | instance.config.options = x.options; 18 | } else { 19 | 20 | // Remove extraneous datasets 21 | while (instance.config.data.datasets.length > x.data.datasets.length) { 22 | instance.config.data.datasets.pop(); 23 | } 24 | 25 | x.data.datasets.forEach(function(dataset, sid) { 26 | 27 | if (instance.config.data.datasets[sid]) { 28 | // Update the existing datasets 29 | dataset.data.forEach(function(point, pid) { 30 | instance.config.data.datasets[sid].data[pid] = point; 31 | }) 32 | Object.keys(dataset).forEach(function(key) { 33 | if(key!=='data') { // don't mutate data key 34 | instance.config.data.datasets[sid][key] = dataset[key]; 35 | } 36 | }) 37 | } else { 38 | // Add new datasets 39 | instance.config.data.datasets[sid] = dataset; 40 | } 41 | 42 | }) 43 | 44 | } 45 | 46 | // Update the options 47 | instance.options = Chart.helpers.configMerge(instance.options, x.options); 48 | instance.update(); 49 | 50 | }, 51 | 52 | resize: function(width, height) { 53 | instance.resize(); 54 | }, 55 | 56 | instance: instance 57 | }; 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /inst/shiny-examples/options/ui.R: -------------------------------------------------------------------------------- 1 | library(radarchart) 2 | 3 | shinyUI(pageWithSidebar( 4 | headerPanel('Radarchart Options Chooser'), 5 | sidebarPanel( 6 | checkboxGroupInput('selectedPeople', 'Who to include', 7 | names(radarchart::skills)[-1], selected="Rich"), 8 | 9 | textInput("main", "main (title)", value = ""), 10 | 11 | numericInput("maxScale", "maxScale - 0 for NULL (default)", value = 10, min = 0, 12 | max = NA, step = 1), 13 | 14 | numericInput("scaleStepWidth", "scaleStepWidth - 0 for NULL (default)", 15 | value = 0, min = 0, max = NA, step = 1), 16 | 17 | numericInput("scaleStartValue", "scaleStartValue - 0 is the default", 18 | value = 0, min = NA, max = NA, step = 1), 19 | 20 | numericInput("labelSize", "labelSize", value = 18, min = 1, max = NA, step = 1), 21 | 22 | numericInput("lineAlpha", "lineAlpha", value = 0.8, min = 0, max = 1, step = 0.05), 23 | 24 | numericInput("polyAlpha", "polyAlpha", value = 0.2, min = 0, max = 1, step = 0.05), 25 | 26 | checkboxInput("addDots", "addDots", value = TRUE), 27 | 28 | checkboxInput("showLegend", "showLegend", value = TRUE), 29 | 30 | checkboxInput("showToolTipLabel", "showToolTipLabel", value = FALSE), 31 | 32 | checkboxInput("responsive", "responsive", value = TRUE), 33 | 34 | radioButtons("colMat", "colMatrix", choices=c("Matrix", "Named"), 35 | selected = "Named", inline = TRUE), 36 | 37 | uiOutput("colMatText"), 38 | actionButton("colButton", "Update") 39 | 40 | ), 41 | mainPanel( 42 | p("Try changing the options in the side panel and then copy the function call that produces it."), 43 | chartJSRadarOutput("radar", width = "450", height = "300"), 44 | code(textOutput("radarCall")), width = 7 45 | ) 46 | )) 47 | -------------------------------------------------------------------------------- /man/chartJSRadar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/chartJSRadar.R 3 | \name{chartJSRadar} 4 | \alias{chartJSRadar} 5 | \title{Make a ChartJS Radar Plot} 6 | \usage{ 7 | chartJSRadar(scores, labs, width = NULL, height = NULL, main = NULL, 8 | maxScale = NULL, scaleStepWidth = NULL, scaleStartValue = 0, 9 | responsive = TRUE, labelSize = 18, showLegend = TRUE, addDots = TRUE, 10 | colMatrix = NULL, polyAlpha = 0.2, lineAlpha = 0.8, 11 | showToolTipLabel = TRUE, ...) 12 | } 13 | \arguments{ 14 | \item{scores}{Data frame or named list of scores for each axis. 15 | If \code{labs} is not specified then labels are taken from the first column (or element).} 16 | 17 | \item{labs}{Labels for each axis. If left unspecified labels are taken from 18 | the scores data set. If set to NA then labels are left blank.} 19 | 20 | \item{width}{Width of output plot} 21 | 22 | \item{height}{Height of output plot} 23 | 24 | \item{main}{Character: Title to be displayed} 25 | 26 | \item{maxScale}{Max value on each axis} 27 | 28 | \item{scaleStepWidth}{Spacing between rings on radar} 29 | 30 | \item{scaleStartValue}{Value at the centre of the radar} 31 | 32 | \item{responsive}{Logical. whether or not the chart should be responsive and resize when the browser does} 33 | 34 | \item{labelSize}{Numeric. Point label font size in pixels} 35 | 36 | \item{showLegend}{Logical whether to show the legend} 37 | 38 | \item{addDots}{Logical. Whether to show a dot for each point} 39 | 40 | \item{colMatrix}{Numeric matrix of rgb colour values. If \code{NULL} defaults are used} 41 | 42 | \item{polyAlpha}{Alpha value for the fill of polygons} 43 | 44 | \item{lineAlpha}{Alpha value for the outlines} 45 | 46 | \item{showToolTipLabel}{Logical. If \code{TRUE} then data set labels are shown in the tooltip hover over} 47 | 48 | \item{...}{Extra options passed straight to chart.js. Names must match existing options 49 | \url{http://www.chartjs.org/docs/#getting-started-global-chart-configuration}} 50 | } 51 | \description{ 52 | R bindings to the radar plot in the chartJS library 53 | } 54 | \examples{ 55 | # Using the data frame interface 56 | chartJSRadar(scores=skills) 57 | 58 | # Or using a list interface 59 | labs <- c("Communicator", "Data Wangler", "Programmer", "Technologist", "Modeller", "Visualizer") 60 | 61 | scores <- list("Rich" = c(9, 7, 4, 5, 3, 7), 62 | "Andy" = c(7, 6, 6, 2, 6, 9), 63 | "Aimee" = c(6, 5, 8, 4, 7, 6)) 64 | 65 | # Default settings 66 | chartJSRadar(scores=scores, labs=labs) 67 | 68 | # Fix the max score 69 | chartJSRadar(scores=scores, labs=labs, maxScale=10) 70 | 71 | # Fix max and spacing 72 | chartJSRadar(scores=scores, labs=labs, maxScale=12, scaleStepWidth = 2) 73 | 74 | # Change title and remove legend 75 | chartJSRadar(scores=scores, labs=labs, main = "Data Science Radar", showLegend = FALSE) 76 | 77 | # Add pass through settings for extra options 78 | chartJSRadar(scores=scores, labs=labs, maxScale =10, scaleLineWidth=5) 79 | 80 | } 81 | 82 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/chart.js/README.md: -------------------------------------------------------------------------------- 1 | # Chart.js 2 | 3 | [![Build Status](https://travis-ci.org/chartjs/Chart.js.svg?branch=master)](https://travis-ci.org/chartjs/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js) [![Coverage Status](https://coveralls.io/repos/github/chartjs/Chart.js/badge.svg?branch=master)](https://coveralls.io/github/chartjs/Chart.js?branch=master) 4 | 5 | [![Chart.js on Slack](https://img.shields.io/badge/slack-Chart.js-blue.svg)](https://chart-js-automation.herokuapp.com/) 6 | 7 | *Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org) 8 | 9 | ## Installation 10 | 11 | You can download the latest version of Chart.js from the [GitHub releases](https://github.com/chartjs/Chart.js/releases/latest) or use a [Chart.js CDN](https://cdnjs.com/libraries/Chart.js). 12 | 13 | To install via npm: 14 | 15 | ```bash 16 | npm install chart.js --save 17 | ``` 18 | 19 | To install via bower: 20 | ```bash 21 | bower install chart.js --save 22 | ``` 23 | 24 | #### Selecting the Correct Build 25 | 26 | Chart.js provides two different builds that are available for your use. The `Chart.js` and `Chart.min.js` files include Chart.js and the accompanying color parsing library. If this version is used and you require the use of the time axis, [Moment.js](http://momentjs.com/) will need to be included before Chart.js. 27 | 28 | The `Chart.bundle.js` and `Chart.bundle.min.js` builds include Moment.js in a single file. This version should be used if you require time axes and want a single file to include, select this version. Do not use this build if your application already includes Moment.js. If you do, Moment.js will be included twice, increasing the page load time and potentially introducing version issues. 29 | 30 | ## Documentation 31 | 32 | You can find documentation at [www.chartjs.org/docs](http://www.chartjs.org/docs). The markdown files that build the site are available under `/docs`. Previous version documentation is available at [www.chartjs.org/docs/#notes-previous-versions](http://www.chartjs.org/docs/#notes-previous-versions). 33 | 34 | ## Contributing 35 | 36 | Before submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/Chart.js/blob/master/CONTRIBUTING.md) first. 37 | 38 | For support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/chartjs). 39 | 40 | ## Building and Testing 41 | 42 | To build, run `gulp build`. 43 | 44 | To test, run `gulp test`. 45 | 46 | To test against code standards, run `gulp lint`. 47 | 48 | More information on building and testing can be found in [gulpfile.js](gulpfile.js). 49 | 50 | Thanks to [BrowserStack](https://browserstack.com) for allowing our team to test on thousands of browsers. 51 | 52 | ## License 53 | 54 | Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT). 55 | -------------------------------------------------------------------------------- /tests/testthat/test-chartJSRadar.R: -------------------------------------------------------------------------------- 1 | context("chartJSRadar") 2 | 3 | test_that("chartJSRadar takes scores and labels", { 4 | 5 | labs <- c("Communicator", "Data Wangler", "Programmer", "Technologist", 6 | "Modeller", "Visualizer") 7 | scores <- list("Rich" = c(9, 7, 4, 5, 3, 7), 8 | "Andy" = c(7, 6, 6, 2, 6, 9), 9 | "Aimee" = c(6, 5, 8, 4, 7, 6), 10 | "Doug" = c(4, 5, 8, 9, 8, 2)) 11 | 12 | a <- chartJSRadar(scores = scores, labs = labs) 13 | 14 | # Expect that chart contains the correct scores for the first dataset 15 | expect_equal(a$x$data$datasets[[1]]$data, scores[[1]]) 16 | 17 | # Expect that the chart contains the correct labels 18 | expect_equal(a$x$data$labels, labs) 19 | }) 20 | 21 | test_that("chartJSRadar takes a data frame", { 22 | 23 | scores <- data.frame("Label"= c("Communicator", "Data Wangler", "Programmer", 24 | "Technologist", "Modeller", "Visualizer"), 25 | "Rich" = c(9, 7, 4, 5, 3, 7), 26 | "Andy" = c(7, 6, 6, 2, 6, 9), 27 | "Aimee" = c(6, 5, 8, 4, 7, 6), 28 | "Doug" = c(4, 5, 8, 9, 8, 2)) 29 | 30 | a <- chartJSRadar(scores = scores) 31 | 32 | expect_equal(a$x$data$labels, scores$Label) 33 | # Expect datasets length to equal number of cols in dataframe (minus the Label) 34 | expect_equal(length(a$x$data$datasets), ncol(scores) - 1) 35 | }) 36 | 37 | test_that("chartJSRadar handles missing labels", { 38 | 39 | scores <- data.frame("Rich" = c(9, 7, 4, 5, 3, 7), 40 | "Andy" = c(7, 6, 6, 2, 6, 9)) 41 | 42 | # Missing labels and no character column in position 1 43 | expect_error(chartJSRadar(scores = scores)) 44 | 45 | a <- chartJSRadar(scores = scores, labs = NA) 46 | 47 | # NA labels converted to blank 48 | expect_equal(a$x$data$labels, c("", "", "", "", "", "")) 49 | 50 | # If labels are specified they should be the right length 51 | expect_error(chartJSRadar(scores = scores, labs = LETTERS[1:3])) 52 | }) 53 | 54 | test_that("chartJSRadar options can be set correctly", { 55 | 56 | labs <- c("Communicator", "Data Wangler", "Programmer", "Technologist", 57 | "Modeller", "Visualizer") 58 | scores <- list("Rich" = c(9, 7, 4, 5, 3, 7), 59 | "Andy" = c(7, 6, 6, 2, 6, 9), 60 | "Aimee" = c(6, 5, 8, 4, 7, 6), 61 | "Doug" = c(4, 5, 8, 9, 8, 2)) 62 | 63 | # Set some non-default options and test object has been set correctly 64 | exMaxScale <- 10 65 | exResponsive <- FALSE 66 | exLabelSize <- 20 67 | 68 | a <- chartJSRadar(scores = scores, labs = labs, 69 | maxScale = exMaxScale, 70 | responsive = exResponsive, 71 | labelSize = exLabelSize) 72 | 73 | expect_equal(a$x$options$scale$ticks$max, exMaxScale) 74 | expect_equal(a$x$options$responsive, exResponsive) 75 | expect_equal(a$x$options$scale$pointLabels$fontSize, exLabelSize) 76 | }) 77 | -------------------------------------------------------------------------------- /inst/shiny-examples/options/server.R: -------------------------------------------------------------------------------- 1 | library(radarchart) 2 | 3 | shinyServer(function(input, output) { 4 | 5 | # Build the "call" statement 6 | # This is supposed to be the call made to chartJSRadar that would give the 7 | # current plot 8 | 9 | v <- reactiveValues( cmText = col2rgb(c("red", "forestgreen", "navyblue"))) 10 | 11 | observeEvent(input$colButton, { 12 | if(!is.null(input$colMatValue)) { 13 | v$cmText <- eval(parse(text=input$colMatValue)) 14 | } else { 15 | v$cmText <- NULL 16 | } 17 | }) 18 | 19 | output$colMatText <- renderUI({ 20 | cmValue <- reactive({ 21 | if (input$colMat == "Named") { 22 | 'col2rgb(c("red", "forestgreen", "navyblue"))' 23 | } else { 24 | "matrix(c(255, 0, 0, 34, 139, 34, 0, 0, 128), nrow = 3)" 25 | } 26 | }) 27 | textInput("colMatValue", "Code: ", value=cmValue()) 28 | }) 29 | 30 | output$radarCall <- reactive({ 31 | 32 | arguments <- c( 33 | paste0("skills[, c(\"Label\"," , 34 | paste0(paste0('"', input$selectedPeople, '"'), collapse=", "), ")]", 35 | collapse=""), 36 | 37 | paste0("main = ", ifelse(input$main != "", input$main, "NULL")), 38 | 39 | paste0("maxScale = ", ifelse(input$maxScale>0, input$maxScale, "NULL")), 40 | 41 | paste0("scaleStepWidth = ", 42 | ifelse(input$scaleStepWidth>0, input$scaleStepWidth, "NULL")), 43 | 44 | paste0("scaleStartValue = ", input$scaleStartValue), 45 | 46 | paste0("labelSize = ", input$labelSize), 47 | 48 | paste0("addDots = ", as.character(input$addDots)), 49 | 50 | paste0("showToolTipLabel = ", as.character(input$showToolTipLabel)), 51 | 52 | paste0("showLegend = ", as.character(input$showLegend)), 53 | 54 | paste0("lineAlpha = ", input$lineAlpha), 55 | 56 | paste0("polyAlpha = ", input$polyAlpha), 57 | 58 | paste0("responsive = ", as.character(input$responsive)), 59 | 60 | paste0("colMatrix = ", input$colMatValue) 61 | ) 62 | 63 | arguments[1] <- paste0("chartJSRadar(", arguments[1]) 64 | arguments[length(arguments)] <- paste0(arguments[length(arguments)], ")") 65 | 66 | paste(arguments, sep="", collapse=", ") 67 | 68 | }) 69 | 70 | 71 | # This is because the 0 represents NULL thing is hard to feed directly to the 72 | # chartJSRadar call 73 | output$radar <- renderChartJSRadar({ 74 | 75 | # Convert zero to a NULL 76 | maxScaleR <- reactive({ 77 | if (input$maxScale>0) 78 | input$maxScale 79 | else 80 | NULL 81 | }) 82 | # Convert zero to a NULL 83 | scaleStepWidthR <- reactive({ 84 | if (input$scaleStepWidth>0) 85 | input$scaleStepWidth 86 | else 87 | NULL 88 | }) 89 | 90 | # The main call 91 | chartJSRadar(skills[, c("Label", input$selectedPeople)], 92 | main = input$main, 93 | maxScale = maxScaleR(), 94 | scaleStepWidth = scaleStepWidthR(), 95 | scaleStartValue = input$scaleStartValue, 96 | responsive = input$responsive, 97 | showLegend = input$showLegend, 98 | labelSize = input$labelSize, 99 | addDots = input$addDots, 100 | lineAlpha = input$lineAlpha, 101 | polyAlpha = input$polyAlpha, 102 | showToolTipLabel=input$showToolTipLabel, 103 | colMatrix = v$cmText) 104 | }) 105 | 106 | }) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # radarchart 2 | 3 | [![Project Status: Unsupported – The project has reached a stable, usable state but the author(s) have ceased all work on it. A new maintainer may be desired.](https://www.repostatus.org/badges/latest/unsupported.svg)](https://www.repostatus.org/#unsupported) 4 | [![Build Status](https://travis-ci.org/MangoTheCat/radarchart.svg?branch=master)](https://travis-ci.org/MangoTheCat/radarchart) [![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/github/MangoTheCat/radarchart?branch=master&svg=true)](https://ci.appveyor.com/project/MangoTheCat/radarchart) [![CRAN Status](http://www.r-pkg.org/badges/version/radarchart)](http://www.r-pkg.org/pkg/radarchart) 5 | [![codecov](https://codecov.io/gh/MangoTheCat/radarchart/branch/master/graph/badge.svg)](https://codecov.io/gh/MangoTheCat/radarchart) 6 | [![CRAN RStudio mirror downloads](http://cranlogs.r-pkg.org/badges/radarchart)](http://www.r-pkg.org/pkg/radarchart) 7 | [![Total CRAN downloads](http://cranlogs.r-pkg.org/badges/grand-total/radarchart)](http://www.r-pkg.org/pkg/radarchart) 8 | 9 | An R implementation of the radar chart from the [chart.js](http://www.chartjs.org/) javascript library. 10 | 11 | Unfortunately we're not developing `radarchart` at the moment. Major CRAN fixes will be done if necessary. 12 | 13 | ## Installation 14 | 15 | You can install from CRAN. 16 | ```r 17 | install.packages("radarchart") 18 | ``` 19 | 20 | To install the latest version direct from GitHub you'll need devtools installed. Assuming you have this run: 21 | ```r 22 | devtools::install_github("MangoTheCat/radarchart") 23 | ``` 24 | 25 | Or if you want to hack about with the code then clone the repository, change directory into it and run 26 | ```r 27 | devtools::install() 28 | ``` 29 | 30 | Note: `htmlwidgets` packages don't work well with `devtools::load_all()`. 31 | 32 | ## Usage 33 | 34 | Once installed you can make a radar chart 35 | 36 | ```r 37 | library(radarchart) 38 | 39 | labs <- c("Communicator", "Data Wangler", "Programmer", 40 | "Technologist", "Modeller", "Visualizer") 41 | 42 | scores <- list( 43 | "Rich" = c(9, 7, 4, 5, 3, 7), 44 | "Andy" = c(7, 6, 6, 2, 6, 9), 45 | "Aimee" = c(6, 5, 8, 4, 7, 6) 46 | ) 47 | 48 | chartJSRadar(scores = scores, labs = labs, maxScale = 10) 49 | ``` 50 | Static image of example output 51 |

Static version. Real plots are interactive

52 | 53 | Alternatively, you may supply a data frame and `chartJSRadar` will pickup the labels from the first column of the data. Also we're showing an option to display data set labels in the mouse over. 54 | 55 | ```r 56 | scores <- data.frame("Label"=c("Communicator", "Data Wangler", "Programmer", 57 | "Technologist", "Modeller", "Visualizer"), 58 | "Rich" = c(9, 7, 4, 5, 3, 7), 59 | "Andy" = c(7, 6, 6, 2, 6, 9), 60 | "Aimee" = c(6, 5, 8, 4, 7, 6)) 61 | 62 | chartJSRadar(scores, maxScale = 10, showToolTipLabel=TRUE) 63 | ``` 64 | Static image of example output 65 |

Static version. Real plots are interactive

66 | 67 | You can now also add a title 68 | 69 | ```r 70 | chartJSRadar(skills, main = "Data Science Radar") 71 | ``` 72 | Static image of example output 73 |

Static version. Real plots are interactive

74 | 75 | ## Shiny 76 | 77 | As it's based on htmlwidgets it's easy to use `radarchart` with Shiny. Just use the 78 | 79 | ```r 80 | chartJSRadarOutput("ID", width = "450", height = "300") 81 | ``` 82 | function in your `ui.R` and call `chartJSRadar` as normal in your `server.R`. A minimal example can be found in [`inst/shiny-examples/basic`](https://github.com/MangoTheCat/radarchart/tree/master/inst/shiny-examples/basic). You can run this with the `runExampleApp` function 83 | 84 | ```r 85 | runExampleApp("basic") 86 | ``` 87 | 88 | An `"options"` app is available to help construct more customised radar charts. 89 | 90 | ## License 91 | 92 | MIT © Mango Solutions, Nick Downie 93 | -------------------------------------------------------------------------------- /R/chartJSRadar.R: -------------------------------------------------------------------------------- 1 | #' Make a ChartJS Radar Plot 2 | #' 3 | #' R bindings to the radar plot in the chartJS library 4 | #' 5 | #' @param scores Data frame or named list of scores for each axis. 6 | #' If \code{labs} is not specified then labels are taken from the first column (or element). 7 | #' @param labs Labels for each axis. If left unspecified labels are taken from 8 | #' the scores data set. If set to NA then labels are left blank. 9 | #' @param width Width of output plot 10 | #' @param height Height of output plot 11 | #' @param main Character: Title to be displayed 12 | #' @param maxScale Max value on each axis 13 | #' @param scaleStepWidth Spacing between rings on radar 14 | #' @param scaleStartValue Value at the centre of the radar 15 | #' @param responsive Logical. whether or not the chart should be responsive and resize when the browser does 16 | #' @param labelSize Numeric. Point label font size in pixels 17 | #' @param showLegend Logical whether to show the legend 18 | #' @param addDots Logical. Whether to show a dot for each point 19 | #' @param colMatrix Numeric matrix of rgb colour values. If \code{NULL} defaults are used 20 | #' @param polyAlpha Alpha value for the fill of polygons 21 | #' @param lineAlpha Alpha value for the outlines 22 | #' @param showToolTipLabel Logical. If \code{TRUE} then data set labels are shown in the tooltip hover over 23 | #' @param ... Extra options passed straight to chart.js. Names must match existing options 24 | #' \url{http://www.chartjs.org/docs/#getting-started-global-chart-configuration} 25 | #' 26 | #' @import htmlwidgets 27 | #' @import htmltools 28 | #' 29 | #' @export 30 | #' @examples 31 | #' # Using the data frame interface 32 | #' chartJSRadar(scores=skills) 33 | #' 34 | #' # Or using a list interface 35 | #' labs <- c("Communicator", "Data Wangler", "Programmer", "Technologist", "Modeller", "Visualizer") 36 | #' 37 | #' scores <- list("Rich" = c(9, 7, 4, 5, 3, 7), 38 | #' "Andy" = c(7, 6, 6, 2, 6, 9), 39 | #' "Aimee" = c(6, 5, 8, 4, 7, 6)) 40 | #' 41 | #' # Default settings 42 | #' chartJSRadar(scores=scores, labs=labs) 43 | #' 44 | #' # Fix the max score 45 | #' chartJSRadar(scores=scores, labs=labs, maxScale=10) 46 | #' 47 | #' # Fix max and spacing 48 | #' chartJSRadar(scores=scores, labs=labs, maxScale=12, scaleStepWidth = 2) 49 | #' 50 | #' # Change title and remove legend 51 | #' chartJSRadar(scores=scores, labs=labs, main = "Data Science Radar", showLegend = FALSE) 52 | #' 53 | #' # Add pass through settings for extra options 54 | #' chartJSRadar(scores=scores, labs=labs, maxScale =10, scaleLineWidth=5) 55 | #' 56 | chartJSRadar <- function(scores, labs, width = NULL, height = NULL, main = NULL, 57 | maxScale = NULL, scaleStepWidth = NULL, 58 | scaleStartValue = 0, responsive = TRUE, labelSize = 18, 59 | showLegend = TRUE, 60 | addDots = TRUE, colMatrix = NULL, polyAlpha = .2, 61 | lineAlpha = .8, showToolTipLabel = TRUE, ...) { 62 | 63 | # Should we keep variable names consistent from chart.js to R? 64 | # Then we can just pass through anything that doesn't need preprocessing 65 | 66 | # If it comes through as a single vector wrap it back up 67 | if(!is.list(scores)) scores <- list(scores) 68 | 69 | # This block trys to handle different ways the data might 70 | # not look how we expect. Missings etc. 71 | if(missing(labs)) { 72 | if(is.character(scores[[1]]) | is.factor(scores[[1]])) { 73 | labs <- scores[[1]] # Copy the first column of scores into the labels 74 | if (length(scores) > 1) { # This catches empty data 75 | scores[[1]] <- NULL # Drop the labels column 76 | } else { 77 | # Add a dummy column with no data 78 | scores <- data.frame("null"=rep(NA, length(labs))) 79 | } 80 | } else { 81 | stop("if labs is unspecified then the first column of scores must be character data") 82 | } 83 | } 84 | 85 | 86 | 87 | # If NA is supplied then put blank labels 88 | if(all(is.na(labs))) { 89 | labs <- rep("", length(scores[[1]])) 90 | } 91 | 92 | # Check data is in right shape 93 | x <- vapply(scores, function(x) length(x)==length(labs), FALSE) 94 | if(!all(x)) { 95 | stop("Each score vector must be the same length as the labs vector") 96 | } 97 | 98 | colMatrix <- colourMatrix(colMatrix) 99 | 100 | # Check for maxScale 101 | opScale <- list(scale = list()) 102 | opScale$scale <- setRadarScale(maxScale, scaleStepWidth, scaleStartValue) 103 | opScale$scale$pointLabels <- list(fontSize = labelSize) 104 | #fontColor = "#111", 105 | #fontFamily = "Times") 106 | 107 | opToolTip <- list(tooltips = list(enabled = showToolTipLabel, 108 | mode = "label")) 109 | 110 | # Any extra options passed straight through. Names must match existing options 111 | # http://www.chartjs.org/docs/#getting-started-global-chart-configuration 112 | opPassThrough <- list(...) 113 | 114 | opTitle <- list(title = list(display = !is.null(main), text = main)) 115 | 116 | opLegend <- list(legend = list(display = showLegend)) 117 | 118 | # Combine scale options, pass through and explicit options 119 | opList <- c(list(responsive = responsive), 120 | opTitle, opScale, opToolTip, opLegend, opPassThrough) 121 | 122 | 123 | # forward options using x 124 | datasets <- lapply(names(scores), function(x) list(label=x)) 125 | 126 | for (i in seq_along(datasets)) { 127 | 128 | iCol <- (i-1) %% ncol(colMatrix) + 1 # cyclic repeat colours 129 | 130 | fillCol <- paste0("rgba(", paste0(colMatrix[ , iCol], collapse=","), 131 | ",", polyAlpha, ")") 132 | lineCol <- paste0("rgba(", paste0(colMatrix[ , iCol], collapse=","), 133 | ",", lineAlpha, ")") 134 | 135 | datasets[[i]]$data <- scores[[i]] # Data Points 136 | 137 | datasets[[i]]$backgroundColor <- fillCol # Polygon Fill 138 | datasets[[i]]$borderColor <- lineCol # Line Colour 139 | datasets[[i]]$pointBackgroundColor <- lineCol # Point colour 140 | 141 | datasets[[i]]$pointBorderColor <- "#fff" # Point outline 142 | datasets[[i]]$pointHoverBackgroundColor <- "#fff" # Point Highlight fill 143 | datasets[[i]]$pointHoverBorderColor <- lineCol # Point Highlight line 144 | if(!addDots) datasets[[i]]$pointRadius <- 0 145 | } 146 | 147 | x <- list(data = list(labels=labs, datasets=datasets), options = opList) 148 | 149 | #print(jsonlite::toJSON(x, pretty = TRUE, auto_unbox = TRUE)) 150 | 151 | # create widget 152 | htmlwidgets::createWidget( 153 | name = "chartJSRadar", 154 | x, 155 | width = width, 156 | height = height, 157 | package = "radarchart" 158 | ) 159 | } 160 | 161 | #' Autoscale the radar plot 162 | #' 163 | #' @param maxScale Numeric length 1. Desired max limit 164 | #' @param scaleStepWidth Numeric length 1. Spacing between rings 165 | #' @param scaleStartValue Numeric length 1. Value of the centre 166 | #' 167 | #' @return A list containing the scale options for chartjs 168 | #' 169 | #' @examples 170 | #' \dontrun{ 171 | #' setRadarScale(15, 3) 172 | #' setRadarScale(15, 5, 2) 173 | #' } 174 | setRadarScale <- function(maxScale = NULL, scaleStepWidth = NULL, 175 | scaleStartValue = 0) { 176 | 177 | if (!is.null(maxScale)) { 178 | 179 | opScale <- list(ticks = list(max = maxScale)) 180 | opScale$ticks$min <- scaleStartValue 181 | 182 | # Did they fix the tick points? 183 | if (!is.null(scaleStepWidth)) { 184 | opScale$ticks$stepSize <- scaleStepWidth 185 | opScale$ticks$maxTicksLimit <- 1000 186 | } 187 | # else { 188 | # if (maxScale-scaleStartValue <= 12) { 189 | # opScale$scaleStepWidth <- 1 190 | # } else { 191 | # opScale$scaleStepWidth <- floor( (maxScale-scaleStartValue) / 10) 192 | # } 193 | # } 194 | # opScale$scaleSteps <- ceiling( (maxScale - scaleStartValue) / 195 | # opScale$scaleStepWidth) 196 | # opScale$scaleStartValue <- scaleStartValue 197 | } else { 198 | if(!is.null(scaleStartValue)) { 199 | opScale <- list(ticks = list(min = scaleStartValue)) 200 | } else { 201 | opScale <- list() 202 | } 203 | } 204 | opScale 205 | } 206 | 207 | #' Tell htmltools where to output the chart 208 | #' 209 | #' @param id The id of the target object 210 | #' @param style css stylings 211 | #' @param class class of the target 212 | #' @param width width of target 213 | #' @param height height of target 214 | #' @param ... extra arguments currently unused 215 | #' 216 | #' @export 217 | chartJSRadar_html <- function(id, style, class, width, height, ...){ 218 | htmltools::tags$canvas(id = id, class = class, width=width, height=height) 219 | } 220 | 221 | #' Widget output function for use in Shiny 222 | #' 223 | #' @param outputId output variable to read from 224 | #' @param width Must be valid CSS unit 225 | #' @param height Must be valid CSS unit 226 | #' 227 | #' @export 228 | chartJSRadarOutput <- function(outputId, width = "450", height = "300"){ 229 | shinyWidgetOutput(outputId, "chartJSRadar", width, height, package = "radarchart") 230 | } 231 | 232 | #' Widget render function for use in Shiny 233 | #' 234 | #' @param expr expression passed to \link[htmlwidgets]{shinyRenderWidget} 235 | #' @param env environment in which to evaluate expression 236 | #' @param quoted Logical. Is expression quoted? 237 | #' 238 | #' @export 239 | renderChartJSRadar <- function(expr, env = parent.frame(), quoted = FALSE) { 240 | if (!quoted) { 241 | expr <- substitute(expr) 242 | } # force quoted 243 | shinyRenderWidget(expr, chartJSRadarOutput, env, quoted = TRUE) 244 | } 245 | -------------------------------------------------------------------------------- /inst/htmlwidgets/lib/chart.js/dist/Chart.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Chart.js 3 | * http://chartjs.org/ 4 | * Version: 2.5.0 5 | * 6 | * Copyright 2017 Nick Downie 7 | * Released under the MIT license 8 | * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md 9 | */ 10 | !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,a,i){function n(r,s){if(!a[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=a[r]={exports:{}};e[r][0].call(d.exports,function(t){var a=e[r][1][t];return n(a?a:t)},d,d.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;ra?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return e<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=a<0?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),s=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*a.red()+l*i.red(),s*a.green()+l*i.green(),s*a.blue()+l*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function d(t){var e,a,i,n=u(t),o=n[0],r=n[1],s=n[2];return o/=95.047,r/=100,s/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*r-16,a=500*(o-r),i=200*(r-s),[e,a,i]}function c(t){return z(d(t))}function h(t){var e,a,i,n,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return o=255*l,[o,o,o];a=l<.5?l*(1+s):l+s-l*s,e=2*l-a,n=[0,0,0];for(var u=0;u<3;u++)i=r+1/3*-(u-1),i<0&&i++,i>1&&i--,o=6*i<1?e+6*(a-e)*i:2*i<1?a:3*i<2?e+(a-e)*(2/3-i)*6:e,n[u]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=o<=1?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return s(h(t))}function v(t){return l(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),s=255*i*(1-a*o),l=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,l,r];case 1:return[s,i,r];case 2:return[r,i,l];case 3:return[r,s,i];case 4:return[l,r,i];case 5:return[i,r,s]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=a<=1?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return s(x(t))}function M(t){return l(x(t))}function w(t){var e,a,i,n,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),a=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),n=s+i*(a-s),e){default:case 6:case 0:r=a,g=n,b=s;break;case 1:r=n,g=a,b=s;break;case 2:r=s,g=a,b=n;break;case 3:r=s,g=n,b=a;break;case 4:r=n,g=s,b=a;break;case 5:r=a,g=s,b=n}return[255*r,255*g,255*b]}function C(t){return i(w(t))}function I(t){return n(w(t))}function D(t){return s(w(t))}function A(t){return l(w(t))}function T(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,s=t[3]/100;return e=1-Math.min(1,n*(1-s)+s),a=1-Math.min(1,o*(1-s)+s),i=1-Math.min(1,r*(1-s)+s),[255*e,255*a,255*i]}function P(t){return i(T(t))}function _(t){return n(T(t))}function F(t){return o(T(t))}function V(t){return l(T(t))}function R(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+o*-1.5372+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function O(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function L(t){return z(O(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],s=t[2];return o<=8?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=e/95.047<=.008856?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=i/108.883<=.008859?i=108.883*(n-s/200-16/116)/7.787:108.883*Math.pow(n-s/200,3),[e,a,i]}function z(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,a<0&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function W(t){return R(B(t))}function N(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function E(t){return B(N(t))}function H(t){return W(N(t))}function j(t){return G[t]}function U(t){return i(j(t))}function q(t){return n(j(t))}function Y(t){return o(j(t))}function X(t){return s(j(t))}function K(t){return d(j(t))}function J(t){return u(j(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:M,hwb2rgb:w,hwb2hsl:C,hwb2hsv:I,hwb2cmyk:D,hwb2keyword:A,cmyk2rgb:T,cmyk2hsl:P,cmyk2hsv:_,cmyk2hwb:F,cmyk2keyword:V,keyword2rgb:j,keyword2hsl:U,keyword2hsv:q,keyword2hwb:Y,keyword2cmyk:X,keyword2lab:K,keyword2xyz:J,xyz2rgb:R,xyz2lab:O,xyz2lch:L,lab2xyz:B,lab2rgb:W,lab2lch:z,lch2lab:N,lch2xyz:E,lch2rgb:H};var G={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Z={};for(var Q in G)Z[JSON.stringify(G[Q])]=Q},{}],5:[function(t,e,a){var i=t(4),n=function(){return new u};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];n[s]=n[s]||{},n[s][l]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o'),n[o]&&e.push(n[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s&&s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(p),y:Math.sin(p)},b=g<=0&&0<=p||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,M={x:y?-1:Math.min(m.x*(m.x<0?1:S),v.x*(v.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),v.y*(v.y<0?1:S))},w={x:b?1:Math.max(m.x*(m.x>0?1:S),v.x*(v.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),v.y*(v.y>0?1:S))},C={width:.5*(w.x-M.x),height:.5*(w.y-M.y)};u=Math.min(s/C.width,l/C.height),d={x:(w.x+M.x)*-.5,y:(w.y+M.y)*-.5}}i.borderWidth=a.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=Math.max(a.outerRadius-i.radiusLength,0),e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,s=o.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:u+o.offsetX,y:d+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,a,o.data.labels[a])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===a?b.startAngle=s.rotation:b.startAngle=n.getMeta().data[a-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,a,i=0,n=this.index,o=t.length,r=0;ri?e:i,i=a>i?a:i;return i}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,n,o,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(o=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:a.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:o.cubicInterpolationMode?o.cubicInterpolationMode:a.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,n=u.length;i');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o'),n[o]&&e.push(n[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},s=a.getDataset(),l=a.chart.options.elements.line,u=a.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:o.tension?o.tension:e.getValueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,l.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,l.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,l.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,l.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,l.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,l.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;it.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(e,a,i,n,o){var r,s,l,u,d,c;if("object"==typeof a&&(r=a.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void e.drawImage(a,n-a.width/2,o-a.height/2);if(!(isNaN(i)||i<=0)){switch(a){default:e.beginPath(),e.arc(n,o,i,0,2*Math.PI),e.closePath(),e.fill();break;case"triangle":e.beginPath(),s=3*i/Math.sqrt(3),d=s*Math.sqrt(3)/2,e.moveTo(n-s/2,o+d/3),e.lineTo(n+s/2,o+d/3),e.lineTo(n,o-2*d/3),e.closePath(),e.fill();break;case"rect":c=1/Math.SQRT2*i,e.beginPath(),e.fillRect(n-c,o-c,2*c,2*c),e.strokeRect(n-c,o-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=n-h,g=o-h,p=Math.SQRT2*i;t.helpers.drawRoundedRectangle(e,f,g,p,p,i/2),e.fill();break;case"rectRot":c=1/Math.SQRT2*i,e.beginPath(),e.moveTo(n-c,o),e.lineTo(n,o+c),e.lineTo(n+c,o),e.lineTo(n,o-c),e.closePath(),e.fill();break;case"cross":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"crossRot":e.beginPath(),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"star":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"line":e.beginPath(),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"dash":e.beginPath(),e.moveTo(n,o),e.lineTo(n+i,o),e.closePath()}e.stroke()}},e.clipArea=function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},e.unclipArea=function(t){t.restore()}}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){function e(e){e=e||{};var a=e.data=e.data||{};return a.datasets=a.datasets||[],a.labels=a.labels||[],e.options=i.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}function a(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}var i=t.helpers,n=t.plugins,o=t.platform;t.types={},t.instances={},t.controllers={},t.Controller=function(a,n,r){var s=this;n=e(n);var l=o.acquireContext(a,n),u=l&&l.canvas,d=u&&u.height,c=u&&u.width;return r.ctx=l,r.canvas=u,r.config=n,r.width=c,r.height=d,r.aspectRatio=d?c/d:null,s.id=i.uid(),s.chart=r,s.config=n,s.options=n.options,s._bufferedRender=!1,t.instances[s.id]=s,Object.defineProperty(s,"data",{get:function(){return s.config.data}}),l&&u?(s.initialize(),s.update(),s):(console.error("Failed to create chart: can't acquire context from the given item"),s)},i.extend(t.Controller.prototype,{initialize:function(){var t=this;return n.notify(t,"beforeInit"),i.retinaScale(t.chart),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),n.notify(t,"afterInit"),t},clear:function(){return i.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,a=e.chart,o=e.options,r=a.canvas,s=o.maintainAspectRatio&&a.aspectRatio||null,l=Math.floor(i.getMaximumWidth(r)),u=Math.floor(s?l/s:i.getMaximumHeight(r));if((a.width!==l||a.height!==u)&&(r.width=a.width=l,r.height=a.height=u,r.style.width=l+"px",r.style.height=u+"px",i.retinaScale(a),!t)){var d={width:l,height:u};n.notify(e,"resize",[d]),e.options.onResize&&e.options.onResize(e,d),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},a=t.scale;i.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),i.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),a&&(a.id=a.id||"scale")},buildScales:function(){var e=this,a=e.options,n=e.scales={},o=[];a.scales&&(o=o.concat((a.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(a.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),a.scale&&o.push({options:a.scale,dtype:"radialLinear",isDefault:!0}),i.each(o,function(a){var o=a.options,r=i.getValueOrDefault(o.type,a.dtype),s=t.scaleService.getScaleConstructor(r);if(s){var l=new s({id:o.id,options:o,ctx:e.chart.ctx,chart:e});n[l.id]=l,a.isDefault&&(e.scale=l)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,a=[],n=[];if(i.each(e.data.datasets,function(i,o){var r=e.getDatasetMeta(o);r.type||(r.type=i.type||e.config.type),a.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](e,o),n.push(r.controller))},e),a.length>1)for(var o=1;o0||(n.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,n=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&a(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;ti&&t.insertElements(i,n-i)},insertElements:function(t,e){for(var a=0;a=0;n--)e.call(a,t[n],n);else for(n=0;n=i[a].length||!i[a][n].type?i[a].push(o.configMerge(s,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],s,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,s=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,a,i,n,r=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=r.length;for(e=0;e0?r[e-1]:null,n=e0?r[e-1]:null,n=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i0?(a=l[0].clientX,i=l[0].clientY):(a=n.clientX,i=n.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return a=Math.round((a-s.left-u)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"),10),i=parseInt(o.getStyle(e,"padding-right"),10),n=e.clientWidth-a-i,r=o.getConstraintWidth(t);return isNaN(r)?n:Math.min(n,r)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"),10),i=parseInt(o.getStyle(e,"padding-bottom"),10),n=e.clientHeight-a-i,r=o.getConstraintHeight(t);return isNaN(r)?n:Math.min(n,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var a=t.canvas,i=t.height,n=t.width;a.height=i*e,a.width=n*e,t.ctx.scale(e,e),a.style.height=i+"px",a.style.width=n+"px"}},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var s=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?s=o.measureText(t,n,r,s,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(s=o.measureText(t,n,r,s,e))})});var l=r.length/2;if(l>a.length){for(var u=0;ui&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.error("Color.js not found!"),e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!==e.length)return!1;for(a=0,i=t.length;a0&&(s=t.getDatasetMeta(s[0]._datasetIndex).data),s},"x-axis":function(t,e){return o(t,e,!0)},point:function(t,a){var n=e(a,t.chart);return i(t,n)},nearest:function(t,a,i){var o=e(a,t.chart),r=n(t,o,i.intersect);return r.length>1&&r.sort(function(t,e){var a=t.getArea(),i=e.getArea(),n=a-i;return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),r.slice(0,1)},x:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inXRange(o.x)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r},y:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inYRange(o.y)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r}}}}},{}],28:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){return this.controller=new t.Controller(e,a,this),this.controller};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('
    ');for(var a=0;a'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("");return e.push("
"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?x:C,w),I-=e.height):(e=t.update(M,S),C-=e.width),D.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(D,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:Math.max(F,A),right:Math.max(V,T),top:0,bottom:0};t.update(t.options.fullWidth?x:C,y/2,i)}else t.update(a.minSize.width,I)}function r(t){var a=e.findNextWhere(D,function(e){return e.box===t}),i={left:0,right:0,top:R,bottom:O};a&&t.update(a.minSize.width,I,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?d:F,t.right=t.options.fullWidth?a-c:F+C,t.top=E,t.bottom=E+t.height,E=t.bottom):(t.left=N,t.right=N+t.width,t.top=R,t.bottom=R+I,N=t.right)}if(t){var l=t.options.layout,u=l?l.padding:null,d=0,c=0,h=0,f=0;isNaN(u)?(d=u.left||0,c=u.right||0,h=u.top||0,f=u.bottom||0):(d=u,c=u,h=u,f=u);var g=e.where(t.boxes,function(t){return"left"===t.options.position}),p=e.where(t.boxes,function(t){return"right"===t.options.position}),m=e.where(t.boxes,function(t){return"top"===t.options.position}),v=e.where(t.boxes,function(t){return"bottom"===t.options.position}),b=e.where(t.boxes,function(t){return"chartArea"===t.options.position});m.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),v.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var x=a-d-c,y=i-h-f,k=x/2,S=y/2,M=(a-k)/(g.length+p.length),w=(i-S)/(m.length+v.length),C=x,I=y,D=[];e.each(g.concat(p,m,v),n);var A=0,T=0,P=0,_=0;e.each(m.concat(v),function(t){if(t.getPadding){var e=t.getPadding();A=Math.max(A,e.left),T=Math.max(T,e.right)}}),e.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();P=Math.max(P,e.top),_=Math.max(_,e.bottom)}});var F=d,V=c,R=h,O=f;e.each(g.concat(p),o),e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m.concat(v),o),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height}),e.each(g.concat(p),r),F=d,V=c,R=h,O=f,e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height});var L=Math.max(A-F,0);F+=L,V+=Math.max(T-V,0);var B=Math.max(P-R,0);R+=B,O+=Math.max(_-O,0);var z=i-R-O,W=a-F-V;W===C&&z===I||(e.each(g,function(t){t.height=z}),e.each(p,function(t){t.height=z}),e.each(m,function(t){t.options.fullWidth||(t.width=W)}),e.each(v,function(t){t.options.fullWidth||(t.width=W)}),I=z,C=W);var N=d+L,E=h+B;e.each(g.concat(m),s),N+=C,E+=I,e.each(p,s),e.each(v,s),t.chartArea={left:F,top:R,right:F+C,bottom:R+I},e.each(b,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(C,I)})}}}}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function a(e,a){var i=new t.Legend({ctx:e.chart.ctx,options:a,chart:e});e.legend=i,t.layoutService.addBox(e,i)}var i=t.helpers,n=i.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return i.isArray(e.datasets)?e.datasets.map(function(e,a){return{text:e.label,fillStyle:i.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(a),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:a}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:n,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:function(){var t=this,e=t.options.labels,a=e.generateLabels.call(t,t.chart);e.filter&&(a=a.filter(function(a){return e.filter(a,t.chart.data)})),t.options.reverse&&a.reverse(),t.legendItems=a},afterBuildLabels:n,beforeFit:n,fit:function(){var a=this,n=a.options,o=n.labels,r=n.display,s=a.ctx,l=t.defaults.global,u=i.getValueOrDefault,d=u(o.fontSize,l.defaultFontSize),c=u(o.fontStyle,l.defaultFontStyle),h=u(o.fontFamily,l.defaultFontFamily),f=i.fontString(d,c,h),g=a.legendHitBoxes=[],p=a.minSize,m=a.isHorizontal();if(m?(p.width=a.maxWidth,p.height=r?10:0):(p.width=r?10:0,p.height=a.maxHeight),r)if(s.font=f,m){var v=a.lineWidths=[0],b=a.legendItems.length?d+o.padding:0;s.textAlign="left",s.textBaseline="top",i.each(a.legendItems,function(t,i){var n=e(o,d),r=n+d/2+s.measureText(t.text).width;v[v.length-1]+r+o.padding>=a.width&&(b+=d+o.padding,v[v.length]=a.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+o.padding}),p.height+=b}else{var x=o.padding,y=a.columnWidths=[],k=o.padding,S=0,M=0,w=d+x;i.each(a.legendItems,function(t,a){var i=e(o,d),n=i+d/2+s.measureText(t.text).width;M+w>p.height&&(k+=S+o.padding,y.push(S),S=0,M=0),S=Math.max(S,n),M+=w,g[a]={left:0,top:0,width:n,height:d}}),k+=S,y.push(S),p.width+=k}a.width=p.width,a.height=p.height},afterFit:n,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,n=a.options,o=n.labels,r=t.defaults.global,s=r.elements.line,l=a.width,u=a.lineWidths;if(n.display){var d,c=a.ctx,h=i.getValueOrDefault,f=h(o.fontColor,r.defaultFontColor),g=h(o.fontSize,r.defaultFontSize),p=h(o.fontStyle,r.defaultFontStyle),m=h(o.fontFamily,r.defaultFontFamily),v=i.fontString(g,p,m);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(o,g),x=a.legendHitBoxes,y=function(e,a,i){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(i.fillStyle,r.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,r.defaultColor);var o=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),n.labels&&n.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=e+u,f=a+u;t.canvasHelpers.drawPoint(c,i.pointStyle,l,d,f)}else o||c.strokeRect(e,a,b,g),c.fillRect(e,a,b,g);c.restore()}},k=function(t,e,a,i){c.fillText(a.text,b+g/2+t,e),a.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},S=a.isHorizontal();d=S?{x:a.left+(l-u[0])/2,y:a.top+o.padding,line:0}:{x:a.left+o.padding,y:a.top+o.padding,line:0};var M=g+o.padding;i.each(a.legendItems,function(t,e){var i=c.measureText(t.text).width,n=b+g/2+i,r=d.x,s=d.y;S?r+n>=l&&(s=d.y+=M,d.line++,r=d.x=a.left+(l-u[d.line])/2):s+M>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+o.padding,s=d.y=a.top+o.padding,d.line++),y(r,s,t),x[e].left=r,x[e].top=s,k(r,s,t,i),S?d.x+=n+o.padding:d.y+=M})}},handleEvent:function(t){var e=this,a=e.options,i="mouseup"===t.type?"click":t.type,n=!1;if("mousemove"===i){if(!a.onHover)return}else{if("click"!==i)return;if(!a.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===i){a.onClick.call(e,t.native,e.legendItems[l]),n=!0;break}if("mousemove"===i){a.onHover.call(e,t.native,e.legendItems[l]),n=!0;break}}}return n}}),t.plugins.register({beforeInit:function(t){var e=t.options.legend;e&&a(t,e)},beforeUpdate:function(e){var n=e.options.legend;n?(n=i.configMerge(t.defaults.global.legend,n),e.legend?e.legend.options=n:a(e,n)):(t.layoutService.removeBox(e,e.legend),delete e.legend)},afterEvent:function(t,e){var a=t.legend;a&&a.handleEvent(e)}})}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.plugins={},t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){e.indexOf(t)===-1&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);a!==-1&&e.splice(a,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length; 13 | },getAll:function(){return this._plugins},notify:function(t,e,a){var i,n,o,r,s,l=this.descriptors(t),u=l.length;for(i=0;ic&&rt.maxHeight){r--;break}r++,d=s*u}t.labelRotation=r},afterCalculateTickRotation:function(){i.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callCallback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},o=t.options,r=o.ticks,s=o.scaleLabel,l=o.gridLines,u=o.display,d=t.isHorizontal(),c=a(r),h=1.5*a(s).size,f=o.gridLines.tickMarkLength;if(d?n.width=t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:n.width=u&&l.drawTicks?f:0,d?n.height=u&&l.drawTicks?f:0:n.height=t.maxHeight,s.display&&u&&(d?n.height+=h:n.width+=h),r.display&&u){var g=i.longestText(t.ctx,c.font,t.ticks,t.longestTextCache),p=i.numberOfLabelLines(t.ticks),m=.5*c.size;if(d){t.longestLabelWidth=g;var v=i.toRadians(t.labelRotation),b=Math.cos(v),x=Math.sin(v),y=x*g+c.size*p+m*p;n.height=Math.min(t.maxHeight,n.height+y),t.ctx.font=c.font;var k=t.ticks[0],S=e(t.ctx,k,c.font),M=t.ticks[t.ticks.length-1],w=e(t.ctx,M,c.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?b*S+3:b*m+3,t.paddingRight="bottom"===o.position?b*m+3:b*w+3):(t.paddingLeft=S/2+3,t.paddingRight=w/2+3)}else r.mirror?g=0:g+=t.options.ticks.padding,n.width+=g,t.paddingTop=c.size/2,t.paddingBottom=c.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var s=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(s/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,a=t.max;return t.beginAtZero?0:e<0&&a<0?a:e>0&&a>0?e:0},draw:function(e){var n=this,o=n.options;if(o.display){var r,s,l=n.ctx,u=t.defaults.global,d=o.ticks,c=o.gridLines,h=o.scaleLabel,f=0!==n.labelRotation,g=d.autoSkip,p=n.isHorizontal();d.maxTicksLimit&&(s=d.maxTicksLimit);var m=i.getValueOrDefault(d.fontColor,u.defaultFontColor),v=a(d),b=c.drawTicks?c.tickMarkLength:0,x=i.getValueOrDefault(c.borderDash,u.borderDash),y=i.getValueOrDefault(c.borderDashOffset,u.borderDashOffset),k=i.getValueOrDefault(h.fontColor,u.defaultFontColor),S=a(h),M=i.toRadians(n.labelRotation),w=Math.cos(M),C=n.longestLabelWidth*w;l.fillStyle=m;var I=[];if(p){if(r=!1,f&&(C/=2),(C+d.autoSkipPadding)*n.ticks.length>n.width-(n.paddingLeft+n.paddingRight)&&(r=1+Math.floor((C+d.autoSkipPadding)*n.ticks.length/(n.width-(n.paddingLeft+n.paddingRight)))),s&&n.ticks.length>s)for(;!r||n.ticks.length/(r||1)>s;)r||(r=1),r+=1;g||(r=!1)}var D="right"===o.position?n.left:n.right-b,A="right"===o.position?n.left+b:n.right,T="bottom"===o.position?n.top:n.bottom-b,P="bottom"===o.position?n.top+b:n.bottom;if(i.each(n.ticks,function(t,a){if(void 0!==t&&null!==t){var s=n.ticks.length===a+1,l=r>1&&a%r>0||a%r===0&&a+r>=n.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var u,h;a===("undefined"!=typeof n.zeroLineIndex?n.zeroLineIndex:0)?(u=c.zeroLineWidth,h=c.zeroLineColor):(u=i.getValueAtIndexOrDefault(c.lineWidth,a),h=i.getValueAtIndexOrDefault(c.color,a));var g,m,v,k,S,w,C,_,F,V,R="middle",O="middle";if(p){"bottom"===o.position?(O=f?"middle":"top",R=f?"right":"center",V=n.top+b):(O=f?"middle":"bottom",R=f?"left":"center",V=n.bottom-b);var L=n.getPixelForTick(a)+i.aliasPixel(u);F=n.getPixelForTick(a,c.offsetGridLines)+d.labelOffset,g=v=S=C=L,m=T,k=P,w=e.top,_=e.bottom}else{var B,z="left"===o.position,W=d.padding;d.mirror?(R=z?"left":"right",B=W):(R=z?"right":"left",B=b+W),F=z?n.right-B:n.left+B;var N=n.getPixelForTick(a);N+=i.aliasPixel(u),V=n.getPixelForTick(a,c.offsetGridLines),g=D,v=A,S=e.left,C=e.right,m=k=w=_=N}I.push({tx1:g,ty1:m,tx2:v,ty2:k,x1:S,y1:w,x2:C,y2:_,labelX:F,labelY:V,glWidth:u,glColor:h,glBorderDash:x,glBorderDashOffset:y,rotation:-1*M,label:t,textBaseline:O,textAlign:R})}}}),i.each(I,function(t){if(c.display&&(l.save(),l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.setLineDash&&(l.setLineDash(t.glBorderDash),l.lineDashOffset=t.glBorderDashOffset),l.beginPath(),c.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),c.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke(),l.restore()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=v.font,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var e=t.label;if(i.isArray(e))for(var a=0,n=0;a0)i=t.stepSize;else{var o=e.niceNum(a.max-a.min,!1);i=e.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(a.min/i)*i,s=Math.ceil(a.max/i)*i;t.min&&t.max&&t.stepSize&&e.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=e.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l),n.push(void 0!==t.min?t.min:r);for(var u=1;u3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}}}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){function e(e,a){var i=new t.Title({ctx:e.chart.ctx,options:a,chart:e});e.titleBlock=i,t.layoutService.addBox(e,i)}var a=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var i=a.noop;t.Title=t.Element.extend({initialize:function(t){var e=this;a.extend(e,t),e.legendHitBoxes=[]},beforeUpdate:i,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:i,beforeSetDimensions:i,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:i,beforeBuildLabels:i,buildLabels:i,afterBuildLabels:i,beforeFit:i,fit:function(){var e=this,i=a.getValueOrDefault,n=e.options,o=t.defaults.global,r=n.display,s=i(n.fontSize,o.defaultFontSize),l=e.minSize;e.isHorizontal()?(l.width=e.maxWidth,l.height=r?s+2*n.padding:0):(l.width=r?s+2*n.padding:0,l.height=e.maxHeight),e.width=l.width,e.height=l.height},afterFit:i,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var e=this,i=e.ctx,n=a.getValueOrDefault,o=e.options,r=t.defaults.global;if(o.display){var s,l,u,d=n(o.fontSize,r.defaultFontSize),c=n(o.fontStyle,r.defaultFontStyle),h=n(o.fontFamily,r.defaultFontFamily),f=a.fontString(d,c,h),g=0,p=e.top,m=e.left,v=e.bottom,b=e.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=f,e.isHorizontal()?(s=m+(b-m)/2,l=p+(v-p)/2,u=b-m):(s="left"===o.position?m+d/2:b-d/2,l=p+(v-p)/2,u=v-p,g=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0,u),i.restore()}}}),t.plugins.register({beforeInit:function(t){var a=t.options.title;a&&e(t,a)},beforeUpdate:function(i){var n=i.options.title;n?(n=a.configMerge(t.defaults.global.title,n),i.titleBlock?i.titleBlock.options=n:e(i,n)):(t.layoutService.removeBox(i,i.titleBlock),delete i.titleBlock)}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.color(t);return a.alpha(e*a.alpha()).rgbaString()}function a(t,e){return e&&(l.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n,x:t._model.x,y:t._model.y}}function n(e){var a=t.defaults.global,i=l.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,a.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,a.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,a.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,a.defaultFontStyle),titleFontSize:i(e.titleFontSize,a.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,_footerFontFamily:i(e.footerFontFamily,a.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,a.defaultFontStyle),footerFontSize:i(e.footerFontSize,a.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors}}function o(t,e){var a=t._chart.ctx,i=2*e.yPadding,n=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=s*d,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=r*c,i+=r?(r-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){n=Math.max(n,a.measureText(t).width+f)};return a.font=l.fontString(d,e._titleFontStyle,e._titleFontFamily),l.each(e.title,g),a.font=l.fontString(c,e._bodyFontStyle,e._bodyFontFamily),l.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,l.each(o,function(t){l.each(t.before,g),l.each(t.lines,g),l.each(t.after,g)}),f=0,a.font=l.fontString(h,e._footerFontStyle,e._footerFontFamily),l.each(e.footer,g),n+=2*e.xPadding,{width:n,height:i}}function r(t,e){var a=t._model,i=t._chart,n=t._chartInstance.chartArea,o="center",r="center";a.yi.height-e.height&&(r="bottom");var s,l,u,d,c,h=(n.left+n.right)/2,f=(n.top+n.bottom)/2;"center"===r?(s=function(t){return t<=h},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},s(a.x)?(o="left",u(a.x)&&(o="center",r=c(a.y))):l(a.x)&&(o="right",d(a.x)&&(o="center",r=c(a.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:r}}function s(t,e,a){var i=t.x,n=t.y,o=t.caretSize,r=t.caretPadding,s=t.cornerRadius,l=a.xAlign,u=a.yAlign,d=o+r,c=s+r;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?n+=d:n-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:n}}var l=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,callbacks:{beforeTitle:l.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.indexl;)o-=2*Math.PI;for(;o=s&&o<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,a=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var a=e._view;e._view.steppedLine===!0?(l.lineTo(a.x,t._view.y),l.lineTo(a.x,a.y)):0===e._view.tension?l.lineTo(a.x,a.y):l.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,a.controlPointPreviousX,a.controlPointPreviousY,a.x,a.y)}var i=this,n=i._view,o=n.spanGaps,r=n.scaleZero,s=i._loop;s||("top"===n.fill?r=n.scaleTop:"bottom"===n.fill&&(r=n.scaleBottom));var l=i._chart.ctx;l.save();var u=i._children.slice(),d=-1;s&&u.length&&u.push(u[0]);var c,h,f,g;if(u.length&&n.fill){for(l.beginPath(),c=0;ce?1:-1,r=1,s=u.borderSkipped||"left"):(e=u.x-u.width/2,a=u.x+u.width/2,i=u.y,n=u.base,o=1,r=n>i?1:-1,s=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-a),Math.abs(i-n));d=d>c?c:d;var h=d/2,f=e+("left"!==s?h*o:0),g=a+("right"!==s?-h*o:0),p=i+("top"!==s?h*r:0),m=n+("bottom"!==s?-h*r:0);f!==g&&(i=p,n=m),p!==m&&(e=f,a=g)}l.beginPath(),l.fillStyle=u.backgroundColor,l.strokeStyle=u.borderColor,l.lineWidth=d;var v=[[e,n],[e,i],[a,i],[a,n]],b=["bottom","left","top","right"],x=b.indexOf(s,0);x===-1&&(x=0);var y=t(0);l.moveTo(y[0],y[1]);for(var k=1;k<4;k++)y=t(k),l.lineTo(y[0],y[1]);l.fill(),d&&l.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=a(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,i){var n=this;if(!n._view)return!1;var o=!1,r=a(n);return o=e(n)?t>=r.left&&t<=r.right:i>=r.top&&i<=r.bottom},inXRange:function(t){var e=a(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=a(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,a,i=this._view;return e(this)?(t=i.x,a=(i.y+i.base)/2):(t=(i.x+i.base)/2,a=i.y),{x:t,y:a}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.getStyle(t,e),i=a&&a.match(/(\d+)px/);return i?Number(i[1]):void 0}function a(t,a){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t._chartjs={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=e(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(a.options.aspectRatio||2);else{var s=e(t,"height");void 0!==r&&(t.height=s)}return t}function i(t,e,a,i,n){return{type:t,chart:e,native:n||null,x:void 0!==a?a:null,y:void 0!==i?i:null}}function n(t,e){ 14 | var a=u[t.type]||t.type,n=l.getRelativePosition(t,e);return i(a,e,n.x,n.y,t)}function o(t){var e=document.createElement("iframe");return e.className="chartjs-hidden-iframe",e.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",e.tabIndex=-1,l.addEvent(e,"load",function(){l.addEvent(e.contentWindow||e,"resize",t),t()}),e}function r(t,e,a){var n=t._chartjs={ticking:!1},r=function(){n.ticking||(n.ticking=!0,l.requestAnimFrame.call(window,function(){if(n.resizer)return n.ticking=!1,e(i("resize",a))}))};n.resizer=o(r),t.insertBefore(n.resizer,t.firstChild)}function s(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}}var l=t.helpers,u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};return{acquireContext:function(t,e){if("string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t instanceof HTMLCanvasElement){var i=t.getContext&&t.getContext("2d");if(i instanceof CanvasRenderingContext2D)return a(t,e),i}return null},releaseContext:function(t){var e=t.canvas;if(e._chartjs){var a=e._chartjs.initial;["height","width"].forEach(function(t){var i=a[t];void 0===i||null===i?e.removeAttribute(t):e.setAttribute(t,i)}),l.each(a.style||{},function(t,a){e.style[a]=t}),e.width=e.width,delete e._chartjs}},addEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void r(i.parentNode,a,t.chart);var o=a._chartjs||(a._chartjs={}),s=o.proxies||(o.proxies={}),u=s[t.id+"_"+e]=function(e){a(n(e,t.chart))};l.addEvent(i,e,u)},removeEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void s(i.parentNode,a);var n=a._chartjs||{},o=n.proxies||{},r=o[t.id+"_"+e];r&&l.removeEvent(i,e,r)}}}},{}],42:[function(t,e,a){"use strict";var i=t(41);e.exports=function(t){t.platform={acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},t.helpers.extend(t.platform,i(t))}},{41:41}],43:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,a=t.getLabels();t.minIndex=0,t.maxIndex=a.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(a,t.options.ticks.min),t.minIndex=i!==-1?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(a,t.options.ticks.max),t.maxIndex=i!==-1?i:t.maxIndex),t.min=a[t.minIndex],t.max=a[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var a=this,i=a.chart.data,n=a.isHorizontal();return i.yLabels&&!n?a.getRightValue(i.datasets[e].data[t]):a.ticks[t-a.minIndex]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&isNaN(e)){var r=n.getLabels(),s=r.indexOf(t);e=s!==-1?s:e}if(n.isHorizontal()){var l=n.width/o,u=l*(e-n.minIndex);return(n.options.gridLines.offsetGridLines&&i||n.maxIndex===n.minIndex&&i)&&(u+=l/2),n.left+Math.round(u)}var d=n.height/o,c=d*(e-n.minIndex);return n.options.gridLines.offsetGridLines&&i&&(c+=d/2),n.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=(n?a.width:a.height)/i;return t-=n?a.left:a.top,a.options.gridLines.offsetGridLines&&(t-=o/2),e=t<=0?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,a)}},{}],44:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=a.chart,o=n.data,r=o.datasets,s=a.isHorizontal();a.min=null,a.max=null;var l=i.stacked;if(void 0===l&&e.each(r,function(e,a){if(!l){var i=n.getDatasetMeta(a);n.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(l=!0)}}),i.stacked||l){var u={};e.each(r,function(o,r){var s=n.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");void 0===u[l]&&(u[l]={positiveValues:[],negativeValues:[]});var d=u[l].positiveValues,c=u[l].negativeValues;n.isDatasetVisible(r)&&t(s)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||s.data[e].hidden||(d[e]=d[e]||0,c[e]=c[e]||0,i.relativePoints?d[e]=100:n<0?c[e]+=n:d[e]+=n)})}),e.each(u,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:ia.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,a=this,i=a.start,n=+a.getRightValue(t),o=a.end-i;return a.isHorizontal()?(e=a.left+a.width/o*(n-i),Math.round(e)):(e=a.bottom-a.height/o*(n-i),Math.round(e))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=a?e.width:e.height,n=(a?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*n},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,a)}},{}],45:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);n<0&&o<0?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var a=this,i=a.options,n=i.ticks,o=a.getTickLimit();o=Math.max(2,o);var r={maxTicks:o,min:n.min,max:n.max,stepSize:e.getValueOrDefault(n.fixedStepSize,n.stepSize)},s=a.ticks=t.Ticks.generators.linear(r,a);a.handleDirectionalChanges(),a.max=e.max(s),a.min=e.min(s),n.reverse?(s.reverse(),a.start=a.max,a.end=a.min):(a.start=a.min,a.end=a.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],46:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,s=r.datasets,l=e.getValueOrDefault,u=a.isHorizontal();a.min=null,a.max=null,a.minNotZero=null;var d=i.stacked;if(void 0===d&&e.each(s,function(e,a){if(!d){var i=o.getDatasetMeta(a);o.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(s,function(n,r){var s=o.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");o.isDatasetVisible(r)&&t(s)&&(void 0===c[l]&&(c[l]=[]),e.each(n.data,function(t,e){var n=c[l],o=+a.getRightValue(t);isNaN(o)||s.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(c,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(s,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:ia.max&&(a.max=i),0!==i&&(null===a.minNotZero||in?{start:e-a-5,end:e}:{start:e,end:e+a+5}}function o(t){var o,r,s,l=a(t),u=Math.min(t.height/2,t.width/2),d={l:t.width,r:0,t:t.height,b:0},c={};t.ctx.font=l.font,t._pointLabelSizes=[];var h=e(t);for(o=0;od.r&&(d.r=m.end,c.r=g),v.startd.b&&(d.b=v.end,c.b=g)}t.setReductions(u,d,c)}function r(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function s(t){return 0===t||180===t?"center":t<180?"left":"right"}function l(t,e,a,i){if(f.isArray(e))for(var n=a.y,o=1.5*i,r=0;r270||t<90)&&(a.y-=e.h)}function d(t){var i=t.ctx,n=f.getValueOrDefault,o=t.options,r=o.angleLines,d=o.pointLabels;i.lineWidth=r.lineWidth,i.strokeStyle=r.color;var c=t.getDistanceFromCenterForValue(o.reverse?t.min:t.max),h=a(t);i.textBaseline="top";for(var p=e(t)-1;p>=0;p--){if(r.display){var m=t.getPointPosition(p,c);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}var v=t.getPointPosition(p,c+5),b=n(d.fontColor,g.defaultFontColor);i.font=h.font,i.fillStyle=b;var x=t.getIndexAngle(p),y=f.toDegrees(x);i.textAlign=s(y),u(y,t._pointLabelSizes[p],v),l(i,t.pointLabels[p]||"",v,h.size)}}function c(t,a,i,n){var o=t.ctx;if(o.strokeStyle=f.getValueAtIndexOrDefault(a.color,n-1),o.lineWidth=f.getValueAtIndexOrDefault(a.lineWidth,n-1),t.options.lineArc)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var r=e(t);if(0===r)return;o.beginPath();var s=t.getPointPosition(0,i);o.moveTo(s.x,s.y);for(var l=1;l0&&a>0?e:0)},draw:function(){var t=this,e=t.options,a=e.gridLines,i=e.ticks,n=f.getValueOrDefault;if(e.display){var o=t.ctx,r=n(i.fontSize,g.defaultFontSize),s=n(i.fontStyle,g.defaultFontStyle),l=n(i.fontFamily,g.defaultFontFamily),u=f.fontString(r,s,l);f.each(t.ticks,function(s,l){if(l>0||e.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-d;if(a.display&&0!==l&&c(t,a,d,l),i.display){var f=n(i.fontColor,g.defaultFontColor);if(o.font=u,i.showLabelBackdrop){var p=o.measureText(s).width;o.fillStyle=i.backdropColor,o.fillRect(t.xCenter-p/2-i.backdropPaddingX,h-r/2-i.backdropPaddingY,p+2*i.backdropPaddingX,r+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=f,o.fillText(s,t.xCenter,h)}}}),e.lineArc||d(t)}}});t.scaleService.registerScaleType("radialLinear",m,p)}},{}],48:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return null===t||null===e?null:"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getLabelDiff:function(t,e){var a=this;return null===t||null===e?null:(void 0===a.labelDiffs&&a.buildLabelDiffs(),"undefined"!=typeof a.labelDiffs[t]?a.labelDiffs[t][e]:null)},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],s=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),r.push(a),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildLabelDiffs:function(){var t=this;t.labelDiffs=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0&&e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i.diff(t.firstTick,t.tickUnit,!0)))},t),e.each(t.chart.data.datasets,function(i){var n=[];"object"==typeof i.data[0]&&null!==i.data[0]?e.each(i.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),n.push(a.diff(t.firstTick,t.tickUnit,!0)))},t):n=a,t.labelDiffs.push(n)},t)},buildTicks:function(){var i=this;i.ctx.save();var n=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(n,o,r);if(i.ctx.font=s,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var l=i.isHorizontal()?i.width:i.height,u=i.tickFormatFunction(i.firstTick,0,[]),d=i.ctx.measureText(u).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));d=d*c+n*h;var f=l/d;i.tickUnit=i.options.time.minUnit,i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,p=a.units[g];g=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,p.steps[m]);break}break}if(p.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)=0&&(i.lastTick=y),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var S=i.unitScale;S<=i.scaleSizeInUnits;S+=i.unitScale){var M=x.clone().add(S,i.tickUnit);if(i.options.time.max&&M.diff(i.lastTick,i.tickUnit,!0)>=0)break;i.ticks.push(M)}var w=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);0===w&&0!==i.scaleSizeInUnits||(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore(),i.labelDiffs=void 0},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t