├── 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 | [](https://travis-ci.org/chartjs/Chart.js) [](https://codeclimate.com/github/nnnick/Chart.js) [](https://coveralls.io/github/chartjs/Chart.js?branch=master)
4 |
5 | [](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 | [](https://www.repostatus.org/#unsupported)
4 | [](https://travis-ci.org/MangoTheCat/radarchart) [](https://ci.appveyor.com/project/MangoTheCat/radarchart) [](http://www.r-pkg.org/pkg/radarchart)
5 | [](https://codecov.io/gh/MangoTheCat/radarchart)
6 | [](http://www.r-pkg.org/pkg/radarchart)
7 | [](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 |
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 |
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 |
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