Update libraries

This commit is contained in:
christianesperar 2016-05-04 23:40:49 +08:00
parent 868a8e86b5
commit 30814a1aab
138 changed files with 9864 additions and 9319 deletions

View file

@ -1611,10 +1611,6 @@
rating: 4
});
$('.starrr').on('click', function (e) {
e.preventDefault();
});
$('.stars').on('starrr:change', function (e, value) {
$('.stars-count').html(value);
});

View file

@ -1,23 +1,23 @@
{
"name": "Chart.js",
"version": "2.0.2",
"version": "2.1.0",
"description": "Simple HTML5 Charts using the canvas element",
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"license": "MIT",
"main": [
"dist/Chart.js"
],
"devDependencies": {
"jquery": "~2.1.4"
},
"_release": "2.0.2",
"_release": "2.1.0",
"_resolution": {
"type": "version",
"tag": "2.0.2",
"commit": "67625063a3c1242ca13858aa629668007b5b8106"
"tag": "2.1.0",
"commit": "2ee37e12e379ca9b8ad3be7105715bf8c543ead0"
},
"_source": "https://github.com/nnnick/Chart.js.git",
"_target": "^2.0.2",
"_originalSource": "Chart.js",
"_direct": true
"_originalSource": "Chart.js"
}

View file

@ -1,4 +1,3 @@
---
engines:
duplication:
enabled: true
@ -11,9 +10,9 @@ engines:
enabled: true
ratings:
paths:
- "**.js"
- "src/**/*.js"
exclude_paths:
- dist/
- node_modules/
- test/
- coverage/
- dist/**/*
- node_modules/**/*
- test/**/*
- coverage/**/*

View file

@ -1,7 +1,6 @@
language: node_js
node_js:
- "5.6"
- "4.3"
- "5.10"
before_install:
- "export CHROME_BIN=/usr/bin/google-chrome"

View file

@ -7,9 +7,9 @@ Contributions to Chart.js are welcome and encouraged, but please have a look thr
Using issues
------------
The [issue tracker](https://github.com/nnnick/Chart.js/issues) is the preferred channel for reporting bugs, requesting new features and submitting pull requests.
The [issue tracker](https://github.com/chartjs/Chart.js/issues) is the preferred channel for reporting bugs, requesting new features and submitting pull requests.
If you're suggesting a new chart type, please take a look at [writing new chart types](https://github.com/nnnick/Chart.js/blob/master/docs/06-Advanced.md#writing-new-chart-types) in the documentation, and some of the [community extensions](https://github.com/nnnick/Chart.js/blob/master/docs/06-Advanced.md#community-extensions) that have been created already.
If you're suggesting a new chart type, please take a look at [writing new chart types](https://github.com/chartjs/Chart.js/blob/master/docs/07-Advanced.md#writing-new-chart-types) in the documentation or consider [creating a plugin](https://github.com/chartjs/Chart.js/blob/master/docs/07-Advanced.md#creating-plugins).
To keep the library lightweight for everyone, it's unlikely we'll add many more chart types to the core of Chart.js, but issues are a good medium to design and spec out how new chart types could work and look.
@ -41,21 +41,24 @@ Pull requests
Clear, concise pull requests are excellent at continuing the project's community driven growth. But please review [these guidelines](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) and the guidelines below before starting work on the project.
Guidlines:
Be advised that **Chart.js 1.0.2 is in feature-complete status**. Pull requests adding new features to the 1.x branch will be disregarded.
Guidelines:
- Please create an issue first:
- For bugs, we can discuss the fixing approach
- For enhancements, we can discuss if it is within the project scope and avoid duplicate effort
- Please make changes to the files in [`/src`](https://github.com/nnnick/Chart.js/tree/master/src), not `Chart.js` or `Chart.min.js` in the repo root directory, this avoids merge conflicts
- Please make changes to the files in [`/src`](https://github.com/chartjs/Chart.js/tree/master/src), not `Chart.js` or `Chart.min.js` in the repo root directory, this avoids merge conflicts
- Tabs for indentation, not spaces please
- If adding new functionality, please also update the relevant `.md` file in [`/docs`](https://github.com/nnnick/Chart.js/tree/master/docs)
- If adding new functionality, please also update the relevant `.md` file in [`/docs`](https://github.com/chartjs/Chart.js/tree/master/docs)
- Please make your commits in logical sections with clear commit messages
Joining the Project
Joining the project
-------------
- Active committers and contributors are invited to introduce yourself and request commit access to this project. Please send an email to hello@nickdownie.com or file an issue.
- Active committers and contributors are invited to introduce yourself and request commit access to this project. Please send an email to hello@nickdownie.com or file an issue.
- We have a very active Slack community that you can join at https://chartjs-slack-automation.herokuapp.com. If you think you can help, we'd love to have you!
License
-------
By contributing your code, you agree to license your contribution under the [MIT license](https://github.com/nnnick/Chart.js/blob/master/LICENSE.md).
By contributing your code, you agree to license your contribution under the [MIT license](https://github.com/chartjs/Chart.js/blob/master/LICENSE.md).

View file

@ -1,4 +1,5 @@
Copyright (c) 2013-2015 Nick Downie
The MIT License (MIT)
Copyright (c) 2013-2016 Nick Downie
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:

View file

@ -1,45 +1,36 @@
# Chart.js
[![Build Status](https://travis-ci.org/nnnick/Chart.js.svg?branch=v2.0-dev)](https://travis-ci.org/nnnick/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js)[![Coverage Status](https://coveralls.io/repos/nnnick/Chart.js/badge.svg?branch=v2.0-dev)](https://coveralls.io/r/nnnick/Chart.js?branch=v2.0-dev)
# Chart.js
[![Build Status](https://travis-ci.org/chartjs/Chart.js.svg?branch=master)](https://travis-ci.org/chartjs/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js) [![Coverage Status](https://coveralls.io/repos/github/chartjs/Chart.js/badge.svg?branch=master)](https://coveralls.io/github/chartjs/Chart.js?branch=master)
[![Chart.js on Slack](https://img.shields.io/badge/slack-Chart.js-blue.svg)](https://chartjs-slack-automation.herokuapp.com/)
*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)
## v2.0 Beta
## Installation
Current Release: [2.0.0-beta2](https://github.com/nnnick/Chart.js/releases/tag/2.0.0-beta2)
To download a zip, go to the Chart.js on Github
The next generation and release of Chart.js has been well under way this year and we are very close to releasing some amazing new features including, but not limited to:
- Rewritten, optimized, and unit-tested
- New and improved scales (log, time, linear, category, multiple scales)
- Improved responsiveness and resizing
- Powerful support for adding, removing, changing, and updating data on the fly
- Animations on all elements, colors and tooltips
- Powerful customization when you need it. Automatic and dynamic when you don't.
- Excellent support for modern frameworks and modular build systems.
- Even more extensible via new element controllers, combo chart support, and hook system
- Bug fixes not addressed in 1.x, and much, much more...
To install via npm / bower:
#####Contributing to 2.0
Submit PR's to the v2.0-dev branch.
#####Building and Testing
`gulp build`, `gulp test`
## v1.x Status: Feature Complete
We are now treating v1.x as feature complete. PR's for bug fixes are welcome, but we urge any open PR's for v1.x features to be refactored and resubmitted for v2.x (if the feature has not already been implemented).
```bash
npm install chart.js --save
bower install Chart.js --save
```
CDN: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0/Chart.js
## Documentation
You can find documentation at [chartjs.org/docs](http://www.chartjs.org/docs/). The markdown files that build the site are available under `/docs`. Please note - in some of the json examples of configuration you might notice some liquid tags - this is just for the generating the site html, please disregard.
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).
## Bugs, issues and contributing
## Contributing
Before submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](https://github.com/nnnick/Chart.js/blob/master/CONTRIBUTING.md) first.
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.
For support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/chartjs).
## Building and Testing
`gulp build`, `gulp test`
## License
Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT).

View file

@ -1,9 +1,10 @@
{
"name": "Chart.js",
"version": "2.0.2",
"version": "2.1.0",
"description": "Simple HTML5 Charts using the canvas element",
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"license": "MIT",
"main": [
"dist/Chart.js"
],

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -5,9 +5,9 @@ anchor: getting-started
### Download Chart.js
To download a zip, go to [Chart.js on Github](https://github.com/nnnick/Chart.js) and choose the version that is right for your application.
* [Standard build](https://raw.githubusercontent.com/nnnick/Chart.js/v2.0-dev/dist/Chart.js) (~31kB gzipped)
* [Bundled with Moment.js](https://raw.githubusercontent.com/nnnick/Chart.js/v2.0-dev/dist/Chart.bundle.js) (~45kB gzipped)
To download a zip, go to [Chart.js on Github](https://github.com/chartjs/Chart.js) and choose the version that is right for your application.
* [Standard build](https://raw.githubusercontent.com/chartjs/Chart.js/v2.0-dev/dist/Chart.js) (~31kB gzipped)
* [Bundled with Moment.js](https://raw.githubusercontent.com/chartjs/Chart.js/v2.0-dev/dist/Chart.bundle.js) (~45kB gzipped)
* [CDN Versions](https://cdnjs.com/libraries/Chart.js)
To install via npm / bower:
@ -110,7 +110,7 @@ responsive | Boolean | true | Resizes when the canvas container does.
responsiveAnimationDuration | Number | 0 | Duration in milliseconds it takes to animate to new size after a resize event.
maintainAspectRatio | Boolean | true | Maintain the original canvas aspect ratio `(width / height)` when resizing
events | Array[String] | `["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]` | Events that the chart should listen to for tooltips and hovering
hover |-|-|-
hover |Object|-|-
*hover*.onHover | Function | null | Called when any of the events fire. Called in the context of the chart and passed an array of active elements (bars, points, etc)
*hover*.mode | String | 'single' | Sets which elements hover. Acceptable options are `'single'`, `'label'`, or `'dataset'`. `single` highlights the closest element. `label` highlights elements in all datasets at the same `X` value. `dataset` highlights the closest dataset.
*hover*.animationDuration | Number | 400 | Duration in milliseconds it takes to animate hover style changes
@ -126,7 +126,7 @@ The global options for the chart title is defined in `Chart.defaults.global.titl
Name | Type | Default | Description
--- | --- | --- | ---
display | Boolean | true | Show the title block
display | Boolean | false | Show the title block
position | String | 'top' | Position of the title. 'top' or 'bottom' are allowed
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
fontColor | Color | '#666' | Text color
@ -144,14 +144,14 @@ display | Boolean | true | Is the legend displayed
position | String | 'top' | Position of the legend. Options are 'top' or 'bottom'
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
onClick | Function | `function(event, legendItem) {}` | A callback that is called when a click is registered on top of a label item
labels |-|-|-
*labels*boxWidth | Number | 40 | Width of coloured box
*labels*fontSize | Number | 12 | Font size
*labels*fontStyle | String | "normal" |
*labels*fontColor | Color | "#666" |
*labels*fontFamily | String | "Helvetica Neue" |
*labels*padding | Number | 10 | Padding between rows of colored boxes
*labels*generateLabels: | Function | `function(data) { }` | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. Styles that can be returned are `fillStyle`, `strokeStyle`, `lineCap`, `lineDash`, `lineDashOffset`, `lineWidth`, `lineJoin`. Return a `hidden` attribute to indicate that the label refers to something that is not visible. A strikethrough style will be given to the text in this case.
labels |Object|-|-
*labels*.boxWidth | Number | 40 | Width of coloured box
*labels*.fontSize | Number | 12 | Font size
*labels*.fontStyle | String | "normal" |
*labels*.fontColor | Color | "#666" |
*labels*.fontFamily | String | "Helvetica Neue" |
*labels*.padding | Number | 10 | Padding between rows of colored boxes
*labels*.generateLabels: | Function | `function(data) { }` | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. Styles that can be returned are `fillStyle`, `strokeStyle`, `lineCap`, `lineDash`, `lineDashOffset`, `lineWidth`, `lineJoin`. Return a `hidden` attribute to indicate that the label refers to something that is not visible. A strikethrough style will be given to the text in this case.
The global options for tooltips are defined in `Chart.defaults.global.tooltips`.
@ -177,7 +177,7 @@ caretSize | Number | 5 | Size, in px, of the tooltip arrow
cornerRadius | Number | 6 | Radius of tooltip corner curves
multiKeyBackground | Color | "#fff" | Color to draw behind the colored boxes when multiple items are in the tooltip
| | |
callbacks | - | - | V2.0 introduces callback functions as a replacement for the template engine in v1. The tooltip has the following callbacks for providing text. For all functions, 'this' will be the tooltip object create from the Chart.Tooltip constructor
callbacks | Object | - | V2.0 introduces callback functions as a replacement for the template engine in v1. The tooltip has the following callbacks for providing text. For all functions, 'this' will be the tooltip object create from the Chart.Tooltip constructor
**Callback Functions** | | | All functions are called with the same arguments
xLabel | String or Array[Strings] | | This is the xDataValue for each item to be displayed in the tooltip
yLabel | String or Array[Strings] | | This is the yDataValue for each item to be displayed in the tooltip
@ -210,12 +210,12 @@ The global options for elements are defined in `Chart.defaults.global.elements`.
Name | Type | Default | Description
--- |:---:| --- | ---
arc | - | - | -
arc | Object | - | -
*arc*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default fill color for arcs
*arc*.borderColor | Color | "#fff" | Default stroke color for arcs
*arc*.borderWidth | Number | 2 | Default stroke width for arcs
line | - | - | -
*line*.tension | Number | 0.4 | Default bezier curve tension. Set to `0` for no bezier curves.
line | Object | - | -
*line*.lineTension | Number | 0.4 | Default bezier curve tension. Set to `0` for no bezier curves.
*line*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default line fill color
*line*.borderWidth | Number | 3 | Default line stroke width
*line*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default line stroke color
@ -224,7 +224,7 @@ line | - | - | -
*line*.borderDashOffset | Number | 0.0 | Default line dash offset. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
*line*.borderJoinStyle | String | 'miter' | Default line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
*line*.fill | Boolean | true |
point | - | - | -
point | Object | - | -
*point*.radius | Number | 3 | Default point radius
*point*.pointStyle | String | 'circle' | Default point style
*point*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default point fill color
@ -233,7 +233,7 @@ point | - | - | -
*point*.hitRadius | Number | 1 | Extra radius added to point radius for hit detection
*point*.hoverRadius | Number | 4 | Default point radius when hovered
*point*.hoverBorderWidth | Number | 1 | Default stroke width when hovered
rectangle | - | - | -
rectangle | Object | - | -
*rectangle*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default bar fill color
*rectangle*.borderWidth | Number | 0 | Default bar stroke width
*rectangle*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default bar stroke color
@ -246,3 +246,30 @@ Chart.defaults.global.responsive = true;
```
Now, every time we create a chart, `options.responsive` will be `true`.
### Colors
When supplying colors to Chart options, you can use a number of formats. You can specify the color as a string in hexadecimal, RGB, or HSL notations.
You can also pass a [CanvasGradient](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient) object. You will need to create this before passing to the chart, but using it you can achieve some interesting effects.
The final option is to pass a [CanvasPattern](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern) object. For example, if you wanted to fill a dataset with a pattern from an image you could do the following.
```javascript
var img = new Image();
img.src = 'https://example.com/my_image.png';
img.onload = function() {
var ctx = document.getElementById('canvas').getContext('2d');
var fillPattern = ctx.CreatePattern(img, 'repeat');
var chart = new Chart(ctx, {
data: {
labels: ['Item 1', 'Item 2', 'Item 3'],
datasets: [{
data: [10, 20, 30],
backgroundColor: fillPattern
}]
}
})
}
```

View file

@ -15,6 +15,7 @@ Name | Type | Default | Description
--- |:---:| --- | ---
type | String | Chart specific. | Type of scale being employed. Custom scales can be created and registered with a string key. Options: ["category"](#scales-category-scale), ["linear"](#scales-linear-scale), ["logarithmic"](#scales-logarithmic-scale), ["time"](#scales-time-scale), ["radialLinear"](#scales-radial-linear-scale)
display | Boolean | true | If true, show the scale including gridlines, ticks, and labels. Overrides *gridLines.display*, *scaleLabel.display*, and *ticks.display*.
position | String | "left" | Position of the scale. Possible values are top, left, bottom and right.
beforeUpdate | Function | undefined | Callback called before the update process starts. Passed a single argument, the scale instance.
beforeSetDimensions | Function | undefined | Callback that runs before dimensions are set. Passed a single argument, the scale instance.
afterSetDimensions | Function | undefined | Callback that runs after dimensions are set. Passed a single argument, the scale instance.
@ -29,23 +30,24 @@ afterCalculateTickRotation | Function | undefined | Callback that runs after tic
beforeFit | Function | undefined | Callback that runs before the scale fits to the canvas. Passed a single argument, the scale instance.
afterFit | Function | undefined | Callback that runs after the scale fits to the canvas. Passed a single argument, the scale instance.
afterUpdate | Function | undefined | Callback that runs at the end of the update process. Passed a single argument, the scale instance.
**gridLines** | Array | - | Options for the grid lines that run perpendicular to the axis.
**gridLines** | Object | - | Options for the grid lines that run perpendicular to the axis.
*gridLines*.display | Boolean | true |
*gridLines*.color | Color | "rgba(0, 0, 0, 0.1)" | Color of the grid lines.
*gridLines*.lineWidth | Number | 1 | Stroke width of grid lines
*gridLines*.drawOnChartArea | Boolean | true | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn
*gridLines*.drawTicks | Boolean | true | If true, draw lines beside the ticks in the axis area beside the chart.
*gridLines*.tickMarkLength | Number | 10 | Length in pixels that the grid lines will draw into the axis area.
*gridLines*.zeroLineWidth | Number | 1 | Stroke width of the grid line for the first index (index 0).
*gridLines*.zeroLineColor | Color | "rgba(0, 0, 0, 0.25)" | Stroke color of the grid line for the first index (index 0).
*gridLines*.offsetGridLines | Boolean | false | If true, offset labels from grid lines.
**scaleLabel** | Array | | Title for the entire axis.
**scaleLabel** | Object | | Title for the entire axis.
*scaleLabel*.display | Boolean | false |
*scaleLabel*.labelString | String | "" | The text for the title. (i.e. "# of People", "Response Choices")
*scaleLabel*.fontColor | Color | "#666" | Font color for the scale title.
*scaleLabel*.fontFamily| String | "Helvetica Neue" | Font family for the scale title, follows CSS font-family options.
*scaleLabel*.fontSize | Number | 12 | Font size for the scale title.
*scaleLabel*.fontStyle | String | "normal" | Font style for the scale title, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
**ticks** | Array | | Settings for the labels that run along the axis.
**ticks** | Object | | Settings for the labels that run along the axis.
*ticks*.beginAtZero | Boolean | false | If true the scale will be begin at 0, if false the ticks will begin at your smallest data value.
*ticks*.fontColor | Color | "#666" | Font color for the tick labels.
*ticks*.fontFamily | String | "Helvetica Neue" | Font family for the tick labels, follows CSS font-family options.

View file

@ -29,82 +29,61 @@ var myLineChart = Chart.Line(ctx, {
```
### Data structure
The following options can be included in a line chart dataset to configure options for that specific dataset.
All point* properties can be specified as an array. If these are set to an array value, the first value applies to the first point, the second value to the second point, and so on.
Property | Type | Usage
--- | --- | ---
data | `Array<Number>` | The data to plot in a line
label | `String` | The label for the dataset which appears in the legend and tooltips
xAxisID | `String` | The ID of the x axis to plot this dataset on
yAxisID | `String` | The ID of the y axis to plot this dataset on
fill | `Boolean` | If true, fill the area under the line
lineTension | `Number` | Bezier curve tension of the line. Set to 0 to draw straightlines. *Note* This was renamed from 'tension' but the old name still works.
backgroundColor | `Color` | The fill color under the line. See [Colors](#getting-started-colors)
borderWidth | `Number` | The width of the line in pixels
borderColor | `Color` | The color of the line.
borderCapStyle | `String` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)
borderDash | `Array<Number>` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)
borderDashOffset | `Number` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
borderJoinStyle | `String` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
pointBorderColor | `Color or Array<Color>` | The border color for points.
pointBackgroundColor | `Color or Array<Color>` | The fill color for points
pointBorderWidth | `Number or Array<Number>` | The width of the point border in pixels
pointRadius | `Number or Array<Number>` | The radius of the point shape. If set to 0, nothing is rendered.
pointHoverRadius | `Number or Array<Number>` | The radius of the point when hovered
pointHitRadius | `Number or Array<Number>` | The pixel size of the non-displayed point that reacts to mouse events
pointHoverBackgroundColor | `Color or Array<Color>` | Point background color when hovered
pointHoverBorderColor | `Color or Array<Color>` | Point border color when hovered
pointHoverBorderWidth | `Number or Array<Number>` | Border width of point when hovered
pointStyle | `String or Array<String>` | The style of point. Options include 'circle', 'triangle', 'rect', 'rectRot', 'cross', 'crossRot', 'star', 'line', and 'dash'
An example data object using these attributes is shown below.
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
// Boolean - if true fill the area under the line
fill: false,
// String - the color to fill the area under the line with if fill is true
backgroundColor: "rgba(220,220,220,0.2)",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - Line color
borderColor: "rgba(220,220,220,1)",
// String - cap style of the line. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap
lineTension: 0.1,
backgroundColor: "rgba(75,192,192,0.4)",
borderColor: "rgba(75,192,192,1)",
borderCapStyle: 'butt',
// Array - Length and spacing of dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash
borderDash: [],
// Number - Offset for line dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
borderDashOffset: 0.0,
// String - line join style. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin
borderJoinStyle: 'miter',
// String or array - Point stroke color
pointBorderColor: "rgba(220,220,220,1)",
// String or array - Point fill color
pointBorderColor: "rgba(75,192,192,1)",
pointBackgroundColor: "#fff",
// Number or array - Stroke width of point border
pointBorderWidth: 1,
// Number or array - Radius of point when hovered
pointHoverRadius: 5,
// String or array - point background color when hovered
pointHoverBackgroundColor: "rgba(220,220,220,1)",
// Point border color when hovered
pointHoverBackgroundColor: "rgba(75,192,192,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
// Number or array - border width of point when hovered
pointHoverBorderWidth: 2,
// Tension - bezier curve tension of the line. Set to 0 to draw straight Wlines connecting points
tension: 0.1,
// Number - the pixel size of the point shape. Can be set to 0 to not render a circle over the point
radius: 1,
// The actual data
pointRadius: 1,
pointHitRadius: 10,
data: [65, 59, 80, 81, 56, 55, 40],
// String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used. First id is y-axis-0
yAxisID: "y-axis-0",
},
{
label: "My Second dataset",
fill: false,
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBorderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(220,220,220,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
@ -119,26 +98,26 @@ The label key on each dataset is optional, and can be used when generating a sca
These are the customisation options specific to Line charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for line chart are defined in `Chart.defaults.Line`.
The default options for line chart are defined in `Chart.defaults.line`.
Name | Type | Default | Description
--- | --- | --- | ---
showLines | Boolean | true | If false, the lines between points are not drawn
stacked | Boolean | false | If true, lines stack on top of each other along the y axis.
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
elements | - | - | -
*elements*.point | - | - | -
elements | Object | - | -
*elements*.point | Object | - | -
*elements.point*.radius | Number | `3` | Defines the size of the Point shape. Can be set to zero to skip rendering a point.
scales | - | - | -
*scales*.xAxes | Array | `[{type:"category","id":"x-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
scales | Object | - | -
*scales*.xAxes | Array | `[{type:"category","id":"x-axis-0"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#scales) for details on the available options.
*Options for xAxes* | | |
type | String | "category" | As defined in ["Category"](#scales-category-scale).
id | String | "x-axis-1" | Id of the axis so that data can bind to it.
id | String | "x-axis-0" | Id of the axis so that data can bind to it.
| | |
*scales*.yAxes | Array | `[{type:"linear","id":"y-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
*scales*.yAxes | Array | `[{type:"linear","id":"y-axis-0"}]` | Defines all of the y axes used in the chart. See the [scale documentation](#scales) for details on the available options.
*Options for yAxes* | | |
type | String | "linear" | As defined in ["Linear"](#scales-linear-scale).
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
id | String | "y-axis-0" | Id of the axis so that data can bind to it.
You can override these for your `Chart` instance by passing a member `options` into the `Line` method.

View file

@ -21,7 +21,36 @@ var myBarChart = new Chart(ctx, {
});
```
Or if you want horizontal bars.
```javascript
var myBarChart = new Chart(ctx, {
type: 'horizontalBar',
data: data,
options: options
});
```
### Data structure
The following options can be included in a bar chart dataset to configure options for that specific dataset.
Some properties can be specified as an array. If these are set to an array value, the first value applies to the first bar, the second value to the second bar, and so on.
Property | Type | Usage
--- | --- | ---
data | `Array<Number>` | The data to plot as bars
label | `String` | The label for the dataset which appears in the legend and tooltips
xAxisID | `String` | The ID of the x axis to plot this dataset on
yAxisID | `String` | The ID of the y axis to plot this dataset on
backgroundColor | `Color or Array<Color>` | The fill color of the bars. See [Colors](#getting-started-colors)
borderColor | `Color or Array<Color>` | Bar border color
borderWidth | `Number or Array<Number>` | Border width of bar in pixels
borderSkipped | `String or Array<String>` | Which edge to skip drawing the border for. Options are 'bottom', 'left', 'top', and 'right'
hoverBackgroundColor | `Color or Array<Color>` | Bar background color when hovered
hoverBorderColor | `Color or Array<Color>` | Bar border color when hovered
hoverBorderWidth | `Number or Array<Number>` | Border width of bar when hovered
An example data object using these attributes is shown below.
```javascript
var data = {
@ -29,79 +58,45 @@ var data = {
datasets: [
{
label: "My First dataset",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - the bar color
backgroundColor: "rgba(220,220,220,0.2)",
// String or array - bar stroke color
borderColor: "rgba(220,220,220,1)",
// Number or array - bar border width
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 1,
// String or array - fill color when hovered
hoverBackgroundColor: "rgba(220,220,220,0.2)",
// String or array - border color when hovered
hoverBorderColor: "rgba(220,220,220,1)",
// The actual data
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 80, 81, 56, 55, 40],
// String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used.
yAxisID: "y-axis-0",
},
{
label: "My Second dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
borderWidth: 1,
hoverBackgroundColor: "rgba(220,220,220,0.2)",
hoverBorderColor: "rgba(220,220,220,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data.
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for bar chart are defined in `Chart.defaults.Bar`.
The default options for bar chart are defined in `Chart.defaults.bar`.
Name | Type | Default | Description
--- |:---:| --- | ---
stacked | Boolean | false |
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
scales | Array | - | -
scales | Object | - | -
*scales*.xAxes | Array | | The bar chart officially supports only 1 x-axis but uses an array to keep the API consistent. Use a scatter chart if you need multiple x axes.
*Options for xAxes* | | |
type | String | "Category" | As defined in [Scales](#scales-category-scale).
display | Boolean | true | If true, show the scale.
position | String | "bottom" | Position of the scale. Options are "top" and "bottom" for dataset scales.
id | String | "x-axis-1" | Id of the axis so that data can bind to it
categoryPercentage | Number | 0.8 | Percent (0-1) of the available width (the space between the gridlines for small datasets) for each data-point to use for the bars. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
barPercentage | Number | 0.9 | Percent (0-1) of the available width each bar should be within the category percentage. 1.0 will take the whole category width and put the bars right next to each other. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
gridLines | Array | [See Scales](#scales) |
gridLines | Object | [See Scales](#scales) |
*gridLines*.offsetGridLines | Boolean | true | If true, the bars for a particular data point fall between the grid lines. If false, the grid line will go right down the middle of the bars.
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
| | |
*scales*.yAxes | Array | `[{ type: "linear" }]` |
*Options for xAxes* | | |
type | String | "linear" | As defined in [Scales](#scales-linear-scale).
display | Boolean | true | If true, show the scale.
position | String | "left" | Position of the scale. Options are "left" and "right" for dataset scales.
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
gridLines | Array | [See Scales](#scales) |
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override.
@ -128,9 +123,18 @@ new Chart(ctx, {
// for both x and y axes.
```
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.bar`. For horizontal bars, this object is available at `Chart.defaults.horizontalBar`.
#### barPercentage vs categoryPercentage
The default options for horizontal bar charts are defined in `Chart.defaults.horizontalBar` and are same as those of the bar chart, but with `xAxes` and `yAxes` swapped and the following additional options.
Name | Type | Default | Description
--- |:---:| --- | ---
*Options for xAxes* | | |
position | String | "bottom" |
*Options for yAxes* | | |
position | String | "left" |
### barPercentage vs categoryPercentage
The following shows the relationship between the bar percentage option and the category percentage option.

View file

@ -23,28 +23,59 @@ var myRadarChart = new Chart(ctx, {
```
### Data structure
The following options can be included in a radar chart dataset to configure options for that specific dataset.
All point* properties can be specified as an array. If these are set to an array value, the first value applies to the first point, the second value to the second point, and so on.
Property | Type | Usage
--- | --- | ---
data | `Array<Number>` | The data to plot in a line
label | `String` | The label for the dataset which appears in the legend and tooltips
fill | `Boolean` | If true, fill the area under the line
lineTension | `Number` | Bezier curve tension of the line. Set to 0 to draw straightlines. *Note* This was renamed from 'tension' but the old name still works.
backgroundColor | `Color` | The fill color under the line. See [Colors](#getting-started-colors)
borderWidth | `Number` | The width of the line in pixels
borderColor | `Color` | The color of the line.
borderCapStyle | `String` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)
borderDash | `Array<Number>` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)
borderDashOffset | `Number` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
borderJoinStyle | `String` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
pointBorderColor | `Color or Array<Color>` | The border color for points.
pointBackgroundColor | `Color or Array<Color>` | The fill color for points
pointBorderWidth | `Number or Array<Number>` | The width of the point border in pixels
pointRadius | `Number or Array<Number>` | The radius of the point shape. If set to 0, nothing is rendered.
pointHoverRadius | `Number or Array<Number>` | The radius of the point when hovered
hitRadius | `Number or Array<Number>` | The pixel size of the non-displayed point that reacts to mouse events
pointHoverBackgroundColor | `Color or Array<Color>` | Point background color when hovered
pointHoverBorderColor | `Color or Array<Color>` | Point border color when hovered
pointHoverBorderWidth | `Number or Array<Number>` | Border width of point when hovered
pointStyle | `String or Array<String>` | The style of point. Options include 'circle', 'triangle', 'rect', 'rectRot', 'cross', 'crossRot', 'star', 'line', and 'dash'
An example data object using these attributes is shown below.
```javascript
var data = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "rgba(220,220,220,1)",
backgroundColor: "rgba(179,181,198,0.2)",
borderColor: "rgba(179,181,198,1)",
pointBackgroundColor: "rgba(179,181,198,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderColor: "rgba(179,181,198,1)",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
pointBackgroundColor: "rgba(255,99,132,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
pointHoverBorderColor: "rgba(255,99,132,1)",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
@ -63,10 +94,10 @@ The default options for radar chart are defined in `Chart.defaults.radar`.
Name | Type | Default | Description
--- | --- | --- | ---
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#scales-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid lines.
scale | Object | [See Scales](#scales) and [Defaults for Radial Linear Scale](#scales-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid lines.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*elements*.line | Array | | Options for all line elements used on the chart, as defined in the global elements, duplicated here to show Radar chart specific defaults.
*elements.line*.tension | Number | 0 | Tension exhibited by lines when calculating splineCurve. Setting to 0 creates straight lines.
*elements*.line | Object | | Options for all line elements used on the chart, as defined in the global elements, duplicated here to show Radar chart specific defaults.
*elements.line*.lineTension | Number | 0 | Tension exhibited by lines when calculating splineCurve. Setting to 0 creates straight lines.
You can override these for your `Chart` instance by passing a second argument into the `Radar` method as an object with the keys you want to override.

View file

@ -23,22 +23,39 @@ new Chart(ctx, {
### Data structure
The following options can be included in a polar area chart dataset to configure options for that specific dataset.
Some properties are specified as arrays. The first value applies to the first bar, the second value to the second bar, and so on.
Property | Type | Usage
--- | --- | ---
data | `Array<Number>` | The data to plot as bars
label | `String` | The label for the dataset which appears in the legend and tooltips
backgroundColor | `Array<Color>` | The fill color of the arcs. See [Colors](#getting-started-colors)
borderColor | `Array<Color>` | Arc border color
borderWidth | `Array<Number>` | Border width of arcs in pixels
hoverBackgroundColor | `Array<Color>` | Arc background color when hovered
hoverBorderColor | `Array<Color>` | Arc border color when hovered
hoverBorderWidth | `Array<Number>` | Border width of arc when hovered
An example data object using these attributes is shown below.
```javascript
var data = {
datasets: [{
data: [
10,
32,
53,
14,
22,
11,
16,
7,
3,
14
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
"#FF6384",
"#4BC0C0",
"#FFCE56",
"#E7E9ED",
"#36A2EB"
],
label: 'My dataset' // for legend
}],
@ -47,7 +64,7 @@ var data = {
"Green",
"Yellow",
"Grey",
"Dark Grey"
"Blue"
]
};
```
@ -59,11 +76,11 @@ These are the customisation options specific to Polar Area charts. These options
Name | Type | Default | Description
--- | --- | --- | ---
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#getting-started-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
scale | Object | [See Scales](#scales) and [Defaults for Radial Linear Scale](#scales-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*scale*.lineArc | Boolean | true | When true, lines are circular.
animateRotate | Boolean |true | If true, will animate the rotation of the chart.
animateScale | Boolean | true | If true, will animate scaling the chart.
*animation*.animateRotate | Boolean |true | If true, will animate the rotation of the chart.
*animation*.animateScale | Boolean | true | If true, will animate scaling the chart.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
*legend*.onClick | Function | function(event, legendItem) {} ` | Handles clicking an individual legend item
legendCallback | Function | `function(chart) ` | Generates the HTML legend via calls to `generateLegend`

View file

@ -7,7 +7,7 @@ Pie and doughnut charts are probably the most commonly used chart there are. The
They are excellent at showing the relational proportions between data.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `cutoutPercentage`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
@ -18,21 +18,23 @@ They are also registered under two aliases in the `Chart` core. Other than their
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
<br>
### Example usage
```javascript
// For a pie chart
var myPieChart = new Chart(ctx[0],{
type:'pie',
var myPieChart = new Chart(ctx,{
type: 'pie',
data: data,
options: options
});
```
```javascript
// And for a doughnut chart
var myDoughnutChart = new Chart(ctx[1], {
type:'doughnut',
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: data,
options: options
});
@ -40,6 +42,19 @@ var myDoughnutChart = new Chart(ctx[1], {
### Data structure
Property | Type | Usage
--- | --- | ---
data | `Array<Number>` | The data to plot as bars
label | `String` | The label for the dataset which appears in the legend and tooltips
backgroundColor | `Array<Color>` | The fill color of the arcs. See [Colors](#getting-started-colors)
borderColor | `Array<Color>` | Arc border color
borderWidth | `Array<Number>` | Border width of arcs in pixels
hoverBackgroundColor | `Array<Color>` | Arc background color when hovered
hoverBorderColor | `Array<Color>` | Arc border color when hovered
hoverBorderWidth | `Array<Number>` | Border width of arc when hovered
An example data object using these attributes is shown below.
```javascript
var data = {
labels: [
@ -51,20 +66,20 @@ var data = {
{
data: [300, 50, 100],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C"
"#FF6384",
"#36A2EB",
"#FFCE56"
],
hoverBackgroundColor: [
"#FF5A5E",
"#5AD3D1",
"#FFC870"
"#FF6384",
"#36A2EB",
"#FFCE56"
]
}]
};
```
For a pie chart, you must pass in an array of objects with a value and an optional color property. The value attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
For a pie chart, datasets need to contain an array of data points. The data points should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. You can also add an array of background colors. The color attributes should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
### Chart options
@ -73,9 +88,8 @@ These are the customisation options specific to Pie & Doughnut charts. These opt
Name | Type | Default | Description
--- | --- | --- | ---
cutoutPercentage | Number | 50 - for doughnut, 0 - for pie | The percentage of the chart that is cut out of the middle.
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#getting-started-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*scale*.lineArc | Boolean | true | When true, lines are arced compared to straight when false.
rotation | Number | -0.5 * Math.PI | Starting angle to draw arcs from
circumference | Number | 2 * Math.PI | Sweep to allow arcs to cover
*animation*.animateRotate | Boolean |true | If true, will animate the rotation of the chart.
*animation*.animateScale | Boolean | false | If true, will animate scaling the Doughnut from the centre.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
@ -96,4 +110,4 @@ new Chart(ctx,{
// and the Doughnut chart defaults but this particular instance will have `animateScale` set to `true`.
```
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.pie`, with the only difference being `percentageInnerCutout` being set to 0.
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.pie`, with the only difference being `cutoutPercentage` being set to 0.

View file

@ -143,7 +143,7 @@ var myPieChart = new Chart(ctx, {
// Otherwise, tooltip will be an object with all tooltip properties like:
// tooltip.caretHeight
// tooltip.caretSize
// tooltip.caretPadding
// tooltip.chart
// tooltip.cornerRadius
@ -233,23 +233,27 @@ To work with Chart.js, custom scale types must implement the following interface
determineDataLimits: function() {},
// Generate tick marks. this.chart is the chart instance. The data object can be accessed as this.chart.data
// buildTicks() should create a ticks array on the scale instance, if you intend to use any of the implementations from the base class
// buildTicks() should create a ticks array on the axis instance, if you intend to use any of the implementations from the base class
buildTicks: function() {},
// Get the value to show for the data at the given index of the the given dataset, ie this.chart.data.datasets[datasetIndex].data[index]
getLabelForIndex: function(index, datasetIndex) {},
// Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
// Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value
// @param index: index into the ticks array
// @param includeOffset: if true, get the pixel halway between the given tick and the next
getPixelForTick: function(index, includeOffset) {},
// Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
// Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value
// @param value : the value to get the pixel for
// @param index : index into the data array of the value
// @param datasetIndex : index of the dataset the value comes from
// @param includeOffset : if true, get the pixel halway between the given tick and the next
getPixelForValue: function(value, index, datasetIndex, includeOffset) {}
// Get the value for a given pixel (x coordinate for horizontal axis, y coordinate for vertical axis)
// @param pixel : pixel value
getValueForPixel: function(pixel) {}
}
```
@ -366,6 +370,38 @@ The built in controller types are:
#### Bar Controller
The bar controller has a special property that you should be aware of. To correctly calculate the width of a bar, the controller must determine the number of datasets that map to bars. To do this, the bar controller attaches a property `bar` to the dataset during initialization. If you are creating a replacement or updated bar controller, you should do the same. This will ensure that charts with regular bars and your new derived bars will work seamlessly.
### Creating Plugins
Starting with v2.1.0, you can create plugins for chart.js. To register your plugin, simply call `Chart.pluginService.register` and pass your plugin in.
Plugins will be called at the following times
* Start of initialization
* End of initialization
* Start of update
* End of update
* Start of draw
* End of draw
Plugins should derive from Chart.PluginBase and implement the following interface
```javascript
{
beforeInit: function(chartInstance) { },
afterInit: function(chartInstance) { },
beforeUpdate: function(chartInstance) { },
afterUpdate: function(chartInstance) { },
// This is called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw
// to do something on each animation frame
beforeRender: function(chartInstance) { },
// Easing is for animation
beforeDraw: function(chartInstance, easing) { },
afterDraw: function(chartInstance, easing) { }
destroy: function(chartInstance) { }
}
```
### Building Chart.js
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.

View file

@ -2,31 +2,22 @@
title: Notes
anchor: notes
---
### Previous versions
Please note - documentation for previous versions are available on the GitHub repo.
- [1.x Documentation](https://github.com/chartjs/Chart.js/tree/v1.1.1/docs)
### Browser support
Browser support for the canvas element is available in all modern & major mobile browsers <a href="http://caniuse.com/canvas" target="_blank">(caniuse.com/canvas)</a>.
For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at <a href="https://code.google.com/p/explorercanvas/" target="_blank">https://code.google.com/p/explorercanvas/</a>. It falls back to Internet explorer's format VML when canvas support is not available. Example use:
Chart.js offers support for all browsers where canvas is supported.
```html
<head>
<!--[if lte IE 8]>
<script src="excanvas.js"></script>
<![endif]-->
</head>
```
Browser support for the canvas element is available in all modern & major mobile browsers <a href="http://caniuse.com/#feat=canvas" target="_blank">(http://caniuse.com/#feat=canvas)</a>.
Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE.
Some important points to note in my experience using ExplorerCanvas as a fallback.
- Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas.
- New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent <a href="http://modernizr.com/" target="_blank">Modernizr</a> to do this.
- When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values.
### Bugs & issues
Please report these on the GitHub page - at <a href="https://github.com/nnnick/Chart.js" target="_blank">github.com/nnnick/Chart.js</a>. If you could include a link to a simple <a href="http://jsbin.com/" target="_blank">jsbin</a> or similar to demonstrate the issue, that'd be really helpful.
Please report these on the GitHub page - at <a href="https://github.com/chartjs/Chart.js" target="_blank">github.com/chartjs/Chart.js</a>. If you could include a link to a simple <a href="http://jsbin.com/" target="_blank">jsbin</a> or similar to demonstrate the issue, that'd be really helpful.
### Contributing
@ -39,4 +30,4 @@ New contributions to the library are welcome, just a couple of guidelines:
- Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate.
### License
Chart.js is open source and available under the <a href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>.
Chart.js is open source and available under the <a href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>.

View file

@ -7,6 +7,7 @@ var gulp = require('gulp'),
connect = require('gulp-connect'),
replace = require('gulp-replace'),
htmlv = require('gulp-html-validator'),
insert = require('gulp-insert'),
inquirer = require('inquirer'),
semver = require('semver'),
exec = require('child_process').exec,
@ -23,13 +24,28 @@ var srcDir = './src/';
var outDir = './dist/';
var testDir = './test/';
var header = "/*!\n\
* Chart.js\n\
* http://chartjs.org/\n\
* Version: {{ version }}\n\
*\n\
* Copyright 2016 Nick Downie\n\
* Released under the MIT license\n\
* https://github.com/chartjs/Chart.js/blob/master/LICENSE.md\n\
*/\n";
var preTestFiles = [
'./node_modules/moment/min/moment.min.js',
];
var testFiles = [
'./test/mockContext.js',
'./test/*.js'
'./test/*.js',
// Disable tests which need to be rewritten based on changes introduced by
// the following changes: https://github.com/chartjs/Chart.js/pull/2346
'!./test/core.layoutService.tests.js',
'!./test/defaultConfig.tests.js',
];
gulp.task('build', buildTask);
@ -54,9 +70,10 @@ gulp.task('default', ['build', 'watch']);
function buildTask() {
var bundled = browserify('./src/Chart.js')
var bundled = browserify('./src/chart.js')
.bundle()
.pipe(source('Chart.bundle.js'))
.pipe(insert.prepend(header))
.pipe(streamify(replace('{{ version }}', package.version)))
.pipe(gulp.dest(outDir))
.pipe(streamify(uglify({
@ -65,10 +82,11 @@ function buildTask() {
.pipe(streamify(concat('Chart.bundle.min.js')))
.pipe(gulp.dest(outDir));
var nonBundled = browserify('./src/Chart.js')
var nonBundled = browserify('./src/chart.js')
.ignore('moment')
.bundle()
.pipe(source('Chart.js'))
.pipe(insert.prepend(header))
.pipe(streamify(replace('{{ version }}', package.version)))
.pipe(gulp.dest(outDir))
.pipe(streamify(uglify({

View file

@ -2,11 +2,12 @@
"name": "chart.js",
"homepage": "http://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "2.0.2",
"version": "2.1.0",
"license": "MIT",
"main": "src/chart.js",
"repository": {
"type": "git",
"url": "https://github.com/nnnick/Chart.js.git"
"url": "https://github.com/chartjs/Chart.js.git"
},
"devDependencies": {
"browserify": "^13.0.0",
@ -16,6 +17,7 @@
"gulp-concat": "~2.1.x",
"gulp-connect": "~2.0.5",
"gulp-html-validator": "^0.0.2",
"gulp-insert": "~0.5.0",
"gulp-jshint": "~1.5.1",
"gulp-karma": "0.0.4",
"gulp-replace": "^0.4.0",

View file

@ -0,0 +1,143 @@
<!doctype html>
<html>
<head>
<title>Horizontal Bar Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var horizontalBarChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: true,
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myHorizontalBar = new Chart(ctx, {
type: 'horizontalBar',
data: horizontalBarChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each horizontal bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'left'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Horizontal Bar Chart'
}
}
});
};
$('#randomizeData').click(function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(horizontalBarChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
dataset.data = dataset.data.map(function() {
return zero ? 0.0 : randomScalingFactor();
});
});
window.myHorizontalBar.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + horizontalBarChartData.datasets.length,
backgroundColor: randomColor(),
data: []
};
for (var index = 0; index < horizontalBarChartData.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
horizontalBarChartData.datasets.push(newDataset);
window.myHorizontalBar.update();
});
$('#addData').click(function() {
if (horizontalBarChartData.datasets.length > 0) {
var month = MONTHS[horizontalBarChartData.labels.length % MONTHS.length];
horizontalBarChartData.labels.push(month);
for (var index = 0; index < horizontalBarChartData.datasets.length; ++index) {
horizontalBarChartData.datasets[index].data.push(randomScalingFactor());
}
window.myHorizontalBar.update();
}
});
$('#removeDataset').click(function() {
horizontalBarChartData.datasets.splice(0, 1);
window.myHorizontalBar.update();
});
$('#removeData').click(function() {
horizontalBarChartData.labels.splice(-1, 1); // remove the label first
horizontalBarChartData.datasets.forEach(function (dataset, datasetIndex) {
dataset.data.pop();
});
window.myHorizontalBar.update();
});
</script>
</body>
</html>

View file

@ -65,14 +65,16 @@
},
animation: {
onComplete: function () {
var ctx = this.chart.ctx;
var chartInstance = this.chart;
var ctx = chartInstance.ctx;
ctx.textAlign = "center";
Chart.helpers.each(this.data.datasets.forEach(function (dataset) {
Chart.helpers.each(dataset.metaData.forEach(function (bar, index) {
Chart.helpers.each(this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
Chart.helpers.each(meta.data.forEach(function (bar, index) {
ctx.fillText(dataset.data[index], bar._model.x, bar._model.y - 10);
}),this)
}),this);
}),this)
}),this);
}
}
}

View file

@ -0,0 +1,154 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "dataset - big points",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
pointRadius: 15,
pointHoverRadius: 10,
}, {
label: "dataset - individual point sizes",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
pointRadius: [2, 4, 6, 18, 0, 12, 20],
}, {
label: "dataset - large pointHoverRadius",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
pointHoverRadius: 30,
}, {
label: "dataset - large pointHitRadius",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
pointHitRadius: 20,
}]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
title: {
display: true,
text: 'Chart.js Line Chart - Different point sizes'
}
}
};
$.each(config.data.datasets, function(i, dataset) {
var background = randomColor(0.5);
dataset.borderColor = background;
dataset.backgroundColor = background;
dataset.pointBorderColor = background;
dataset.pointBackgroundColor = background;
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
if (Array.isArray(dataset.pointRadius)) {
dataset.pointRadius.push(Math.random() * 30);
}
});
window.myLine.update();
}
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
if (Array.isArray(dataset.pointRadius)) {
dataset.pointRadius.pop();
}
});
window.myLine.update();
});
</script>
</body>
</html>

View file

@ -103,6 +103,10 @@
title: {
display: true,
text: 'Chart.js Doughnut Chart'
},
animation: {
animateScale: true,
animateRotate: true
}
}
};

View file

@ -52,8 +52,9 @@
fill: false,
borderDash: [5, 5],
}, {
label: "My Third dataset",
label: "My Third dataset - No bezier",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
lineTension: 0,
fill: false,
}, {
label: "My Fourth dataset",

View file

@ -0,0 +1,174 @@
<!doctype html>
<html>
<head>
<title>Pie Chart with Custom Tooltips</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
#canvas-holder {
width: 100%;
margin-top: 50px;
text-align: center;
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.below {
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.below:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 0 8px 8px 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above {
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 8px 8px 0 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
top: 100%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area1" width="50" height="50" />
</div>
<div id="canvas-holder">
<canvas id="chart-area2" width="300" height="300" />
</div>
<div id="chartjs-tooltip"></div>
<script>
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
//Function to find absolution position of the element and not just it's relative position
function getPosition (element) {
var top = 0, left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return {
top: top,
left: left
};
};
//Finding absolute position of the chart canvas
var position = getPosition(tooltip.chart.canvas)
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: position.left + tooltip.x + 'px',
top: position.top + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var pieData = [{
value: 300,
color: "#F7464A",
highlight: "#FF5A5E",
label: "Red"
}, {
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
}, {
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}, {
value: 40,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
}, {
value: 120,
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}];
window.onload = function() {
var ctx1 = document.getElementById("chart-area1").getContext("2d");
window.myPie = new Chart(ctx1).Pie(pieData);
var ctx2 = document.getElementById("chart-area2").getContext("2d");
window.myPie = new Chart(ctx2).Pie(pieData);
};
</script>
</body>
</html>

View file

@ -96,7 +96,7 @@
$.each(config.data.datasets, function(i, piece) {
$.each(piece.data, function(j, value) {
config.data.datasets[i].data[j] = randomScalingFactor();
//config.data.datasets.backgroundColor[i] = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
config.data.datasets[i].backgroundColor[j] = randomColor(0.7);
});
});
window.myPie.update();

View file

@ -74,7 +74,9 @@
},
reverse: false
},
animateRotate:false
animation: {
animateRotate: false
}
}
};

View file

@ -1,14 +1,3 @@
/*!
* Chart.js
* http://chartjs.org/
* Version: {{ version }}
*
* Copyright 2015 Nick Downie
* Released under the MIT license
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/
var Chart = require('./core/core.js')();
require('./core/core.helpers')(Chart);
@ -18,6 +7,7 @@ require('./core/core.controller')(Chart);
require('./core/core.datasetController')(Chart);
require('./core/core.layoutService')(Chart);
require('./core/core.legend')(Chart);
require('./core/core.plugin.js')(Chart);
require('./core/core.scale')(Chart);
require('./core/core.scaleService')(Chart);
require('./core/core.title')(Chart);

View file

@ -33,31 +33,32 @@ module.exports = function(Chart) {
Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
// Use this to indicate that this is a bar dataset.
this.getDataset().bar = true;
this.getMeta().bar = true;
},
// Get the number of datasets that display bars. We use this to correctly calculate the bar width
getBarCount: function getBarCount() {
var barCount = 0;
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && dataset.bar) {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) {
++barCount;
}
});
}, this);
return barCount;
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Rectangle({
meta.data[index] = meta.data[index] || new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var rectangle = new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
@ -66,22 +67,23 @@ module.exports = function(Chart) {
var numBars = this.getBarCount();
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, rectangle);
this.updateElement(rectangle, index, true, numBars);
this.getDataset().metaData.splice(index, 0, rectangle);
},
update: function update(reset) {
var numBars = this.getBarCount();
helpers.each(this.getDataset().metaData, function(rectangle, index) {
helpers.each(this.getMeta().data, function(rectangle, index) {
this.updateElement(rectangle, index, reset, numBars);
}, this);
},
updateElement: function updateElement(rectangle, index, reset, numBars) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var yScalePoint;
@ -125,9 +127,9 @@ module.exports = function(Chart) {
},
calculateBarBase: function(datasetIndex, index) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var base = 0;
@ -138,14 +140,16 @@ module.exports = function(Chart) {
if (value < 0) {
for (var i = 0; i < datasetIndex; i++) {
var negDS = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(negDS) && negDS.yAxisID === yScale.id && negDS.bar) {
var negDSMeta = this.chart.getDatasetMeta(i);
if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) {
base += negDS.data[index] < 0 ? negDS.data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
var posDS = this.chart.data.datasets[j];
if (helpers.isDatasetVisible(posDS) && posDS.yAxisID === yScale.id && posDS.bar) {
var posDSMeta = this.chart.getDatasetMeta(j);
if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(j)) {
base += posDS.data[index] > 0 ? posDS.data[index] : 0;
}
}
@ -169,9 +173,9 @@ module.exports = function(Chart) {
},
getRuler: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var datasetCount = this.getBarCount();
var tickWidth = (function() {
@ -184,6 +188,12 @@ module.exports = function(Chart) {
var categoryWidth = tickWidth * xScale.options.categoryPercentage;
var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
var fullBarWidth = categoryWidth / datasetCount;
if (xScale.ticks.length !== this.chart.data.labels.length) {
var perc = xScale.ticks.length / this.chart.data.labels.length;
fullBarWidth = fullBarWidth * perc;
}
var barWidth = fullBarWidth * xScale.options.barPercentage;
var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
@ -199,7 +209,7 @@ module.exports = function(Chart) {
},
calculateBarWidth: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var xScale = this.getScaleForId(this.getMeta().xAxisID);
var ruler = this.getRuler();
return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
},
@ -207,9 +217,11 @@ module.exports = function(Chart) {
// Get bar index from the given dataset index accounting for the fact that not all bars are visible
getBarIndex: function(datasetIndex) {
var barIndex = 0;
var meta, j;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j]) && this.chart.data.datasets[j].bar) {
for (j = 0; j < datasetIndex; ++j) {
meta = this.chart.getDatasetMeta(j);
if (meta.bar && this.chart.isDatasetVisible(j)) {
++barIndex;
}
}
@ -218,9 +230,9 @@ module.exports = function(Chart) {
},
calculateBarX: function(index, datasetIndex) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var meta = this.getMeta();
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var barIndex = this.getBarIndex(datasetIndex);
var ruler = this.getRuler();
@ -240,9 +252,9 @@ module.exports = function(Chart) {
},
calculateBarY: function(index, datasetIndex) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var value = this.getDataset().data[index];
@ -253,7 +265,8 @@ module.exports = function(Chart) {
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(ds) && ds.bar && ds.yAxisID === yScale.id) {
var dsMeta = this.chart.getDatasetMeta(i);
if (dsMeta.bar && dsMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
@ -267,8 +280,6 @@ module.exports = function(Chart) {
} else {
return yScale.getPixelForValue(sumPos + value);
}
return yScale.getPixelForValue(value);
}
return yScale.getPixelForValue(value);
@ -276,7 +287,7 @@ module.exports = function(Chart) {
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(rectangle, index) {
helpers.each(this.getMeta().data, function(rectangle, index) {
var d = this.getDataset().data[index];
if (d !== null && d !== undefined && !isNaN(d)) {
rectangle.transition(easingDecimal).draw();
@ -303,4 +314,294 @@ module.exports = function(Chart) {
}
});
// including horizontalBar in the bar file, instead of a file of its own
// it extends bar (like pie extends doughnut)
Chart.defaults.horizontalBar = {
hover: {
mode: "label"
},
scales: {
xAxes: [{
type: "linear",
position: "bottom"
}],
yAxes: [{
position: "left",
type: "category",
// Specific to Horizontal Bar Controller
categoryPercentage: 0.8,
barPercentage: 0.9,
// grid line settings
gridLines: {
offsetGridLines: true
}
}]
},
};
Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
updateElement: function updateElement(rectangle, index, reset, numBars) {
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var xScalePoint;
if (xScale.min < 0 && xScale.max < 0) {
// all less than 0. use the right
xScalePoint = xScale.getPixelForValue(xScale.max);
} else if (xScale.min > 0 && xScale.max > 0) {
xScalePoint = xScale.getPixelForValue(xScale.min);
} else {
xScalePoint = xScale.getPixelForValue(0);
}
helpers.extend(rectangle, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: reset ? xScalePoint : this.calculateBarX(index, this.index),
y: this.calculateBarY(index, this.index),
// Tooltip
label: this.chart.data.labels[index],
datasetLabel: this.getDataset().label,
// Appearance
base: reset ? xScalePoint : this.calculateBarBase(this.index, index),
height: this.calculateBarHeight(numBars),
backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor),
borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped,
borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor),
borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth)
},
draw: function () {
var ctx = this._chart.ctx;
var vm = this._view;
var halfHeight = vm.height / 2,
topY = vm.y - halfHeight,
bottomY = vm.y + halfHeight,
right = vm.base - (vm.base - vm.x),
halfStroke = vm.borderWidth / 2;
// Canvas doesn't allow us to stroke inside the width so we can
// adjust the sizes to fit if we're setting a stroke on the line
if (vm.borderWidth) {
topY += halfStroke;
bottomY -= halfStroke;
right += halfStroke;
}
ctx.beginPath();
ctx.fillStyle = vm.backgroundColor;
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = vm.borderWidth;
// Corner points, from bottom-left to bottom-right clockwise
// | 1 2 |
// | 0 3 |
var corners = [
[vm.base, bottomY],
[vm.base, topY],
[right, topY],
[right, bottomY]
];
// Find first (starting) corner with fallback to 'bottom'
var borders = ['bottom', 'left', 'top', 'right'];
var startCorner = borders.indexOf(vm.borderSkipped, 0);
if (startCorner === -1)
startCorner = 0;
function cornerAt(index) {
return corners[(startCorner + index) % 4];
}
// Draw rectangle from 'startCorner'
ctx.moveTo.apply(ctx, cornerAt(0));
for (var i = 1; i < 4; i++)
ctx.lineTo.apply(ctx, cornerAt(i));
ctx.fill();
if (vm.borderWidth) {
ctx.stroke();
}
},
inRange: function (mouseX, mouseY) {
var vm = this._view;
var inRange = false;
if (vm) {
if (vm.x < vm.base) {
inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.x && mouseX <= vm.base);
} else {
inRange = (mouseY >= vm.y - vm.height / 2 && mouseY <= vm.y + vm.height / 2) && (mouseX >= vm.base && mouseX <= vm.x);
}
}
return inRange;
}
});
rectangle.pivot();
},
calculateBarBase: function (datasetIndex, index) {
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var base = 0;
if (xScale.options.stacked) {
var value = this.chart.data.datasets[datasetIndex].data[index];
if (value < 0) {
for (var i = 0; i < datasetIndex; i++) {
var negDS = this.chart.data.datasets[i];
var negDSMeta = this.chart.getDatasetMeta(i);
if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) {
base += negDS.data[index] < 0 ? negDS.data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
var posDS = this.chart.data.datasets[j];
var posDSMeta = this.chart.getDatasetMeta(j);
if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(j)) {
base += posDS.data[index] > 0 ? posDS.data[index] : 0;
}
}
}
return xScale.getPixelForValue(base);
}
base = xScale.getPixelForValue(xScale.min);
if (xScale.beginAtZero || ((xScale.min <= 0 && xScale.max >= 0) || (xScale.min >= 0 && xScale.max <= 0))) {
base = xScale.getPixelForValue(0, 0);
} else if (xScale.min < 0 && xScale.max < 0) {
// All values are negative. Use the right as the base
base = xScale.getPixelForValue(xScale.max);
}
return base;
},
getRuler: function () {
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var datasetCount = this.getBarCount();
var tickHeight = (function () {
var min = yScale.getPixelForTick(1) - yScale.getPixelForTick(0);
for (var i = 2; i < this.getDataset().data.length; i++) {
min = Math.min(yScale.getPixelForTick(i) - yScale.getPixelForTick(i - 1), min);
}
return min;
}).call(this);
var categoryHeight = tickHeight * yScale.options.categoryPercentage;
var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;
var fullBarHeight = categoryHeight / datasetCount;
if (yScale.ticks.length !== this.chart.data.labels.length) {
var perc = yScale.ticks.length / this.chart.data.labels.length;
fullBarHeight = fullBarHeight * perc;
}
var barHeight = fullBarHeight * yScale.options.barPercentage;
var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);
return {
datasetCount: datasetCount,
tickHeight: tickHeight,
categoryHeight: categoryHeight,
categorySpacing: categorySpacing,
fullBarHeight: fullBarHeight,
barHeight: barHeight,
barSpacing: barSpacing,
};
},
calculateBarHeight: function () {
var yScale = this.getScaleForId(this.getMeta().yAxisID);
var ruler = this.getRuler();
return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
},
calculateBarX: function (index, datasetIndex) {
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var value = this.getDataset().data[index];
if (xScale.options.stacked) {
var sumPos = 0,
sumNeg = 0;
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
var dsMeta = this.chart.getDatasetMeta(i);
if (dsMeta.bar && dsMeta.xAxisID === xScale.id && this.chart.isDatasetVisible(i)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
sumPos += ds.data[index] || 0;
}
}
}
if (value < 0) {
return xScale.getPixelForValue(sumNeg + value);
} else {
return xScale.getPixelForValue(sumPos + value);
}
}
return xScale.getPixelForValue(value);
},
calculateBarY: function (index, datasetIndex) {
var meta = this.getMeta();
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var barIndex = this.getBarIndex(datasetIndex);
var ruler = this.getRuler();
var topTick = yScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo);
topTick -= this.chart.isCombo ? (ruler.tickHeight / 2) : 0;
if (yScale.options.stacked) {
return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;
}
return topTick +
(ruler.barHeight / 2) +
ruler.categorySpacing +
(ruler.barHeight * barIndex) +
(ruler.barSpacing / 2) +
(ruler.barSpacing * barIndex);
}
});
};

View file

@ -40,11 +40,9 @@ module.exports = function(Chart) {
Chart.controllers.bubble = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
@ -52,25 +50,22 @@ module.exports = function(Chart) {
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
},
update: function update(reset) {
var points = this.getDataset().metaData;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var meta = this.getMeta();
var points = meta.data;
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
@ -89,8 +84,9 @@ module.exports = function(Chart) {
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var meta = this.getMeta();
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
@ -137,7 +133,7 @@ module.exports = function(Chart) {
var easingDecimal = ease || 1;
// Transition and Draw the Points
helpers.each(this.getDataset().metaData, function(point, index) {
helpers.each(this.getMeta().data, function(point, index) {
point.transition(easingDecimal);
point.draw();
});

View file

@ -21,11 +21,11 @@ module.exports = function(Chart) {
if (chart.data.datasets.length) {
for (var i = 0; i < chart.data.datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '"></span>');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</span></li>');
text.push('</li>');
}
}
@ -34,37 +34,45 @@ module.exports = function(Chart) {
},
legend: {
labels: {
generateLabels: function(data) {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor);
var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor);
var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth);
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
// Extra data used for toggling the correct item
index: i
};
});
}, this);
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
var index = legendItem.index;
var chart = this.chart;
var i, ilen, meta;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
meta.data[index].hidden = !meta.data[index].hidden;
}
this.chart.update();
chart.update();
}
},
@ -102,17 +110,17 @@ module.exports = function(Chart) {
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
meta.data[index] = meta.data[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index, colorForNewElement) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
@ -123,17 +131,9 @@ module.exports = function(Chart) {
this.getDataset().backgroundColor.splice(index, 0, colorForNewElement);
}
// Reset the point
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, arc);
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) {
return helpers.isDatasetVisible(ds);
}).length;
},
// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
@ -141,7 +141,7 @@ module.exports = function(Chart) {
var ringIndex = 0;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j])) {
if (this.chart.isDatasetVisible(j)) {
++ringIndex;
}
}
@ -156,7 +156,7 @@ module.exports = function(Chart) {
var offset = {x: 0, y: 0};
// If the chart's circumference isn't a full circle, calculate minSize as a ratio of the width/height of the arc
if (this.chart.options.circumference && this.chart.options.circumference < Math.PI * 2.0) {
if (this.chart.options.circumference < Math.PI * 2.0) {
var startAngle = this.chart.options.rotation % (Math.PI * 2.0);
startAngle += Math.PI * 2.0 * (startAngle >= Math.PI ? -1 : startAngle < -Math.PI ? 1 : 0);
var endAngle = startAngle + this.chart.options.circumference;
@ -176,30 +176,26 @@ module.exports = function(Chart) {
this.chart.outerRadius = Math.max(minSize / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount();
this.chart.offsetX = offset.x * this.chart.outerRadius;
this.chart.offsetY = offset.y * this.chart.outerRadius;
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
if (!isNaN(value)) {
this.getDataset().total += Math.abs(value);
}
}, this);
this.getMeta().total = this.calculateTotal();
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index));
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
helpers.each(this.getMeta().data, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
updateElement: function(arc, index, reset) {
var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2;
var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2;
var startAngle = this.chart.options.rotation || (Math.PI * -0.5); // non reset case handled later
var endAngle = this.chart.options.rotation || (Math.PI * -0.5); // non reset case handled later
var circumference = reset && this.chart.options.animation.animateRotate ? 0 : this.calculateCircumference(this.getDataset().data[index]) * ((this.chart.options.circumference || (2.0 * Math.PI)) / (2.0 * Math.PI));
var startAngle = this.chart.options.rotation; // non reset case handled later
var endAngle = this.chart.options.rotation; // non reset case handled later
var circumference = reset && this.chart.options.animation.animateRotate ? 0 : arc.hidden? 0 : this.calculateCircumference(this.getDataset().data[index]) * (this.chart.options.circumference / (2.0 * Math.PI));
var innerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.innerRadius;
var outerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.outerRadius;
@ -229,12 +225,12 @@ module.exports = function(Chart) {
});
// Set correct angles if not resetting
if (!reset) {
if (!reset || !this.chart.options.animation.animateRotate) {
if (index === 0) {
arc._model.startAngle = this.chart.options.rotation || (Math.PI * -0.5);
arc._model.startAngle = this.chart.options.rotation;
} else {
arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle;
arc._model.startAngle = this.getMeta().data[index - 1]._model.endAngle;
}
arc._model.endAngle = arc._model.startAngle + arc._model.circumference;
@ -245,7 +241,7 @@ module.exports = function(Chart) {
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(arc, index) {
helpers.each(this.getMeta().data, function(arc, index) {
arc.transition(easingDecimal).draw();
});
},
@ -268,12 +264,29 @@ module.exports = function(Chart) {
arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth);
},
calculateTotal: function() {
var dataset = this.getDataset();
var meta = this.getMeta();
var total = 0;
var value;
helpers.each(meta.data, function(element, index) {
value = dataset.data[index];
if (!isNaN(value) && !element.hidden) {
total += Math.abs(value);
}
});
return total;
},
calculateCircumference: function(value) {
if (this.getDataset().total > 0 && !isNaN(value)) {
return (Math.PI * 1.999999) * (value / this.getDataset().total);
var total = this.getMeta().total;
if (total > 0 && !isNaN(value)) {
return (Math.PI * 2.0) * (value / total);
} else {
return 0;
}
}
});
};
};

View file

@ -26,48 +26,45 @@ module.exports = function(Chart) {
Chart.controllers.line = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
var meta = this.getMeta();
meta.dataset = meta.dataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData
_points: meta.data
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0)
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var meta = this.getMeta();
var line = meta.dataset;
var points = meta.data;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
@ -86,9 +83,16 @@ module.exports = function(Chart) {
// Data
line._children = points;
// Model
// Compatibility: If the properties are defined with only the old name, use those values
if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined))
{
this.getDataset().lineTension = this.getDataset().tension;
}
line._model = {
// Appearance
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
@ -158,8 +162,9 @@ module.exports = function(Chart) {
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var meta = this.getMeta();
var yScale = this.getScaleForId(meta.yAxisID);
var xScale = this.getScaleForId(meta.xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
@ -178,27 +183,37 @@ module.exports = function(Chart) {
point._index = index;
// Desired view properties
// Compatibility: If the properties are defined with only the old name, use those values
if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined))
{
this.getDataset().pointRadius = this.getDataset().radius;
}
if ((this.getDataset().hitRadius !== undefined) && (this.getDataset().pointHitRadius === undefined))
{
this.getDataset().pointHitRadius = this.getDataset().hitRadius;
}
point._model = {
x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo),
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius),
radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius),
pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle),
backgroundColor: this.getPointBackgroundColor(point, index),
borderColor: this.getPointBorderColor(point, index),
borderWidth: this.getPointBorderWidth(point, index),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius)
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointHitRadius, index, this.chart.options.elements.point.hitRadius)
};
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
calculatePointY: function(value, index, datasetIndex, isCombo) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var meta = this.getMeta();
var xScale = this.getScaleForId(meta.xAxisID);
var yScale = this.getScaleForId(meta.yAxisID);
if (yScale.options.stacked) {
@ -207,7 +222,8 @@ module.exports = function(Chart) {
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
if (ds.type === 'line' && helpers.isDatasetVisible(ds)) {
var dsMeta = this.chart.getDatasetMeta(i);
if (dsMeta.type === 'line' && this.chart.isDatasetVisible(i)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
@ -228,12 +244,13 @@ module.exports = function(Chart) {
updateBezierControlPoints: function() {
// Update bezier control points
helpers.each(this.getDataset().metaData, function(point, index) {
var meta = this.getMeta();
helpers.each(meta.data, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index)._model,
helpers.previousItem(meta.data, index)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index)._model,
point._model.tension
helpers.nextItem(meta.data, index)._model,
meta.dataset._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
@ -249,19 +266,20 @@ module.exports = function(Chart) {
},
draw: function(ease) {
var meta = this.getMeta();
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point) {
helpers.each(meta.data, function(point) {
point.transition(easingDecimal);
});
// Transition and Draw the line
if (this.chart.options.showLines)
this.getDataset().metaDataset.transition(easingDecimal).draw();
meta.dataset.transition(easingDecimal).draw();
// Draw the points
helpers.each(this.getDataset().metaData, function(point) {
helpers.each(meta.data, function(point) {
point.draw();
});
},
@ -281,7 +299,13 @@ module.exports = function(Chart) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius);
// Compatibility: If the properties are defined with only the old name, use those values
if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined))
{
this.getDataset().pointRadius = this.getDataset().radius;
}
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius);
point._model.backgroundColor = this.getPointBackgroundColor(point, index);
point._model.borderColor = this.getPointBorderColor(point, index);
point._model.borderWidth = this.getPointBorderWidth(point, index);

View file

@ -12,8 +12,10 @@ module.exports = function(Chart) {
},
//Boolean - Whether to animate the rotation of the chart
animateRotate: true,
animateScale: true,
animation: {
animateRotate: true,
animateScale: true
},
aspectRatio: 1,
legendCallback: function(chart) {
@ -35,37 +37,45 @@ module.exports = function(Chart) {
},
legend: {
labels: {
generateLabels: function(data) {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var fill = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(ds.backgroundColor, i, this.chart.options.elements.arc.backgroundColor);
var stroke = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(ds.borderColor, i, this.chart.options.elements.arc.borderColor);
var bw = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(ds.borderWidth, i, this.chart.options.elements.arc.borderWidth);
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
// Extra data used for toggling the correct item
index: i
};
});
}, this);
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
var index = legendItem.index;
var chart = this.chart;
var i, ilen, meta;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
meta.data[index].hidden = !meta.data[index].hidden;
}
this.chart.update();
chart.update();
}
},
@ -86,51 +96,43 @@ module.exports = function(Chart) {
linkScales: function() {
// no scales for doughnut
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
var meta = this.getMeta();
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
meta.data[index] = meta.data[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, arc);
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) {
return helpers.isDatasetVisible(ds);
}).length;
},
update: function update(reset) {
var meta = this.getMeta();
var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top);
this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
this.getDataset().total += Math.abs(value);
}, this);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.getVisibleDatasetCount();
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index);
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
meta.count = this.countVisibleElements();
helpers.each(meta.data, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
@ -142,23 +144,25 @@ module.exports = function(Chart) {
// If there is NaN data before us, we need to calculate the starting angle correctly.
// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
var notNullIndex = 0;
var visibleCount = 0;
var meta = this.getMeta();
for (var i = 0; i < index; ++i) {
if (!isNaN(this.getDataset().data[i])) {
++notNullIndex;
if (!isNaN(this.getDataset().data[i]) && !meta.data[i].hidden) {
++visibleCount;
}
}
var startAngle = (-0.5 * Math.PI) + (circumference * notNullIndex);
var endAngle = startAngle + circumference;
var distance = arc.hidden? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]);
var startAngle = (-0.5 * Math.PI) + (circumference * visibleCount);
var endAngle = startAngle + (arc.hidden? 0 : circumference);
var resetModel = {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.options.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : startAngle,
endAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : endAngle,
outerRadius: this.chart.options.animation.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : startAngle,
endAngle: this.chart.options.animation.animateRotate ? Math.PI * -0.5 : endAngle,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth),
@ -179,7 +183,7 @@ module.exports = function(Chart) {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
outerRadius: distance,
startAngle: startAngle,
endAngle: endAngle,
@ -196,7 +200,7 @@ module.exports = function(Chart) {
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(arc, index) {
helpers.each(this.getMeta().data, function(arc, index) {
arc.transition(easingDecimal).draw();
});
},
@ -219,18 +223,27 @@ module.exports = function(Chart) {
arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth);
},
calculateCircumference: function(value) {
if (isNaN(value)) {
return 0;
} else {
// Count the number of NaN values
var numNaN = helpers.where(this.getDataset().data, function(data) {
return isNaN(data);
}).length;
countVisibleElements: function() {
var dataset = this.getDataset();
var meta = this.getMeta();
var count = 0;
return (2 * Math.PI) / (this.getDataset().data.length - numNaN);
helpers.each(meta.data, function(element, index) {
if (!isNaN(dataset.data[index]) && !element.hidden) {
count++;
}
});
return count;
},
calculateCircumference: function(value) {
var count = this.getMeta().count;
if (count > 0 && !isNaN(value)) {
return (2 * Math.PI) / count;
} else {
return 0;
}
}
});
};
};

View file

@ -22,18 +22,17 @@ module.exports = function(Chart) {
},
addElements: function() {
var meta = this.getMeta();
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
meta.dataset = meta.dataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData,
_points: meta.data,
_loop: true
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
meta.data[index] = meta.data[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
@ -45,27 +44,24 @@ module.exports = function(Chart) {
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
// Add to the points array and reset it
this.getMeta().data.splice(index, 0, point);
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var meta = this.getMeta();
var line = meta.dataset;
var points = meta.data;
var scale = this.chart.scale;
var scaleBase;
@ -78,15 +74,21 @@ module.exports = function(Chart) {
scaleBase = scale.getPointPositionForValue(0, 0);
}
helpers.extend(this.getDataset().metaDataset, {
// Compatibility: If the properties are defined with only the old name, use those values
if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined))
{
this.getDataset().lineTension = this.getDataset().tension;
}
helpers.extend(meta.dataset, {
// Utility
_datasetIndex: this.index,
// Data
_children: this.getDataset().metaData,
_children: points,
// Model
_model: {
// Appearance
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
@ -103,7 +105,7 @@ module.exports = function(Chart) {
}
});
this.getDataset().metaDataset.pivot();
meta.dataset.pivot();
// Update Points
helpers.each(points, function(point, index) {
@ -144,11 +146,12 @@ module.exports = function(Chart) {
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
updateBezierControlPoints: function() {
helpers.each(this.getDataset().metaData, function(point, index) {
var meta = this.getMeta();
helpers.each(meta.data, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index, true)._model,
helpers.previousItem(meta.data, index, true)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index, true)._model,
helpers.nextItem(meta.data, index, true)._model,
point._model.tension
);
@ -165,18 +168,19 @@ module.exports = function(Chart) {
},
draw: function(ease) {
var meta = this.getMeta();
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point, index) {
helpers.each(meta.data, function(point, index) {
point.transition(easingDecimal);
});
// Transition and Draw the line
this.getDataset().metaDataset.transition(easingDecimal).draw();
meta.dataset.transition(easingDecimal).draw();
// Draw the points
helpers.each(this.getDataset().metaData, function(point) {
helpers.each(meta.data, function(point) {
point.draw();
});
},

View file

@ -43,9 +43,8 @@ module.exports = function(Chart) {
helpers.extend(Chart.Controller.prototype, {
initialize: function initialize() {
// TODO
// If BeforeInit(this) doesn't return false, proceed
// Before init plugin notification
Chart.pluginService.notifyPlugins('beforeInit', [this]);
this.bindEvents();
@ -60,8 +59,8 @@ module.exports = function(Chart) {
this.initToolTip();
this.update();
// TODO
// If AfterInit(this) doesn't return false, proceed
// After init plugin notification
Chart.pluginService.notifyPlugins('afterInit', [this]);
return this;
},
@ -209,18 +208,18 @@ module.exports = function(Chart) {
var newControllers = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (!dataset.type) {
dataset.type = this.config.type;
var meta = this.getDatasetMeta(datasetIndex);
if (!meta.type) {
meta.type = dataset.type || this.config.type;
}
var type = dataset.type;
types.push(type);
types.push(meta.type);
if (dataset.controller) {
dataset.controller.updateIndex(datasetIndex);
if (meta.controller) {
meta.controller.updateIndex(datasetIndex);
} else {
dataset.controller = new Chart.controllers[type](this, datasetIndex);
newControllers.push(dataset.controller);
meta.controller = new Chart.controllers[meta.type](this, datasetIndex);
newControllers.push(meta.controller);
}
}, this);
@ -238,17 +237,24 @@ module.exports = function(Chart) {
resetElements: function resetElements() {
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.reset();
});
this.getDatasetMeta(datasetIndex).controller.reset();
}, this);
},
update: function update(animationDuration, lazy) {
Chart.pluginService.notifyPlugins('beforeUpdate', [this]);
// In case the entire data object changed
this.tooltip._data = this.data;
// Make sure dataset controllers are updated and new controllers are reset
var newControllers = this.buildOrUpdateControllers();
// Make sure all dataset controllers have correct meta data counts
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
this.getDatasetMeta(datasetIndex).controller.buildOrUpdateElements();
}, this);
Chart.layoutService.update(this, this.chart.width, this.chart.height);
// Can only reset the new controllers after the scales have been updated
@ -256,19 +262,18 @@ module.exports = function(Chart) {
controller.reset();
});
// Make sure all dataset controllers have correct meta data counts
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.buildOrUpdateElements();
});
// This will loop through any data and do the appropriate element update for the type
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.update();
});
this.getDatasetMeta(datasetIndex).controller.update();
}, this);
this.render(animationDuration, lazy);
Chart.pluginService.notifyPlugins('afterUpdate', [this]);
},
render: function render(duration, lazy) {
Chart.pluginService.notifyPlugins('beforeRender', [this]);
if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) {
var animation = new Chart.Animation();
@ -302,6 +307,8 @@ module.exports = function(Chart) {
var easingDecimal = ease || 1;
this.clear();
Chart.pluginService.notifyPlugins('beforeDraw', [this, easingDecimal]);
// Draw all the scales
helpers.each(this.boxes, function(box) {
box.draw(this.chartArea);
@ -318,35 +325,37 @@ module.exports = function(Chart) {
// Draw each dataset via its respective controller (reversed to support proper line stacking)
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
dataset.controller.draw(ease);
if (this.isDatasetVisible(datasetIndex)) {
this.getDatasetMeta(datasetIndex).controller.draw(ease);
}
}, null, true);
}, this, true);
// Restore from the clipping operation
this.chart.ctx.restore();
// Finally draw the tooltip
this.tooltip.transition(easingDecimal).draw();
Chart.pluginService.notifyPlugins('afterDraw', [this, easingDecimal]);
},
// Get the single element that was clicked on
// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
getElementAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
helpers.each(dataset.metaData, function(element, index) {
if (this.isDatasetVisible(datasetIndex)) {
var meta = this.getDatasetMeta(datasetIndex);
helpers.each(meta.data, function(element, index) {
if (element.inRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
return elementsArray;
}
});
}
});
}, this);
return elementsArray;
},
@ -358,10 +367,11 @@ module.exports = function(Chart) {
var found = (function() {
if (this.data.datasets) {
for (var i = 0; i < this.data.datasets.length; i++) {
if (helpers.isDatasetVisible(this.data.datasets[i])) {
for (var j = 0; j < this.data.datasets[i].metaData.length; j++) {
if (this.data.datasets[i].metaData[j].inRange(eventPosition.x, eventPosition.y)) {
return this.data.datasets[i].metaData[j];
var meta = this.getDatasetMeta(i);
if (this.isDatasetVisible(i)) {
for (var j = 0; j < meta.data.length; j++) {
if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {
return meta.data[j];
}
}
}
@ -373,11 +383,12 @@ module.exports = function(Chart) {
return elementsArray;
}
helpers.each(this.data.datasets, function(dataset, dsIndex) {
if (helpers.isDatasetVisible(dataset)) {
elementsArray.push(dataset.metaData[found._index]);
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (this.isDatasetVisible(datasetIndex)) {
var meta = this.getDatasetMeta(datasetIndex);
elementsArray.push(meta.data[found._index]);
}
});
}, this);
return elementsArray;
},
@ -386,12 +397,52 @@ module.exports = function(Chart) {
var elementsArray = this.getElementAtEvent(e);
if (elementsArray.length > 0) {
elementsArray = this.data.datasets[elementsArray[0]._datasetIndex].metaData;
elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;
}
return elementsArray;
},
getDatasetMeta: function(datasetIndex) {
var dataset = this.data.datasets[datasetIndex];
if (!dataset._meta) {
dataset._meta = {};
}
var meta = dataset._meta[this.id];
if (!meta) {
meta = dataset._meta[this.id] = {
type: null,
data: [],
dataset: null,
controller: null,
hidden: null, // See isDatasetVisible() comment
xAxisID: null,
yAxisID: null
};
}
return meta;
},
getVisibleDatasetCount: function() {
var count = 0;
for (var i = 0, ilen = this.data.datasets.length; i<ilen; ++i) {
if (this.isDatasetVisible(i)) {
count++;
}
}
return count;
},
isDatasetVisible: function(datasetIndex) {
var meta = this.getDatasetMeta(datasetIndex);
// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,
// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.
return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
},
generateLegend: function generateLegend() {
return this.options.legendCallback(this);
},
@ -415,6 +466,8 @@ module.exports = function(Chart) {
canvas.style.width = this.chart.originalCanvasStyleWidth;
canvas.style.height = this.chart.originalCanvasStyleHeight;
Chart.pluginService.notifyPlugins('destroy', [this]);
delete Chart.instances[this.id];
},
@ -479,20 +532,17 @@ module.exports = function(Chart) {
}
}
var dataset;
var index;
// Remove styling for last active (even if it may still be active)
if (this.lastActive.length) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
this.getDatasetMeta(this.lastActive[0]._datasetIndex).controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
break;
case 'label':
case 'dataset':
for (var i = 0; i < this.lastActive.length; i++) {
if (this.lastActive[i])
this.data.datasets[this.lastActive[i]._datasetIndex].controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
this.getDatasetMeta(this.lastActive[i]._datasetIndex).controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
}
break;
default:
@ -504,13 +554,13 @@ module.exports = function(Chart) {
if (this.active.length && this.options.hover.mode) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.active[0]._datasetIndex].controller.setHoverStyle(this.active[0]);
this.getDatasetMeta(this.active[0]._datasetIndex).controller.setHoverStyle(this.active[0]);
break;
case 'label':
case 'dataset':
for (var j = 0; j < this.active.length; j++) {
if (this.active[j])
this.data.datasets[this.active[j]._datasetIndex].controller.setHoverStyle(this.active[j]);
this.getDatasetMeta(this.active[j]._datasetIndex).controller.setHoverStyle(this.active[j]);
}
break;
default:

View file

@ -21,12 +21,14 @@ module.exports = function(Chart) {
},
linkScales: function() {
if (!this.getDataset().xAxisID) {
this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id;
}
var meta = this.getMeta();
var dataset = this.getDataset();
if (!this.getDataset().yAxisID) {
this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id;
if (meta.xAxisID === null) {
meta.xAxisID = dataset.xAxisID || this.chart.options.scales.xAxes[0].id;
}
if (meta.yAxisID === null) {
meta.yAxisID = dataset.yAxisID || this.chart.options.scales.yAxes[0].id;
}
},
@ -34,6 +36,10 @@ module.exports = function(Chart) {
return this.chart.data.datasets[this.index];
},
getMeta: function() {
return this.chart.getDatasetMeta(this.index);
},
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
@ -44,13 +50,14 @@ module.exports = function(Chart) {
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var meta = this.getMeta();
var numData = this.getDataset().data.length;
var numMetaData = this.getDataset().metaData.length;
var numMetaData = meta.data.length;
// Make sure that we handle number of datapoints changing
if (numData < numMetaData) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numMetaData - numData);
meta.data.splice(numData, numMetaData - numData);
} else if (numData > numMetaData) {
// Add new elements
for (var index = numMetaData; index < numData; ++index) {

View file

@ -11,7 +11,9 @@ module.exports = function(Chart) {
this.initialize.apply(this, arguments);
};
helpers.extend(Chart.Element.prototype, {
initialize: function() {},
initialize: function() {
this.hidden = false;
},
pivot: function() {
if (!this._view) {
this._view = helpers.clone(this._model);

View file

@ -272,7 +272,7 @@ module.exports = function(Chart) {
helpers.uid = (function() {
var id = 0;
return function() {
return "chart-" + id++;
return id++;
};
})();
helpers.warn = function(str) {
@ -938,9 +938,6 @@ module.exports = function(Chart) {
array.push(element);
}
};
helpers.isDatasetVisible = function(dataset) {
return !dataset.hidden;
};
helpers.callCallback = function(fn, args, _tArg) {
if (fn && typeof fn.call === 'function') {
fn.apply(_tArg, args);

View file

@ -53,10 +53,6 @@ module.exports = function(Chart) {
return box.options.position === "chartArea";
});
function fullWidthSorter(a, b) {
}
// Ensure that full width boxes are at the very top / bottom
topBoxes.sort(function(a, b) {
return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);
@ -253,11 +249,15 @@ module.exports = function(Chart) {
});
helpers.each(topBoxes, function(box) {
box.width = newMaxChartAreaWidth;
if (!box.options.fullWidth) {
box.width = newMaxChartAreaWidth;
}
});
helpers.each(bottomBoxes, function(box) {
box.width = newMaxChartAreaWidth;
if (!box.options.fullWidth) {
box.width = newMaxChartAreaWidth;
}
});
maxChartAreaHeight = newMaxChartAreaHeight;

View file

@ -13,8 +13,11 @@ module.exports = function(Chart) {
// a callback that will handle
onClick: function(e, legendItem) {
var dataset = this.chart.data.datasets[legendItem.datasetIndex];
dataset.hidden = !dataset.hidden;
var index = legendItem.datasetIndex;
var meta = this.chart.getDatasetMeta(index);
// See controller.isDatasetVisible comment
meta.hidden = meta.hidden === null? !this.chart.data.datasets[index].hidden : null;
// We hid a dataset ... rerender the chart
this.chart.update();
@ -34,12 +37,13 @@ module.exports = function(Chart) {
// lineDashOffset :
// lineJoin :
// lineWidth :
generateLabels: function(data) {
generateLabels: function(chart) {
var data = chart.data;
return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
return {
text: dataset.label,
fillStyle: dataset.backgroundColor,
hidden: dataset.hidden,
hidden: !chart.isDatasetVisible(i),
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
@ -99,7 +103,6 @@ module.exports = function(Chart) {
this.afterUpdate();
return this.minSize;
},
afterUpdate: helpers.noop,
@ -139,7 +142,7 @@ module.exports = function(Chart) {
beforeBuildLabels: helpers.noop,
buildLabels: function() {
this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data);
this.legendItems = this.options.labels.generateLabels.call(this, this.chart);
if(this.options.reverse){
this.legendItems.reverse();
}

View file

@ -0,0 +1,58 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
// Plugins are stored here
Chart.plugins = [];
Chart.pluginService = {
// Register a new plugin
register: function(plugin) {
if (Chart.plugins.indexOf(plugin) === -1) {
Chart.plugins.push(plugin);
}
},
// Remove a registered plugin
remove: function(plugin) {
var idx = Chart.plugins.indexOf(plugin);
if (idx !== -1) {
Chart.plugins.splice(idx, 1);
}
},
// Iterate over all plugins
notifyPlugins: function(method, args, scope) {
helpers.each(Chart.plugins, function(plugin) {
if (plugin[method] && typeof plugin[method] === 'function') {
plugin[method].apply(scope, args);
}
}, scope);
}
};
Chart.PluginBase = Chart.Element.extend({
// Plugin methods. All functions are passed the chart instance
// Called at start of chart init
beforeInit: helpers.noop,
// Called at end of chart init
afterInit: helpers.noop,
// Called at start of update
beforeUpdate: helpers.noop,
// Called at end of update
afterUpdate: helpers.noop,
// Called at start of draw
beforeDraw: helpers.noop,
// Called at end of draw
afterDraw: helpers.noop,
// Called during destroy
destroy: helpers.noop,
});
};

View file

@ -6,6 +6,7 @@ module.exports = function(Chart) {
Chart.defaults.scale = {
display: true,
position: "left",
// grid line settings
gridLines: {
@ -14,6 +15,7 @@ module.exports = function(Chart) {
lineWidth: 1,
drawOnChartArea: true,
drawTicks: true,
tickMarkLength: 10,
zeroLineWidth: 1,
zeroLineColor: "rgba(0,0,0,0.25)",
offsetGridLines: false
@ -271,12 +273,12 @@ module.exports = function(Chart) {
// subtract the margins to line up with the chartArea if we are a full width scale
this.minSize.width = this.isFullWidth() ? this.maxWidth - this.margins.left - this.margins.right : this.maxWidth;
} else {
this.minSize.width = this.options.gridLines.display && this.options.display ? 10 : 0;
this.minSize.width = this.options.gridLines.tickMarkLength;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.gridLines.display && this.options.display ? 10 : 0;
this.minSize.height = this.options.gridLines.tickMarkLength;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
@ -392,6 +394,9 @@ module.exports = function(Chart) {
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: helpers.noop,
// Used to get the data value from a given pixel. This is the inverse of getPixelForValue
getValueForPixel: helpers.noop,
// Used for tick location, should
getPixelForTick: function(index, includeOffset) {
if (this.isHorizontal()) {
@ -451,6 +456,7 @@ module.exports = function(Chart) {
var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
var tl = this.options.gridLines.tickMarkLength;
var scaleLabelFontColor = helpers.getValueOrDefault(this.options.scaleLabel.fontColor, Chart.defaults.global.defaultFontColor);
var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize);
@ -468,8 +474,8 @@ module.exports = function(Chart) {
if (this.isHorizontal()) {
setContextLineSettings = true;
var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - 10;
var yTickEnd = this.options.position === "bottom" ? this.top + 10 : this.bottom;
var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - tl;
var yTickEnd = this.options.position === "bottom" ? this.top + tl : this.bottom;
skipRatio = false;
if (((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) {
@ -537,7 +543,7 @@ module.exports = function(Chart) {
if (this.options.ticks.display) {
this.ctx.save();
this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - 10 : this.top + 10);
this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = tickLabelFont;
this.ctx.textAlign = (isRotated) ? "right" : "center";

View file

@ -236,10 +236,12 @@ module.exports = function(Chart) {
tooltipPosition = this.getAveragePosition(this._active);
} else {
helpers.each(this._data.datasets, function(dataset, datasetIndex) {
if (!helpers.isDatasetVisible(dataset)) {
if (!this._chartInstance.isDatasetVisible(datasetIndex)) {
return;
}
var currentElement = dataset.metaData[element._index];
var meta = this._chartInstance.getDatasetMeta(datasetIndex);
var currentElement = meta.data[element._index];
if (currentElement) {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
@ -250,7 +252,7 @@ module.exports = function(Chart) {
datasetIndex: datasetIndex
});
}
}, null, element._yScale.options.stacked);
}, this);
helpers.each(this._active, function(active) {
if (active) {
@ -259,10 +261,9 @@ module.exports = function(Chart) {
backgroundColor: active._view.backgroundColor
});
}
}, null, element._yScale.options.stacked);
}, null);
tooltipPosition = this.getAveragePosition(this._active);
tooltipPosition.y = this._active[0]._yScale.getPixelForDecimal(0.5);
}
// Build the Text Lines
@ -491,7 +492,7 @@ module.exports = function(Chart) {
if (vm.title.length) {
ctx.textAlign = vm._titleAlign;
ctx.textBaseline = "top";
var titleColor = helpers.color(vm.titleColor);
ctx.fillStyle = titleColor.alpha(opacity * titleColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
@ -558,7 +559,7 @@ module.exports = function(Chart) {
ctx.textAlign = vm._footerAlign;
ctx.textBaseline = "top";
var footerColor = helpers.color(vm.footerColor);
ctx.fillStyle = footerColor.alpha(opacity * footerColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);

View file

@ -9,25 +9,31 @@ module.exports = function(Chart) {
};
var DatasetScale = Chart.Scale.extend({
buildTicks: function(index) {
this.startIndex = 0;
this.endIndex = this.chart.data.labels.length;
// Implement this so that
determineDataLimits: function() {
this.minIndex = 0;
this.maxIndex = this.chart.data.labels.length - 1;
var findIndex;
if (this.options.ticks.min !== undefined) {
// user specified min value
findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.min);
this.startIndex = findIndex !== -1 ? findIndex : this.startIndex;
this.minIndex = findIndex !== -1 ? findIndex : this.minIndex;
}
if (this.options.ticks.max !== undefined) {
// user specified max value
findIndex = helpers.indexOf(this.chart.data.labels, this.options.ticks.max);
this.endIndex = findIndex !== -1 ? findIndex : this.endIndex;
this.maxIndex = findIndex !== -1 ? findIndex : this.maxIndex;
}
this.min = this.chart.data.labels[this.minIndex];
this.max = this.chart.data.labels[this.maxIndex];
},
buildTicks: function(index) {
// If we are viewing some subset of labels, slice the original array
this.ticks = (this.startIndex === 0 && this.endIndex === this.chart.data.labels.length) ? this.chart.data.labels : this.chart.data.labels.slice(this.startIndex, this.endIndex + 1);
this.ticks = (this.minIndex === 0 && this.maxIndex === this.chart.data.labels.length - 1) ? this.chart.data.labels : this.chart.data.labels.slice(this.minIndex, this.maxIndex + 1);
},
getLabelForIndex: function(index, datasetIndex) {
@ -37,12 +43,12 @@ module.exports = function(Chart) {
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
// 1 is added because we need the length but we have the indexes
var offsetAmt = Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var offsetAmt = Math.max((this.maxIndex + 1 - this.minIndex - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueWidth = innerWidth / offsetAmt;
var widthOffset = (valueWidth * (index - this.startIndex)) + this.paddingLeft;
var widthOffset = (valueWidth * (index - this.minIndex)) + this.paddingLeft;
if (this.options.gridLines.offsetGridLines && includeOffset) {
widthOffset += (valueWidth / 2);
@ -52,7 +58,7 @@ module.exports = function(Chart) {
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
var valueHeight = innerHeight / offsetAmt;
var heightOffset = (valueHeight * (index - this.startIndex)) + this.paddingTop;
var heightOffset = (valueHeight * (index - this.minIndex)) + this.paddingTop;
if (this.options.gridLines.offsetGridLines && includeOffset) {
heightOffset += (valueHeight / 2);
@ -62,7 +68,27 @@ module.exports = function(Chart) {
}
},
getPixelForTick: function(index, includeOffset) {
return this.getPixelForValue(this.ticks[index], index + this.startIndex, null, includeOffset);
return this.getPixelForValue(this.ticks[index], index + this.minIndex, null, includeOffset);
},
getValueForPixel: function(pixel) {
var value
; var offsetAmt = Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var horz = this.isHorizontal();
var innerDimension = horz ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom);
var valueDimension = innerDimension / offsetAmt;
if (this.options.gridLines.offsetGridLines) {
pixel -= (valueDimension / 2);
}
pixel -= horz ? this.paddingLeft : this.paddingTop;
if (pixel <= 0) {
value = 0;
} else {
value = Math.round(pixel / valueDimension);
}
return value;
}
});

View file

@ -8,7 +8,8 @@ module.exports = function(Chart) {
position: "left",
ticks: {
callback: function(tickValue, index, ticks) {
var delta = ticks[1] - ticks[0];
// If we have lots of ticks, don't use the ones
var delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];
// If we have a number like 2.5 as the delta, figure out how many decimal places we need
if (Math.abs(delta) > 1) {
@ -45,23 +46,23 @@ module.exports = function(Chart) {
var hasPositiveValues = false;
var hasNegativeValues = false;
helpers.each(this.chart.data.datasets, function(dataset) {
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (valuesPerType[meta.type] === undefined) {
valuesPerType[meta.type] = {
positiveValues: [],
negativeValues: []
};
}
// Store these per type
var positiveValues = valuesPerType[dataset.type].positiveValues;
var negativeValues = valuesPerType[dataset.type].negativeValues;
var positiveValues = valuesPerType[meta.type].positiveValues;
var negativeValues = valuesPerType[meta.type].negativeValues;
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
if (this.chart.isDatasetVisible(datasetIndex) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (isNaN(value) || meta.data[index].hidden) {
return;
}
@ -92,11 +93,12 @@ module.exports = function(Chart) {
}, this);
} else {
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (this.chart.isDatasetVisible(datasetIndex) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (isNaN(value) || meta.data[index].hidden) {
return;
}
@ -249,6 +251,19 @@ module.exports = function(Chart) {
return Math.round(pixel);
}
},
getValueForPixel: function(pixel) {
var offset;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
offset = (pixel - this.left - this.paddingLeft) / innerWidth;
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
offset = (this.bottom - this.paddingBottom - pixel) / innerHeight;
}
return this.start + ((this.end - this.start) * offset);
},
getPixelForTick: function(index, includeOffset) {
return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset);
}

View file

@ -30,16 +30,17 @@ module.exports = function(Chart) {
if (this.options.stacked) {
var valuesPerType = {};
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = [];
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (this.chart.isDatasetVisible(datasetIndex) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
if (valuesPerType[meta.type] === undefined) {
valuesPerType[meta.type] = [];
}
helpers.each(dataset.data, function(rawValue, index) {
var values = valuesPerType[dataset.type];
var values = valuesPerType[meta.type];
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (isNaN(value) || meta.data[index].hidden) {
return;
}
@ -63,11 +64,12 @@ module.exports = function(Chart) {
}, this);
} else {
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var meta = this.chart.getDatasetMeta(datasetIndex);
if (this.chart.isDatasetVisible(datasetIndex) && (this.isHorizontal() ? meta.xAxisID === this.id : meta.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (isNaN(value) || meta.data[index].hidden) {
return;
}
@ -164,8 +166,8 @@ module.exports = function(Chart) {
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var pixel;
var newVal = +this.getRightValue(value);
var range = helpers.log10(this.end) - helpers.log10(this.start);
var newVal = +this.getRightValue(value)
; var range = helpers.log10(this.end) - helpers.log10(this.start);
if (this.isHorizontal()) {
@ -187,6 +189,21 @@ module.exports = function(Chart) {
}
return pixel;
},
getValueForPixel: function(pixel) {
var offset;
var range = helpers.log10(this.end) - helpers.log10(this.start);
var value;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
value = this.start * Math.pow(10, (pixel - this.left - this.paddingLeft) * range / innerWidth);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
value = Math.pow(10, (this.bottom - this.paddingBottom - pixel) * range / innerHeight) / this.start;
}
return value;
}
});

View file

@ -63,11 +63,12 @@ module.exports = function(Chart) {
this.min = null;
this.max = null;
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset)) {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
if (this.chart.isDatasetVisible(datasetIndex)) {
var meta = this.chart.getDatasetMeta(datasetIndex);
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
if (isNaN(value) || meta.data[index].hidden) {
return;
}
@ -395,7 +396,7 @@ module.exports = function(Chart) {
}
// Extra 3px out for some label spacing
var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5);
var pointLabelFontColor = helpers.getValueOrDefault(this.options.pointLabels.fontColor, Chart.defaults.global.defaultFontColor);
var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize);
var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle);

View file

@ -86,10 +86,13 @@ module.exports = function(Chart) {
if (this.chart.data.labels && this.chart.data.labels.length > 0) {
helpers.each(this.chart.data.labels, function(label, index) {
var labelMoment = this.parseTime(label);
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
if (labelMoment.isValid()) {
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
scaleLabelMoments.push(labelMoment);
}
scaleLabelMoments.push(labelMoment);
}, this);
this.firstTick = moment.min.call(this, scaleLabelMoments);
@ -101,18 +104,24 @@ module.exports = function(Chart) {
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var momentsForDataset = [];
var datasetVisible = this.chart.isDatasetVisible(datasetIndex);
if (typeof dataset.data[0] === 'object') {
helpers.each(dataset.data, function(value, index) {
var labelMoment = this.parseTime(this.getRightValue(value));
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
momentsForDataset.push(labelMoment);
// May have gone outside the scale ranges, make sure we keep the first and last ticks updated
this.firstTick = this.firstTick !== null ? moment.min(this.firstTick, labelMoment) : labelMoment;
this.lastTick = this.lastTick !== null ? moment.max(this.lastTick, labelMoment) : labelMoment;
if (labelMoment.isValid()) {
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
momentsForDataset.push(labelMoment);
if (datasetVisible) {
// May have gone outside the scale ranges, make sure we keep the first and last ticks updated
this.firstTick = this.firstTick !== null ? moment.min(this.firstTick, labelMoment) : labelMoment;
this.lastTick = this.lastTick !== null ? moment.max(this.lastTick, labelMoment) : labelMoment;
}
}
}, this);
} else {
// We have no labels. Use the ones from the scale
@ -199,7 +208,9 @@ module.exports = function(Chart) {
unitDefinition = time.units[unitDefinitionIndex];
this.tickUnit = unitDefinition.name;
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
var leadingUnitBuffer = this.firstTick.diff(this.firstTick.clone().startOf(this.tickUnit), this.tickUnit, true);
var trailingUnitBuffer = this.lastTick.clone().add(1, this.tickUnit).startOf(this.tickUnit).diff(this.lastTick, this.tickUnit, true);
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true) + leadingUnitBuffer + trailingUnitBuffer;
this.displayFormat = this.options.time.displayFormats[unitDefinition.name];
}
}
@ -217,7 +228,11 @@ module.exports = function(Chart) {
// Only round the last tick if we have no hard maximum
if (!this.options.time.max) {
this.lastTick.endOf(this.tickUnit);
var roundedEnd = this.lastTick.clone().startOf(this.tickUnit);
if (roundedEnd.diff(this.lastTick, this.tickUnit, true) !== 0) {
// Do not use end of because we need this to be in the next time unit
this.lastTick.add(1, this.tickUnit).startOf(this.tickUnit);
}
}
this.smallestLabelSeparation = this.width;
@ -237,7 +252,7 @@ module.exports = function(Chart) {
this.ticks.push(this.firstTick.clone());
// For every unit in between the first and last moment, create a moment and add it to the ticks tick
for (var i = 1; i < this.scaleSizeInUnits; ++i) {
for (var i = 1; i <= this.scaleSizeInUnits; ++i) {
var newTick = roundedStart.clone().add(i, this.tickUnit);
// Are we greater than the max time
@ -251,18 +266,19 @@ module.exports = function(Chart) {
}
// Always show the right tick
if (this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit) !== 0 || this.scaleSizeInUnits === 0) {
// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
// but the last tick was not rounded.
var diff = this.ticks[this.ticks.length - 1].diff(this.lastTick, this.tickUnit);
if (diff !== 0 || this.scaleSizeInUnits === 0) {
// this is a weird case. If the <max> option is the same as the end option, we can't just diff the times because the tick was created from the roundedStart
// but the last tick was not rounded.
if (this.options.time.max) {
this.ticks.push(this.lastTick.clone());
this.scaleSizeInUnits = this.lastTick.diff(this.ticks[0], this.tickUnit, true);
} else {
this.scaleSizeInUnits = Math.ceil(this.scaleSizeInUnits / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.scaleSizeInUnits, this.tickUnit));
this.lastTick = this.ticks[this.ticks.length - 1].clone();
this.ticks.push(this.lastTick.clone());
this.scaleSizeInUnits = this.lastTick.diff(this.firstTick, this.tickUnit, true);
}
}
this.ctx.restore();
},
// Get tooltip label
@ -294,7 +310,7 @@ module.exports = function(Chart) {
this.ticks = this.ticks.map(this.tickFormatFunction, this);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var labelMoment = this.getLabelMoment(datasetIndex, index);
var labelMoment = value && value.isValid && value.isValid() ? value : this.getLabelMoment(datasetIndex, index);
if (labelMoment) {
var offset = labelMoment.diff(this.firstTick, this.tickUnit, true);
@ -316,6 +332,12 @@ module.exports = function(Chart) {
}
}
},
getValueForPixel: function(pixel) {
var innerDimension = this.isHorizontal() ? this.width - (this.paddingLeft + this.paddingRight) : this.height - (this.paddingTop + this.paddingBottom);
var offset = (pixel - (this.isHorizontal() ? this.left + this.paddingLeft : this.top + this.paddingTop)) / innerDimension;
offset *= this.scaleSizeInUnits;
return this.firstTick.clone().add(moment.duration(offset, this.tickUnit).asSeconds(), 'seconds');
},
parseTime: function(label) {
if (typeof this.options.time.parser === 'string') {
return moment(label, this.options.time.parser);

File diff suppressed because it is too large Load diff

View file

@ -1,27 +1,37 @@
// Test the bubble controller
describe('Bubble controller tests', function() {
it('Should be constructed', function() {
var chart = {
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
afterEach(function() {
window.releaseAllCharts();
});
it('should be constructed', function() {
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
xAxisID: 'myXAxis',
yAxisID: 'myYAxis',
data: []
}]
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
var meta = chart.getDatasetMeta(0);
expect(meta.type).toBe('bubble');
expect(meta.controller).not.toBe(undefined);
expect(meta.controller.index).toBe(0);
expect(meta.data).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
meta.controller.updateIndex(1);
expect(meta.controller.index).toBe(1);
});
it('Should use the first scale IDs if the dataset does not specify them', function() {
var chart = {
it('should use the first scale IDs if the dataset does not specify them', function() {
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: []
@ -37,255 +47,116 @@ describe('Bubble controller tests', function() {
}]
}
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
expect(chart.data.datasets[0].xAxisID).toBe('firstXScaleID');
expect(chart.data.datasets[0].yAxisID).toBe('firstYScaleID');
var meta = chart.getDatasetMeta(0);
expect(meta.xAxisID).toBe('firstXScaleID');
expect(meta.yAxisID).toBe('firstYScaleID');
});
it('Should create point elements for each data item during initialization', function() {
var chart = {
it('should create point elements for each data item during initialization', function() {
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'bubble'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
var meta = chart.getDatasetMeta(0);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 points created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
expect(meta.data.length).toBe(4); // 4 points created
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
});
it('should draw all elements', function() {
var chart = {
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'bubble'
},
options: {
showLines: true,
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
animation: false,
showLines: true
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
var meta = chart.getDatasetMeta(0);
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
spyOn(meta.data[0], 'draw');
spyOn(meta.data[1], 'draw');
spyOn(meta.data[2], 'draw');
spyOn(meta.data[3], 'draw');
controller.draw();
chart.update();
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
expect(meta.data[0].draw.calls.count()).toBe(1);
expect(meta.data[1].draw.calls.count()).toBe(1);
expect(meta.data[2].draw.calls.count()).toBe(1);
expect(meta.data[3].draw.calls.count()).toBe(1);
});
it('should update elements', function() {
var data = {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
it('should update elements when modifying style', function() {
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
}]
}],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bubble.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: data
},
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bubble.scales.xAxes[0]);
horizontalScaleConfig.position = 'bottom';
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
chart: {
data: data
},
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: xScale.left + 200,
top: 0
},
data: data,
config: {
type: 'bubble'
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
tension: 0.1,
},
point: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
pointStyle: 'circle'
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
type: 'category'
}],
yAxes: [{
id: 'firstYScaleID'
type: 'linear'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.bubble(chart, 0);
controller.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 5,
skip: false,
// Point
x: 195,
y: 6,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 1,
skip: false,
var meta = chart.getDatasetMeta(0);
// Point
x: 89,
y: 194,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 2,
skip: false,
// Point
x: 153,
y: 185,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 1,
skip: false,
// Point
x: 136,
y: 6,
[ { r: 5, x: 38, y: 32 },
{ r: 1, x: 189, y: 484 },
{ r: 2, x: 341, y: 461 },
{ r: 1, x: 492, y: 32 }
].forEach(function(expected, i) {
expect(meta.data[i]._model.radius).toBe(expected.r);
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: Chart.defaults.global.defaultColor,
borderColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
hitRadius: 1,
skip: false
}));
});
// Use dataset level styles for lines & points
@ -297,198 +168,71 @@ describe('Bubble controller tests', function() {
chart.data.datasets[0].radius = 22;
chart.data.datasets[0].hitRadius = 3.3;
controller.update();
chart.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: 'rgb(98, 98, 98)',
borderWidth: 0.55,
borderColor: 'rgb(8, 8, 8)',
hitRadius: 3.3,
radius: 5,
skip: false,
// Point
x: 195,
y: 6,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: 'rgb(98, 98, 98)',
borderWidth: 0.55,
borderColor: 'rgb(8, 8, 8)',
hitRadius: 3.3,
radius: 1,
skip: false,
// Point
x: 89,
y: 194,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: 'rgb(98, 98, 98)',
borderWidth: 0.55,
borderColor: 'rgb(8, 8, 8)',
hitRadius: 3.3,
radius: 2,
skip: false,
// Point
x: 153,
y: 185,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: 'rgb(98, 98, 98)',
borderWidth: 0.55,
borderColor: 'rgb(8, 8, 8)',
hitRadius: 3.3,
radius: 1,
skip: false,
// Point
x: 136,
y: 6,
});
for (var i=0; i<4; ++i) {
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(98, 98, 98)',
borderColor: 'rgb(8, 8, 8)',
borderWidth: 0.55,
hitRadius: 3.3,
skip: false
}));
}
// point styles
chart.data.datasets[0].metaData[0].custom = {
meta.data[0].custom = {
radius: 2.2,
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
tension: 0.15,
skip: true,
hitRadius: 5,
skip: true
};
controller.update();
chart.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(0, 1, 3)',
borderWidth: 0.787,
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
hitRadius: 5,
radius: 2.2,
skip: true,
// Point
x: 195,
y: 6,
});
skip: true
}));
});
it('should handle number of data point changes in update', function() {
var data = {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
}],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bubble.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: data
},
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bubble.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
chart: {
data: data
},
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
point: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}],
labels: ['label1', 'label2', 'label3', 'label4']
}
};
});
var meta = chart.getDatasetMeta(0);
expect(meta.data.length).toBe(4);
var controller = new Chart.controllers.bubble(chart, 0);
chart.data.datasets[0].data = [{
x: 1,
y: 1,
@ -498,10 +242,12 @@ describe('Bubble controller tests', function() {
y: 5,
r: 2
}]; // remove 2 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
chart.update();
expect(meta.data.length).toBe(2);
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
chart.data.datasets[0].data = [{
x: 10,
@ -524,100 +270,44 @@ describe('Bubble controller tests', function() {
y: 0,
r: 3
}]; // add 3 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[4] instanceof Chart.elements.Point).toBe(true);
chart.update();
expect(meta.data.length).toBe(5);
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[4] instanceof Chart.elements.Point).toBe(true);
});
it('should set hover styles', function() {
var data = {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
}]
}],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bubble.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: data
},
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bubble.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
chart: {
data: data
},
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
point: {
backgroundColor: 'rgb(255, 255, 0)',
borderWidth: 1,
@ -625,29 +315,16 @@ describe('Bubble controller tests', function() {
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
radius: 3
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
var point = meta.data[0];
controller.setHoverStyle(point);
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
expect(point._model.borderWidth).toBe(1);
@ -659,7 +336,7 @@ describe('Bubble controller tests', function() {
chart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].hoverBorderWidth = 2.1;
controller.setHoverStyle(point);
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
@ -673,7 +350,7 @@ describe('Bubble controller tests', function() {
hoverBorderColor: 'rgb(10, 10, 10)'
};
controller.setHoverStyle(point);
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);
@ -681,92 +358,32 @@ describe('Bubble controller tests', function() {
});
it('should remove hover styles', function() {
var data = {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
var chart = window.acquireChart({
type: 'bubble',
data: {
datasets: [{
data: [{
x: 10,
y: 10,
r: 5
}, {
x: -15,
y: -10,
r: 1
}, {
x: 0,
y: -9,
r: 2
}, {
x: -4,
y: 10,
r: 1
}]
}],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bubble.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: data
},
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bubble.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
chart: {
data: data
},
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
fill: true,
tension: 0.1,
},
point: {
backgroundColor: 'rgb(255, 255, 0)',
borderWidth: 1,
@ -774,34 +391,21 @@ describe('Bubble controller tests', function() {
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
radius: 3
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
});
var controller = new Chart.controllers.bubble(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
var point = meta.data[0];
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
chart.options.elements.point.borderWidth = 10.1;
chart.options.elements.point.radius = 1.01;
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
expect(point._model.borderWidth).toBe(10.1);
@ -813,7 +417,7 @@ describe('Bubble controller tests', function() {
chart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].borderWidth = 2.1;
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
@ -827,10 +431,10 @@ describe('Bubble controller tests', function() {
borderColor: 'rgb(10, 10, 10)'
};
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);
expect(point._model.radius).toBe(4.4);
});
});
});

View file

@ -1,73 +1,76 @@
// Test the bar controller
describe('Doughnut controller tests', function() {
it('Should be constructed', function() {
var chart = {
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
afterEach(function() {
window.releaseAllCharts();
});
it('should be constructed', function() {
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: []
}]
}],
labels: []
}
};
});
var controller = new Chart.controllers.doughnut(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
var meta = chart.getDatasetMeta(0);
expect(meta.type).toBe('doughnut');
expect(meta.controller).not.toBe(undefined);
expect(meta.controller.index).toBe(0);
expect(meta.data).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
meta.controller.updateIndex(1);
expect(meta.controller.index).toBe(1);
});
it('Should create arc elements for each data item during initialization', function() {
var chart = {
it('should create arc elements for each data item during initialization', function() {
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [10, 15, 0, 4]
}]
},
config: {
type: 'doughnut'
},
options: {
}],
labels: []
}
};
});
var controller = new Chart.controllers.doughnut(chart, 0);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 rectangles created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true);
var meta = chart.getDatasetMeta(0);
expect(meta.data.length).toBe(4); // 4 rectangles created
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
});
it ('Should reset and update elements', function() {
var chart = {
chartArea: {
left: 0,
top: 0,
right: 100,
bottom: 200,
},
it ('should reset and update elements', function() {
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [1, 2, 3, 4],
hidden: true
}, {
data: [10, 15, 0, 4]
data: [5, 6, 0, 7]
}, {
data: [1]
data: [8, 9, 10, 11]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateRotate: true,
animateScale: false
},
cutoutPercentage: 50,
rotation: Math.PI * -0.5,
circumference: Math.PI * 2.0,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
@ -77,165 +80,95 @@ describe('Doughnut controller tests', function() {
}
}
}
};
});
var controller = new Chart.controllers.doughnut(chart, 1);
controller.reset(); // reset first
var meta = chart.getDatasetMeta(1);
expect(chart.data.datasets[1].metaData[0]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: Math.PI * -0.5,
circumference: 2.166614539857563,
outerRadius: 49,
innerRadius: 36.75
}));
meta.controller.reset(); // reset first
expect(chart.data.datasets[1].metaData[1]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: Math.PI * -0.5,
circumference: 3.2499218097863447,
outerRadius: 49,
innerRadius: 36.75
}));
expect(meta.data.length).toBe(4);
expect(chart.data.datasets[1].metaData[2]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: Math.PI * -0.5,
circumference: 0,
outerRadius: 49,
innerRadius: 36.75
}));
[ { c: 0 },
{ c: 0 },
{ c: 0, },
{ c: 0 }
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
startAngle: Math.PI * -0.5,
endAngle: Math.PI * -0.5,
label: chart.data.labels[i],
hoverBackgroundColor: 'rgb(255, 255, 255)',
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2
}));
})
expect(chart.data.datasets[1].metaData[3]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: Math.PI * -0.5,
circumference: 0.8666458159430251,
outerRadius: 49,
innerRadius: 36.75
}));
chart.update();
controller.update();
expect(chart.data.datasets[1].metaData[0]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: 0.5958182130626666,
circumference: 2.166614539857563,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label0',
}));
expect(chart.data.datasets[1].metaData[1]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: 0.5958182130626666,
endAngle: 3.8457400228490113,
circumference: 3.2499218097863447,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label1'
}));
expect(chart.data.datasets[1].metaData[2]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: 3.8457400228490113,
endAngle: 3.8457400228490113,
circumference: 0,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label2'
}));
expect(chart.data.datasets[1].metaData[3]._model).toEqual(jasmine.objectContaining({
x: 50,
y: 100,
startAngle: 3.8457400228490113,
endAngle: 4.712385838792036,
circumference: 0.8666458159430251,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label3'
}));
[ { c: 1.7453292519, s: -1.5707963267, e: 0.1745329251 },
{ c: 2.0943951023, s: 0.1745329251, e: 2.2689280275 },
{ c: 0, s: 2.2689280275, e: 2.2689280275 },
{ c: 2.4434609527, s: 2.2689280275, e: 4.7123889803 }
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(239);
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(179);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c, 8);
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
label: chart.data.labels[i],
hoverBackgroundColor: 'rgb(255, 255, 255)',
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2
}));
})
// Change the amount of data and ensure that arcs are updated accordingly
chart.data.datasets[1].data = [1, 2]; // remove 2 elements from dataset 0
controller.buildOrUpdateElements();
controller.update();
chart.update();
expect(chart.data.datasets[1].metaData.length).toBe(2);
expect(chart.data.datasets[1].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[1].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data.length).toBe(2);
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
// Add data
chart.data.datasets[1].data = [1, 2, 3, 4];
controller.buildOrUpdateElements();
controller.update();
chart.update();
expect(chart.data.datasets[1].metaData.length).toBe(4);
expect(chart.data.datasets[1].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[1].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[1].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[1].metaData[3] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data.length).toBe(4);
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
});
it ('should draw all arcs', function() {
var chart = {
chartArea: {
left: 0,
top: 0,
right: 100,
bottom: 200,
},
it ('should rotate and limit circumference', function() {
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [10, 15, 0, 4]
data: [2, 4],
hidden: true
}, {
data: [1, 3]
}, {
data: [1, 0]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
labels: ['label0', 'label1']
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
rotation: Math.PI,
circumference: Math.PI * 0.5,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
@ -245,46 +178,62 @@ describe('Doughnut controller tests', function() {
}
}
}
};
});
var controller = new Chart.controllers.doughnut(chart, 0);
var meta = chart.getDatasetMeta(1);
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
expect(meta.data.length).toBe(2);
controller.draw();
// Only startAngle, endAngle and circumference should be different.
[ { c: Math.PI / 8, s: Math.PI, e: Math.PI + Math.PI / 8 },
{ c: 3 * Math.PI / 8, s: Math.PI + Math.PI / 8, e: Math.PI + Math.PI / 2 }
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(495);
expect(meta.data[i]._model.y).toBeCloseToPixel(511);
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(478);
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(359);
expect(meta.data[i]._model.circumference).toBeCloseTo(expected.c,8);
expect(meta.data[i]._model.startAngle).toBeCloseTo(expected.s, 8);
expect(meta.data[i]._model.endAngle).toBeCloseTo(expected.e, 8);
})
});
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
it ('should draw all arcs', function() {
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
}
});
var meta = chart.getDatasetMeta(0);
spyOn(meta.data[0], 'draw');
spyOn(meta.data[1], 'draw');
spyOn(meta.data[2], 'draw');
spyOn(meta.data[3], 'draw');
chart.update();
expect(meta.data[0].draw.calls.count()).toBe(1);
expect(meta.data[1].draw.calls.count()).toBe(1);
expect(meta.data[2].draw.calls.count()).toBe(1);
expect(meta.data[3].draw.calls.count()).toBe(1);
});
it ('should set the hover style of an arc', function() {
var chart = {
chartArea: {
left: 0,
top: 0,
right: 100,
bottom: 200,
},
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
@ -293,16 +242,12 @@ describe('Doughnut controller tests', function() {
}
}
}
};
});
var controller = new Chart.controllers.doughnut(chart, 0);
controller.reset(); // reset first
controller.update();
var arc = chart.data.datasets[0].metaData[0];
controller.setHoverStyle(arc);
var meta = chart.getDatasetMeta(0);
var arc = meta.data[0];
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(0, 0, 230)');
expect(arc._model.borderWidth).toBe(2);
@ -312,8 +257,7 @@ describe('Doughnut controller tests', function() {
chart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)';
chart.data.datasets[0].hoverBorderWidth = 1.56;
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(1.56);
@ -323,8 +267,7 @@ describe('Doughnut controller tests', function() {
chart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)'];
chart.data.datasets[0].hoverBorderWidth = [0.1, 1.56];
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(0.1);
@ -336,36 +279,22 @@ describe('Doughnut controller tests', function() {
hoverBorderWidth: 3.14159,
};
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
expect(arc._model.borderWidth).toBe(3.14159);
});
it ('should unset the hover style of an arc', function() {
var chart = {
chartArea: {
left: 0,
top: 0,
right: 100,
bottom: 200,
},
var chart = window.acquireChart({
type: 'doughnut',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
@ -374,16 +303,12 @@ describe('Doughnut controller tests', function() {
}
}
}
};
});
var controller = new Chart.controllers.doughnut(chart, 0);
controller.reset(); // reset first
controller.update();
var arc = chart.data.datasets[0].metaData[0];
controller.removeHoverStyle(arc);
var meta = chart.getDatasetMeta(0);
var arc = meta.data[0];
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(0, 0, 255)');
expect(arc._model.borderWidth).toBe(2);
@ -393,8 +318,7 @@ describe('Doughnut controller tests', function() {
chart.data.datasets[0].borderColor = 'rgb(18, 18, 18)';
chart.data.datasets[0].borderWidth = 1.56;
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(1.56);
@ -404,8 +328,7 @@ describe('Doughnut controller tests', function() {
chart.data.datasets[0].borderColor = ['rgb(18, 18, 18)'];
chart.data.datasets[0].borderWidth = [0.1, 1.56];
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(0.1);
@ -417,10 +340,9 @@ describe('Doughnut controller tests', function() {
borderWidth: 3.14159,
};
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
expect(arc._model.borderWidth).toBe(3.14159);
});
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,113 +1,93 @@
// Test the polar area controller
describe('Polar area controller tests', function() {
it('Should be constructed', function() {
var chart = {
data: {
datasets: [{
data: []
}]
}
};
var controller = new Chart.controllers.polarArea(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
it('Should create arc elements for each data item during initialization', function() {
var chart = {
afterEach(function() {
window.releaseAllCharts();
});
it('should be constructed', function() {
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [
{ data: [] },
{ data: [] }
],
labels: []
}
});
var meta = chart.getDatasetMeta(1);
expect(meta.type).toEqual('polarArea');
expect(meta.data).toEqual([]);
expect(meta.hidden).toBe(null);
expect(meta.controller).not.toBe(undefined);
expect(meta.controller.index).toBe(1);
meta.controller.updateIndex(0);
expect(meta.controller.index).toBe(0);
});
it('should create arc elements for each data item during initialization', function() {
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'polarArea'
},
options: {
datasets: [
{ data: [] },
{ data: [10, 15, 0, -4] }
],
labels: []
}
};
});
var controller = new Chart.controllers.polarArea(chart, 0);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 arcs created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true);
var meta = chart.getDatasetMeta(1);
expect(meta.data.length).toBe(4); // 4 arcs created
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
});
it('should draw all elements', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'polarArea'
},
options: {
}
};
var controller = new Chart.controllers.polarArea(chart, 0);
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
controller.draw();
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
});
it('should update elements', function() {
var data = {
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.polarArea.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
}
});
// Update ticks & set physical dimensions
scale.update(300, 300);
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
var meta = chart.getDatasetMeta(0);
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'line'
spyOn(meta.data[0], 'draw');
spyOn(meta.data[1], 'draw');
spyOn(meta.data[2], 'draw');
spyOn(meta.data[3], 'draw');
chart.update();
expect(meta.data[0].draw.calls.count()).toBe(1);
expect(meta.data[1].draw.calls.count()).toBe(1);
expect(meta.data[2].draw.calls.count()).toBe(1);
expect(meta.data[3].draw.calls.count()).toBe(1);
});
it('should update elements when modifying data', function() {
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
@ -115,66 +95,32 @@ describe('Polar area controller tests', function() {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
},
},
scale: scale
};
var controller = new Chart.controllers.polarArea(chart, 0);
controller.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 59.5,
startAngle: -0.5 * Math.PI,
endAngle: 0,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
label: 'label1'
borderWidth: 1.2
}
}
}
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 80.75,
startAngle: 0,
endAngle: 0.5 * Math.PI,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
label: 'label2'
});
var meta = chart.getDatasetMeta(0);
expect(meta.data.length).toBe(4);
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 17,
startAngle: 0.5 * Math.PI,
endAngle: Math.PI,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
label: 'label3'
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 0,
startAngle: Math.PI,
endAngle: 1.5 * Math.PI,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
label: 'label4'
[ { o: 156, s: -0.5 * Math.PI, e: 0 },
{ o: 211, s: 0, e: 0.5 * Math.PI },
{ o: 45, s: 0.5 * Math.PI, e: Math.PI },
{ o: 0, s: Math.PI, e: 1.5 * Math.PI }
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(256);
expect(meta.data[i]._model.y).toBeCloseToPixel(272);
expect(meta.data[i]._model.innerRadius).toBeCloseToPixel(0);
expect(meta.data[i]._model.outerRadius).toBeCloseToPixel(expected.o);
expect(meta.data[i]._model.startAngle).toBe(expected.s);
expect(meta.data[i]._model.endAngle).toBe(expected.e);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
label: chart.data.labels[i]
}));
});
// arc styles
@ -182,122 +128,46 @@ describe('Polar area controller tests', function() {
chart.data.datasets[0].borderColor = 'rgb(56, 57, 58)';
chart.data.datasets[0].borderWidth = 1.123;
controller.update();
chart.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 59.5,
startAngle: -0.5 * Math.PI,
endAngle: 0,
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
label: 'label1'
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 80.75,
startAngle: 0,
endAngle: 0.5 * Math.PI,
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
label: 'label2'
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 17,
startAngle: 0.5 * Math.PI,
endAngle: Math.PI,
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
label: 'label3'
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 0,
startAngle: Math.PI,
endAngle: 1.5 * Math.PI,
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
label: 'label4'
});
for (var i = 0; i < 4; ++i) {
expect(meta.data[i]._model.backgroundColor).toBe('rgb(128, 129, 130)');
expect(meta.data[i]._model.borderColor).toBe('rgb(56, 57, 58)');
expect(meta.data[i]._model.borderWidth).toBe(1.123);
}
// arc styles
chart.data.datasets[0].metaData[0].custom = {
meta.data[0].custom = {
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
borderWidth: 0.787
};
controller.update();
chart.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 150,
y: 150,
innerRadius: 0,
outerRadius: 59.5,
expect(meta.data[0]._model.x).toBeCloseToPixel(256);
expect(meta.data[0]._model.y).toBeCloseToPixel(272);
expect(meta.data[0]._model.innerRadius).toBeCloseToPixel(0);
expect(meta.data[0]._model.outerRadius).toBeCloseToPixel(156);
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
startAngle: -0.5 * Math.PI,
endAngle: 0,
backgroundColor: 'rgb(0, 1, 3)',
borderWidth: 0.787,
borderColor: 'rgb(4, 6, 8)',
label: 'label1'
});
}));
});
it('should handle number of data point changes in update', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.polarArea.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.update(300, 300);
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'line'
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
@ -305,73 +175,46 @@ describe('Polar area controller tests', function() {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
},
},
scale: scale
};
borderWidth: 1.2
}
}
}
});
var controller = new Chart.controllers.polarArea(chart, 0);
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(4);
var meta = chart.getDatasetMeta(0);
expect(meta.data.length).toBe(4);
chart.data.datasets[0].data = [1, 2]; // remove 2 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(2);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
// remove 2 items
chart.data.labels = ['label1', 'label2'];
chart.data.datasets[0].data = [1, 2];
chart.update();
chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(5);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[4] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data.length).toBe(2);
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
// add 3 items
chart.data.labels = ['label1', 'label2', 'label3', 'label4', 'label5'];
chart.data.datasets[0].data = [1, 2, 3, 4, 5];
chart.update();
expect(meta.data.length).toBe(5);
expect(meta.data[0] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Arc).toBe(true);
expect(meta.data[4] instanceof Chart.elements.Arc).toBe(true);
});
it('should set arc hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.polarArea.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.update(300, 300);
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'line'
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
@ -379,18 +222,16 @@ describe('Polar area controller tests', function() {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
},
},
scale: scale
};
borderWidth: 1.2
}
}
}
});
var controller = new Chart.controllers.polarArea(chart, 0);
controller.update();
var arc = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
var arc = meta.data[0];
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(0, 230, 0)');
expect(arc._model.borderWidth).toBe(1.2);
@ -400,7 +241,7 @@ describe('Polar area controller tests', function() {
chart.data.datasets[0].hoverBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].hoverBorderWidth = 2.1;
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(arc._model.borderColor).toBe('rgb(123, 125, 127)');
expect(arc._model.borderWidth).toBe(2.1);
@ -412,50 +253,21 @@ describe('Polar area controller tests', function() {
hoverBorderColor: 'rgb(10, 10, 10)'
};
controller.setHoverStyle(arc);
meta.controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(10, 10, 10)');
expect(arc._model.borderWidth).toBe(5.5);
});
it('should remove hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.polarArea.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.update(300, 300);
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'line'
var chart = window.acquireChart({
type: 'polarArea',
data: {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
@ -463,22 +275,20 @@ describe('Polar area controller tests', function() {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.2,
},
},
},
scale: scale
};
borderWidth: 1.2
}
}
}
});
var controller = new Chart.controllers.polarArea(chart, 0);
controller.update();
var arc = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
var arc = meta.data[0];
chart.options.elements.arc.backgroundColor = 'rgb(45, 46, 47)';
chart.options.elements.arc.borderColor = 'rgb(50, 51, 52)';
chart.options.elements.arc.borderWidth = 10.1;
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(45, 46, 47)');
expect(arc._model.borderColor).toBe('rgb(50, 51, 52)');
expect(arc._model.borderWidth).toBe(10.1);
@ -488,7 +298,7 @@ describe('Polar area controller tests', function() {
chart.data.datasets[0].borderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].borderWidth = 2.1;
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(arc._model.borderColor).toBe('rgb(123, 125, 127)');
expect(arc._model.borderWidth).toBe(2.1);
@ -500,9 +310,9 @@ describe('Polar area controller tests', function() {
borderColor: 'rgb(10, 10, 10)'
};
controller.removeHoverStyle(arc);
meta.controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(10, 10, 10)');
expect(arc._model.borderWidth).toBe(5.5);
});
});
});

View file

@ -1,119 +1,92 @@
// Test the polar area controller
describe('Radar controller tests', function() {
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
afterEach(function() {
window.releaseAllCharts();
});
it('Should be constructed', function() {
var chart = {
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: []
}]
}],
labels: []
}
};
});
var controller = new Chart.controllers.radar(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
var meta = chart.getDatasetMeta(0);
expect(meta.type).toBe('radar');
expect(meta.controller).not.toBe(undefined);
expect(meta.controller.index).toBe(0);
expect(meta.data).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
meta.controller.updateIndex(1);
expect(meta.controller.index).toBe(1);
});
it('Should create arc elements for each data item during initialization', function() {
var chart = {
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 15, 0, -4]
data: [10, 15, 0, 4]
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
config: {
type: 'radar'
},
options: {
}
};
});
var controller = new Chart.controllers.radar(chart, 0);
// Line element
expect(chart.data.datasets[0].metaDataset instanceof Chart.elements.Line).toBe(true);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 points created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
var meta = chart.getDatasetMeta(0);
expect(meta.dataset instanceof Chart.elements.Line).toBe(true); // line element
expect(meta.data.length).toBe(4); // 4 points created
expect(meta.data[0] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[1] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[2] instanceof Chart.elements.Point).toBe(true);
expect(meta.data[3] instanceof Chart.elements.Point).toBe(true);
});
it('should draw all elements', function() {
var chart = {
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'radar'
},
options: {
data: [10, 15, 0, 4]
}],
labels: ['label1', 'label2', 'label3', 'label4']
}
};
});
var controller = new Chart.controllers.radar(chart, 0);
var meta = chart.getDatasetMeta(0);
spyOn(chart.data.datasets[0].metaDataset, 'draw');
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
spyOn(meta.dataset, 'draw');
spyOn(meta.data[0], 'draw');
spyOn(meta.data[1], 'draw');
spyOn(meta.data[2], 'draw');
spyOn(meta.data[3], 'draw');
controller.draw();
chart.update();
expect(chart.data.datasets[0].metaDataset.draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
expect(meta.dataset.draw.calls.count()).toBe(1);
expect(meta.data[0].draw.calls.count()).toBe(1);
expect(meta.data[1].draw.calls.count()).toBe(1);
expect(meta.data[2].draw.calls.count()).toBe(1);
expect(meta.data[3].draw.calls.count()).toBe(1);
});
it('should update elements', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.radar.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
scale.update(300, 300);
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'radar'
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
@ -140,15 +113,19 @@ describe('Radar controller tests', function() {
pointStyle: 'circle'
}
}
},
scale: scale
};
}
});
var controller = new Chart.controllers.radar(chart, 0);
controller.update();
var meta = chart.getDatasetMeta(0);
meta.controller.reset(); // reset first
// Line element
expect(chart.data.datasets[0].metaDataset._model).toEqual({
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
@ -158,97 +135,57 @@ describe('Radar controller tests', function() {
borderWidth: 1.2,
fill: true,
tension: 0.1,
}));
scaleTop: 0,
scaleBottom: 300,
scaleZero: {
x: 150,
y: 133
},
[
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
{ x: 256, y: 272, cppx: 256, cppy: 272, cpnx: 256, cpny: 272},
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
expect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);
expect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);
expect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);
expect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
}));
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
// Point
x: 150,
y: 91,
// Control points
controlPointPreviousX: 146.99829997808834,
controlPointPreviousY: 91,
controlPointNextX: 155.09829997808833,
controlPointNextY: 91,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
// Point
x: 231,
y: 150,
// Control points
controlPointPreviousX: 231,
controlPointPreviousY: 145.8377025234528,
controlPointNextX: 231,
controlPointNextY: 153.4377025234528,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
// Point
x: 150,
y: 167,
// Control points
controlPointPreviousX: 156.7197526476963,
controlPointPreviousY: 167,
controlPointNextX: 148.61975264769632,
controlPointNextY: 167,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
// Point
x: 150,
y: 150,
// Control points
controlPointPreviousX: 150,
controlPointPreviousY: 151.7,
controlPointNextX: 150,
controlPointNextY: 144.1,
// Now update controller and ensure proper updates
meta.controller.update();
[
{ x: 256, y: 133, cppx: 246, cppy: 133, cpnx: 272, cpny: 133 },
{ x: 464, y: 272, cppx: 464, cppy: 264, cpnx: 464, cpny: 278 },
{ x: 256, y: 272, cppx: 276.9, cppy: 272, cpnx: 250.4, cpny: 272 },
{ x: 200, y: 272, cppx: 200, cppy: 275, cpnx: 200, cpny: 261 },
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
expect(meta.data[i]._model.controlPointPreviousX).toBeCloseToPixel(expected.cppx);
expect(meta.data[i]._model.controlPointPreviousY).toBeCloseToPixel(expected.cppy);
expect(meta.data[i]._model.controlPointNextX).toBeCloseToPixel(expected.cpnx);
expect(meta.data[i]._model.controlPointNextY).toBeCloseToPixel(expected.cpny);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
pointStyle: 'circle',
skip: false,
tension: 0.1,
}));
});
// Use dataset level styles for lines & points
@ -269,9 +206,13 @@ describe('Radar controller tests', function() {
chart.data.datasets[0].pointBorderColor = 'rgb(56, 57, 58)';
chart.data.datasets[0].pointBorderWidth = 1.123;
controller.update();
meta.controller.update();
expect(chart.data.datasets[0].metaDataset._model).toEqual({
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(98, 98, 98)',
borderCapStyle: 'butt',
borderColor: 'rgb(8, 8, 8)',
@ -281,101 +222,32 @@ describe('Radar controller tests', function() {
borderWidth: 0.55,
fill: false,
tension: 0,
}));
scaleTop: 0,
scaleBottom: 300,
scaleZero: {
x: 150,
y: 133
}
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
pointStyle: 'circle',
skip: false,
tension: 0,
// Point
x: 150,
y: 91,
// Control points
controlPointPreviousX: 150,
controlPointPreviousY: 91,
controlPointNextX: 150,
controlPointNextY: 91,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
pointStyle: 'circle',
skip: false,
tension: 0,
// Point
x: 231,
y: 150,
// Control points
controlPointPreviousX: 231,
controlPointPreviousY: 150,
controlPointNextX: 231,
controlPointNextY: 150,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
pointStyle: 'circle',
skip: false,
tension: 0,
// Point
x: 150,
y: 167,
// Control points
controlPointPreviousX: 150,
controlPointPreviousY: 167,
controlPointNextX: 150,
controlPointNextY: 167,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
pointStyle: 'circle',
skip: false,
tension: 0,
// Point
x: 150,
y: 150,
// Control points
controlPointPreviousX: 150,
controlPointPreviousY: 150,
controlPointNextX: 150,
controlPointNextY: 150,
// Since tension is now 0, we don't care about the control points
[
{ x: 256, y: 133 },
{ x: 464, y: 272 },
{ x: 256, y: 272 },
{ x: 200, y: 272 },
].forEach(function(expected, i) {
expect(meta.data[i]._model.x).toBeCloseToPixel(expected.x);
expect(meta.data[i]._model.y).toBeCloseToPixel(expected.y);
expect(meta.data[i]._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
pointStyle: 'circle',
skip: false,
tension: 0,
}));
});
// Use custom styles for lines & first point
chart.data.datasets[0].metaDataset.custom = {
meta.dataset.custom = {
tension: 0.25,
backgroundColor: 'rgb(55, 55, 54)',
borderColor: 'rgb(8, 7, 6)',
@ -388,7 +260,7 @@ describe('Radar controller tests', function() {
};
// point styles
chart.data.datasets[0].metaData[0].custom = {
meta.data[0].custom = {
radius: 2.2,
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
@ -398,9 +270,13 @@ describe('Radar controller tests', function() {
hitRadius: 5,
};
controller.update();
meta.controller.update();
expect(chart.data.datasets[0].metaDataset._model).toEqual({
expect(meta.dataset._model.scaleTop).toBeCloseToPixel(32);
expect(meta.dataset._model.scaleBottom).toBeCloseToPixel(512);
expect(meta.dataset._model.scaleZero.x).toBeCloseToPixel(256);
expect(meta.dataset._model.scaleZero.y).toBeCloseToPixel(272);
expect(meta.dataset._model).toEqual(jasmine.objectContaining({
backgroundColor: 'rgb(55, 55, 54)',
borderCapStyle: 'square',
borderColor: 'rgb(8, 7, 6)',
@ -410,166 +286,36 @@ describe('Radar controller tests', function() {
borderWidth: 0.3,
fill: true,
tension: 0.25,
}));
scaleTop: 0,
scaleBottom: 300,
scaleZero: {
x: 150,
y: 133
},
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: 'rgb(0, 1, 3)',
borderWidth: 0.787,
borderColor: 'rgb(4, 6, 8)',
hitRadius: 5,
expect(meta.data[0]._model.x).toBeCloseToPixel(256);
expect(meta.data[0]._model.y).toBeCloseToPixel(133);
expect(meta.data[0]._model.controlPointPreviousX).toBeCloseToPixel(241);
expect(meta.data[0]._model.controlPointPreviousY).toBeCloseToPixel(133);
expect(meta.data[0]._model.controlPointNextX).toBeCloseToPixel(281);
expect(meta.data[0]._model.controlPointNextY).toBeCloseToPixel(133);
expect(meta.data[0]._model).toEqual(jasmine.objectContaining({
radius: 2.2,
pointStyle: 'circle',
skip: true,
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
tension: 0.15,
// Point
x: 150,
y: 91,
// Control points
controlPointPreviousX: 145.4974499671325,
controlPointPreviousY: 91,
controlPointNextX: 157.6474499671325,
controlPointNextY: 91,
});
});
it('should handle number of data point changes in update', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.radar.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
scale.update(300, 300);
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'radar'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
tension: 0.1,
},
point: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
},
scale: scale
};
var controller = new Chart.controllers.radar(chart, 0);
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(4);
chart.data.datasets[0].data = [1, 2]; // remove 2 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(2);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(5);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[4] instanceof Chart.elements.Point).toBe(true);
skip: true,
hitRadius: 5,
}));
});
it('should set point hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.radar.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
scale.update(300, 300);
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'radar'
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
@ -593,15 +339,16 @@ describe('Radar controller tests', function() {
radius: 3,
}
}
},
scale: scale
};
}
});
var controller = new Chart.controllers.radar(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
controller.setHoverStyle(point);
meta.controller.update(); // reset first
var point = meta.data[0];
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
expect(point._model.borderWidth).toBe(1);
@ -613,7 +360,7 @@ describe('Radar controller tests', function() {
chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].pointHoverBorderWidth = 2.1;
controller.setHoverStyle(point);
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
@ -627,7 +374,7 @@ describe('Radar controller tests', function() {
hoverBorderColor: 'rgb(10, 10, 10)'
};
controller.setHoverStyle(point);
meta.controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);
@ -636,46 +383,16 @@ describe('Radar controller tests', function() {
it('should remove hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
scaleConfig = Chart.helpers.scaleMerge(scaleConfig, Chart.defaults.radar.scale);
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: data
},
});
// Update ticks & set physical dimensions
scale.top = 0;
scale.left = 0;
scale.right = 300;
scale.bottom = 300;
scale.update(300, 300);
var chart = {
chartArea: {
bottom: 300,
left: 0,
right: 300,
top: 0
},
data: data,
config: {
type: 'radar'
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label1', 'label2', 'label3', 'label4']
},
options: {
showLines: true,
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
@ -699,20 +416,21 @@ describe('Radar controller tests', function() {
radius: 3,
}
}
},
scale: scale
};
}
});
var controller = new Chart.controllers.radar(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
var meta = chart.getDatasetMeta(0);
meta.controller.update(); // reset first
var point = meta.data[0];
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
chart.options.elements.point.borderWidth = 10.1;
chart.options.elements.point.radius = 1.01;
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
expect(point._model.borderWidth).toBe(10.1);
@ -724,7 +442,7 @@ describe('Radar controller tests', function() {
chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].pointBorderWidth = 2.1;
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
@ -738,7 +456,7 @@ describe('Radar controller tests', function() {
borderColor: 'rgb(10, 10, 10)'
};
controller.removeHoverStyle(point);
meta.controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);

View file

@ -6,7 +6,7 @@ describe('Core helper tests', function() {
helpers = window.Chart.helpers;
});
it('Should iterate over an array and pass the extra data to that function', function() {
it('should iterate over an array and pass the extra data to that function', function() {
var testData = [0, 9, "abc"];
var scope = {}; // fake out the scope and ensure that 'this' is the correct thing
@ -33,7 +33,7 @@ describe('Core helper tests', function() {
expect(iterated.slice().reverse()).toEqual(testData);
});
it('Should iterate over properties in an object', function() {
it('should iterate over properties in an object', function() {
var testData = {
myProp1: 'abc',
myProp2: 276,
@ -59,7 +59,7 @@ describe('Core helper tests', function() {
}).not.toThrow();
});
it('Should clone an object', function() {
it('should clone an object', function() {
var testData = {
myProp1: 'abc',
myProp2: ['a', 'b'],
@ -98,7 +98,7 @@ describe('Core helper tests', function() {
});
});
it('Should merge a normal config without scales', function() {
it('should merge a normal config without scales', function() {
var baseConfig = {
valueProp: 5,
arrayProp: [1, 2, 3, 4, 5, 6],
@ -161,7 +161,7 @@ describe('Core helper tests', function() {
});
});
it('Should merge scale configs', function() {
it('should merge scale configs', function() {
var baseConfig = {
scales: {
prop1: {
@ -217,6 +217,7 @@ describe('Core helper tests', function() {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
tickMarkLength: 10,
lineWidth: 1,
offsetGridLines: false,
display: true,
@ -246,7 +247,8 @@ describe('Core helper tests', function() {
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
drawTicks: true, // draw ticks extending towards the label,
tickMarkLength: 10,
lineWidth: 1,
offsetGridLines: false,
display: true,
@ -301,7 +303,7 @@ describe('Core helper tests', function() {
expect(helpers.findPreviousWhere(data, callback, 0)).toBe(undefined);
});
it('Should get the correct sign', function() {
it('should get the correct sign', function() {
expect(helpers.sign(0)).toBe(0);
expect(helpers.sign(10)).toBe(1);
expect(helpers.sign(-5)).toBe(-1);
@ -320,11 +322,12 @@ describe('Core helper tests', function() {
expect(helpers.almostEquals(1e30, 1e30 + Number.EPSILON, 2 * Number.EPSILON)).toBe(true);
});
it('Should generate ids', function() {
expect(helpers.uid()).toBe('chart-0');
expect(helpers.uid()).toBe('chart-1');
expect(helpers.uid()).toBe('chart-2');
expect(helpers.uid()).toBe('chart-3');
it('should generate integer ids', function() {
var uid = helpers.uid();
expect(uid).toEqual(jasmine.any(Number));
expect(helpers.uid()).toBe(uid + 1);
expect(helpers.uid()).toBe(uid + 2);
expect(helpers.uid()).toBe(uid + 3);
});
it('should detect a number', function() {

View file

@ -1,360 +1,244 @@
// Tests of the scale service
describe('Test the layout service', function() {
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
afterEach(function() {
window.releaseAllCharts();
});
it('should fit a simple chart with 2 scales', function() {
var chartInstance = {
boxes: [],
};
var xScaleID = 'xScale';
var yScaleID = 'yScale';
var mockData = {
datasets: [{
yAxisID: yScaleID,
data: [10, 5, 0, 25, 78, -10]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
chart: {
data: mockData
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [
{ data: [10, 5, 0, 25, 78, -10] }
],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
},
id: xScaleID
options: {
scales: {
xAxes: [{
id: 'xScale',
type: 'category'
}],
yAxes: [{
id: 'yScale',
type: 'linear'
}]
}
}
}, {
height: '150px',
width: '250px'
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
chart: {
data: mockData
},
id: yScaleID
});
chartInstance.boxes.push(xScale);
chartInstance.boxes.push(yScale);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 50,
right: 250,
top: 0,
bottom: 83.6977778440511,
});
expect(chart.chartArea.bottom).toBeCloseToPixel(112);
expect(chart.chartArea.left).toBeCloseToPixel(41);
expect(chart.chartArea.right).toBeCloseToPixel(250);
expect(chart.chartArea.top).toBeCloseToPixel(32);
// Is xScale at the right spot
expect(xScale.left).toBe(50);
expect(xScale.right).toBe(250);
expect(xScale.top).toBe(83.6977778440511);
expect(xScale.bottom).toBe(150);
expect(xScale.labelRotation).toBe(50);
expect(chart.scales.xScale.bottom).toBeCloseToPixel(150);
expect(chart.scales.xScale.left).toBeCloseToPixel(41);
expect(chart.scales.xScale.right).toBeCloseToPixel(250);
expect(chart.scales.xScale.top).toBeCloseToPixel(112);
expect(chart.scales.xScale.labelRotation).toBeCloseTo(25);
// Is yScale at the right spot
expect(yScale.left).toBe(0);
expect(yScale.right).toBe(50);
expect(yScale.top).toBe(0);
expect(yScale.bottom).toBe(83.6977778440511);
expect(chart.scales.yScale.bottom).toBeCloseToPixel(112);
expect(chart.scales.yScale.left).toBeCloseToPixel(0);
expect(chart.scales.yScale.right).toBeCloseToPixel(41);
expect(chart.scales.yScale.top).toBeCloseToPixel(32);
expect(chart.scales.yScale.labelRotation).toBeCloseTo(0);
});
it('should fit scales that are in the top and right positions', function() {
var chartInstance = {
boxes: [],
};
var xScaleID = 'xScale';
var yScaleID = 'yScale';
var mockData = {
datasets: [{
yAxisID: yScaleID,
data: [10, 5, 0, 25, 78, -10]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
xScaleConfig.position = 'top';
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
chart: {
data: mockData
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [
{ data: [10, 5, 0, 25, 78, -10] }
],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
},
id: xScaleID
options: {
scales: {
xAxes: [{
id: 'xScale',
type: 'category',
position: 'top'
}],
yAxes: [{
id: 'yScale',
type: 'linear',
position: 'right'
}]
}
}
}, {
height: '150px',
width: '250px'
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
yScaleConfig.position = 'right';
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
chart: {
data: mockData
},
id: yScaleID
});
chartInstance.boxes.push(xScale);
chartInstance.boxes.push(yScale);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 0,
right: 200,
top: 66.3022221559489,
bottom: 150,
});
expect(chart.chartArea.bottom).toBeCloseToPixel(150);
expect(chart.chartArea.left).toBeCloseToPixel(0);
expect(chart.chartArea.right).toBeCloseToPixel(209);
expect(chart.chartArea.top).toBeCloseToPixel(71);
// Is xScale at the right spot
expect(xScale.left).toBe(0);
expect(xScale.right).toBe(200);
expect(xScale.top).toBe(0);
expect(xScale.bottom).toBe(66.3022221559489);
expect(xScale.labelRotation).toBe(50);
expect(chart.scales.xScale.bottom).toBeCloseToPixel(71);
expect(chart.scales.xScale.left).toBeCloseToPixel(0);
expect(chart.scales.xScale.right).toBeCloseToPixel(209);
expect(chart.scales.xScale.top).toBeCloseToPixel(32);
expect(chart.scales.xScale.labelRotation).toBeCloseTo(25);
// Is yScale at the right spot
expect(yScale.left).toBe(200);
expect(yScale.right).toBe(250);
expect(yScale.top).toBe(66.3022221559489);
expect(yScale.bottom).toBe(150);
expect(chart.scales.yScale.bottom).toBeCloseToPixel(150);
expect(chart.scales.yScale.left).toBeCloseToPixel(209);
expect(chart.scales.yScale.right).toBeCloseToPixel(250);
expect(chart.scales.yScale.top).toBeCloseToPixel(71);
expect(chart.scales.yScale.labelRotation).toBeCloseTo(0);
});
it('should fit scales that overlap the chart area', function() {
var chart = window.acquireChart({
type: 'radar',
data: {
datasets: [{
data: [10, 5, 0, 25, 78, -10]
}, {
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
}
});
expect(chart.chartArea.bottom).toBeCloseToPixel(512);
expect(chart.chartArea.left).toBeCloseToPixel(0);
expect(chart.chartArea.right).toBeCloseToPixel(512);
expect(chart.chartArea.top).toBeCloseToPixel(32);
expect(chart.scale.bottom).toBeCloseToPixel(512);
expect(chart.scale.left).toBeCloseToPixel(0);
expect(chart.scale.right).toBeCloseToPixel(512);
expect(chart.scale.top).toBeCloseToPixel(32);
expect(chart.scale.width).toBeCloseToPixel(512);
expect(chart.scale.height).toBeCloseToPixel(480)
});
it('should fit multiple axes in the same position', function() {
var chartInstance = {
boxes: [],
};
var xScaleID = 'xScale';
var yScaleID1 = 'yScale1';
var yScaleID2 = 'yScale2';
var mockData = {
datasets: [{
yAxisID: yScaleID1,
data: [10, 5, 0, 25, 78, -10]
}, {
yAxisID: yScaleID2,
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
chart: {
data: mockData
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
yAxisID: 'yScale1',
data: [10, 5, 0, 25, 78, -10]
}, {
yAxisID: 'yScale2',
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
},
id: xScaleID
options: {
scales: {
xAxes: [{
id: 'xScale',
type: 'category'
}],
yAxes: [{
id: 'yScale1',
type: 'linear'
}, {
id: 'yScale2',
type: 'linear'
}]
}
}
}, {
height: '150px',
width: '250px'
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale1 = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
chart: {
data: mockData
},
id: yScaleID1
});
var yScale2 = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
chart: {
data: mockData
},
id: yScaleID2
});
chartInstance.boxes.push(xScale);
chartInstance.boxes.push(yScale1);
chartInstance.boxes.push(yScale2);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 110,
right: 250,
top: 0,
bottom: 83.6977778440511,
});
expect(chart.chartArea.bottom).toBeCloseToPixel(102);
expect(chart.chartArea.left).toBeCloseToPixel(86);
expect(chart.chartArea.right).toBeCloseToPixel(250);
expect(chart.chartArea.top).toBeCloseToPixel(32);
// Is xScale at the right spot
expect(xScale.left).toBe(110);
expect(xScale.right).toBe(250);
expect(xScale.top).toBe(83.6977778440511);
expect(xScale.bottom).toBe(150);
expect(chart.scales.xScale.bottom).toBeCloseToPixel(150);
expect(chart.scales.xScale.left).toBeCloseToPixel(86);
expect(chart.scales.xScale.right).toBeCloseToPixel(250);
expect(chart.scales.xScale.top).toBeCloseToPixel(103);
expect(chart.scales.xScale.labelRotation).toBeCloseTo(50);
// Are yScales at the right spot
expect(yScale1.left).toBe(0);
expect(yScale1.right).toBe(50);
expect(yScale1.top).toBe(0);
expect(yScale1.bottom).toBe(83.6977778440511);
expect(chart.scales.yScale1.bottom).toBeCloseToPixel(102);
expect(chart.scales.yScale1.left).toBeCloseToPixel(0);
expect(chart.scales.yScale1.right).toBeCloseToPixel(41);
expect(chart.scales.yScale1.top).toBeCloseToPixel(32);
expect(chart.scales.yScale1.labelRotation).toBeCloseTo(0);
expect(yScale2.left).toBe(50);
expect(yScale2.right).toBe(110);
expect(yScale2.top).toBe(0);
expect(yScale2.bottom).toBe(83.6977778440511);
});
// This is an oddball case. What happens is, when the scales are fit the first time they must fit within the assigned size. In this case,
// the labels on the xScale need to rotate to fit. However, when the scales are fit again after the width of the left axis is determined,
// the labels do not need to rotate. Previously, the chart was too small because the chartArea did not expand to take up the space freed up
// due to the lack of label rotation
it('should fit scales that overlap the chart area', function() {
var chartInstance = {
boxes: [],
};
var scaleID = 'scaleID';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78, -10]
}, {
yAxisID: scaleID,
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var scaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
var ScaleConstructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new ScaleConstructor({
ctx: mockContext,
options: scaleConfig,
chart: {
data: mockData
},
id: scaleID
});
chartInstance.boxes.push(scale);
var canvasWidth = 300;
var canvasHeight = 350;
Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 0,
right: 300,
top: 0,
bottom: 350,
});
expect(scale.left).toBe(0);
expect(scale.right).toBe(300);
expect(scale.top).toBe(0);
expect(scale.bottom).toBe(350);
expect(scale.width).toBe(300);
expect(scale.height).toBe(350)
expect(chart.scales.yScale2.bottom).toBeCloseToPixel(102);
expect(chart.scales.yScale2.left).toBeCloseToPixel(41);
expect(chart.scales.yScale2.right).toBeCloseToPixel(86);
expect(chart.scales.yScale2.top).toBeCloseToPixel(32);
expect(chart.scales.yScale2.labelRotation).toBeCloseTo(0);
});
it ('should fix a full width box correctly', function() {
var chartInstance = {
boxes: [],
};
var xScaleID1= 'xScale1';
var xScaleID2 = 'xScale2';
var yScaleID = 'yScale2';
var mockData = {
datasets: [{
xAxisID: xScaleID1,
data: [10, 5, 0, 25, 78, -10]
}, {
xAxisID: xScaleID2,
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var mockContext = window.createMockContext();
var xScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var XConstructor = Chart.scaleService.getScaleConstructor('category');
var xScale1 = new XConstructor({
ctx: mockContext,
options: xScaleConfig,
chart: {
data: mockData
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
xAxisID: 'xScale1',
data: [10, 5, 0, 25, 78, -10]
}, {
xAxisID: 'xScale2',
data: [-19, -20, 0, -99, -50, 0]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5', 'tick6']
},
id: xScaleID1
});
var xScale2 = new XConstructor({
ctx: mockContext,
options: Chart.helpers.extend(Chart.helpers.clone(xScaleConfig), {
position: 'top',
fullWidth: true
}),
chart: {
data: mockData,
},
id: xScaleID2
options: {
scales: {
xAxes: [{
id: 'xScale1',
type: 'category'
}, {
id: 'xScale2',
type: 'category',
position: 'top',
fullWidth: true
}],
yAxes: [{
id: 'yScale',
type: 'linear'
}]
}
}
});
var yScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
var YConstructor = Chart.scaleService.getScaleConstructor('linear');
var yScale = new YConstructor({
ctx: mockContext,
options: yScaleConfig,
chart: {
data: mockData
},
id: yScaleID
});
chartInstance.boxes.push(xScale1);
chartInstance.boxes.push(xScale2);
chartInstance.boxes.push(yScale);
var canvasWidth = 250;
var canvasHeight = 150;
Chart.layoutService.update(chartInstance, canvasWidth, canvasHeight);
expect(chartInstance.chartArea).toEqual({
left: 60,
right: 250,
top: 54.495963211660246,
bottom: 83.6977778440511
});
expect(chart.chartArea.bottom).toBeCloseToPixel(484);
expect(chart.chartArea.left).toBeCloseToPixel(45);
expect(chart.chartArea.right).toBeCloseToPixel(512);
expect(chart.chartArea.top).toBeCloseToPixel(60);
// Are xScales at the right spot
expect(xScale1.left).toBe(60);
expect(xScale1.right).toBe(250);
expect(xScale1.top).toBeCloseTo(83.69, 1e-3);
expect(xScale1.bottom).toBe(150);
expect(chart.scales.xScale1.bottom).toBeCloseToPixel(512);
expect(chart.scales.xScale1.left).toBeCloseToPixel(45);
expect(chart.scales.xScale1.right).toBeCloseToPixel(512);
expect(chart.scales.xScale1.top).toBeCloseToPixel(484);
expect(xScale2.left).toBe(0);
expect(xScale2.right).toBe(250);
expect(xScale2.top).toBe(0);
expect(xScale2.bottom).toBeCloseTo(54.49, 1e-3);
expect(chart.scales.xScale2.bottom).toBeCloseToPixel(28);
expect(chart.scales.xScale2.left).toBeCloseToPixel(0);
expect(chart.scales.xScale2.right).toBeCloseToPixel(512);
expect(chart.scales.xScale2.top).toBeCloseToPixel(0);
// Is yScale at the right spot
expect(yScale.left).toBe(0);
expect(yScale.right).toBe(60);
expect(yScale.top).toBeCloseTo(54.49, 1e-3);
expect(yScale.bottom).toBeCloseTo(83.69, 1e-3);
expect(chart.scales.yScale.bottom).toBeCloseToPixel(484);
expect(chart.scales.yScale.left).toBeCloseToPixel(0);
expect(chart.scales.yScale.right).toBeCloseToPixel(45);
expect(chart.scales.yScale.top).toBeCloseToPixel(60);
});
});

View file

@ -1,6 +1,14 @@
// Test the rectangle element
describe('Legend block tests', function() {
beforeEach(function() {
window.addDefaultMatchers(jasmine);
});
afterEach(function() {
window.releaseAllCharts();
});
it('Should be constructed', function() {
var legend = new Chart.Legend({});
expect(legend).not.toBe(undefined);
@ -25,42 +33,35 @@ describe('Legend block tests', function() {
});
it('should update correctly', function() {
var chart = {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
label: 'dataset1',
backgroundColor: '#f31',
borderCapStyle: 'butt',
borderDash: [2, 2],
borderDashOffset: 5.5
borderDashOffset: 5.5,
data: []
}, {
label: 'dataset2',
hidden: true,
borderJoinStyle: 'miter',
data: []
}, {
label: 'dataset3',
borderWidth: 10,
borderColor: 'green'
}]
borderColor: 'green',
data: []
}],
labels: []
}
};
var context = window.createMockContext();
var options = Chart.helpers.clone(Chart.defaults.global.legend);
var legend = new Chart.Legend({
chart: chart,
ctx: context,
options: options
});
var minSize = legend.update(400, 200);
expect(minSize).toEqual({
width: 400,
height: 54
});
expect(legend.legendItems).toEqual([{
expect(chart.legend.legendItems).toEqual([{
text: 'dataset1',
fillStyle: '#f31',
hidden: undefined,
hidden: false,
lineCap: 'butt',
lineDash: [2, 2],
lineDashOffset: 5.5,
@ -82,7 +83,7 @@ describe('Legend block tests', function() {
}, {
text: 'dataset3',
fillStyle: undefined,
hidden: undefined,
hidden: false,
lineCap: undefined,
lineDash: undefined,
lineDashOffset: undefined,
@ -94,57 +95,59 @@ describe('Legend block tests', function() {
});
it('should draw correctly', function() {
var chart = {
var chart = window.acquireChart({
type: 'bar',
data: {
datasets: [{
label: 'dataset1',
backgroundColor: '#f31',
borderCapStyle: 'butt',
borderDash: [2, 2],
borderDashOffset: 5.5
borderDashOffset: 5.5,
data: []
}, {
label: 'dataset2',
hidden: true,
borderJoinStyle: 'miter',
data: []
}, {
label: 'dataset3',
borderWidth: 10,
borderColor: 'green'
}]
borderColor: 'green',
data: []
}],
labels: []
}
};
var context = window.createMockContext();
var options = Chart.helpers.clone(Chart.defaults.global.legend);
var legend = new Chart.Legend({
chart: chart,
ctx: context,
options: options
});
var minSize = legend.update(400, 200);
legend.left = 50;
legend.top = 100;
legend.right = legend.left + minSize.width;
legend.bottom = legend.top + minSize.height;
expect(chart.legend.legendHitBoxes.length).toBe(3);
legend.draw();
expect(legend.legendHitBoxes).toEqual([{
left: 114,
top: 110,
width: 126,
height: 12
[ { h: 12, l: 101, t: 10, w: 93 },
{ h: 12, l: 205, t: 10, w: 93 },
{ h: 12, l: 308, t: 10, w: 93 }
].forEach(function(expected, i) {
expect(chart.legend.legendHitBoxes[i].height).toBeCloseToPixel(expected.h);
expect(chart.legend.legendHitBoxes[i].left).toBeCloseToPixel(expected.l);
expect(chart.legend.legendHitBoxes[i].top).toBeCloseToPixel(expected.t);
expect(chart.legend.legendHitBoxes[i].width).toBeCloseToPixel(expected.w);
})
// NOTE(SB) We should get ride of the following tests and use image diff instead.
// For now, as discussed with Evert Timberg, simply comment out.
// See http://humblesoftware.github.io/js-imagediff/test.html
/*chart.legend.ctx = window.createMockContext();
chart.update();
expect(chart.legend.ctx .getCalls()).toEqual([{
"name": "measureText",
"args": ["dataset1"]
}, {
left: 250,
top: 110,
width: 126,
height: 12
"name": "measureText",
"args": ["dataset2"]
}, {
"name": "measureText",
"args": ["dataset3"]
}, {
left: 182,
top: 132,
width: 126,
height: 12
}]);
expect(context.getCalls()).toEqual([{
"name": "measureText",
"args": ["dataset1"]
}, {
@ -300,6 +303,6 @@ describe('Legend block tests', function() {
}, {
"name": "fillText",
"args": ["dataset3", 228, 132]
}]);
}]);*/
});
});

View file

@ -0,0 +1,43 @@
// Plugin tests
describe('Test the plugin system', function() {
beforeEach(function() {
Chart.plugins = [];
});
it ('Should register plugins', function() {
var myplugin = {};
Chart.pluginService.register(myplugin);
expect(Chart.plugins.length).toBe(1);
// Should only add plugin once
Chart.pluginService.register(myplugin);
expect(Chart.plugins.length).toBe(1);
});
it ('Should allow unregistering plugins', function() {
var myplugin = {};
Chart.pluginService.register(myplugin);
expect(Chart.plugins.length).toBe(1);
// Should only add plugin once
Chart.pluginService.remove(myplugin);
expect(Chart.plugins.length).toBe(0);
// Removing a plugin that doesn't exist should not error
Chart.pluginService.remove(myplugin);
});
it ('Should allow notifying plugins', function() {
var myplugin = {
count: 0,
trigger: function(chart) {
myplugin.count = chart.count;
}
};
Chart.pluginService.register(myplugin);
Chart.pluginService.notifyPlugins('trigger', [{ count: 10 }]);
expect(myplugin.count).toBe(10);
});
});

View file

@ -63,7 +63,7 @@ describe('Test the doughnut chart default config', function() {
}]
}
};
var expectedLegend = '<ul class="mychart-legend"><li><span style="background-color:red">label1</span></li><li><span style="background-color:green">label2</span></li></ul>';
var expectedLegend = '<ul class="mychart-legend"><li><span style="background-color:red"></span>label1</li><li><span style="background-color:green"></span>label2</li></ul>';
expect(config.legendCallback(chart)).toBe(expectedLegend);
});
@ -74,7 +74,8 @@ describe('Test the doughnut chart default config', function() {
labels: ['label1', 'label2', 'label3'],
datasets: [{
data: [10, 20, NaN],
backgroundColor: ['red', 'green', 'blue']
backgroundColor: ['red', 'green', 'blue'],
metaData: [{}, {}, {}]
}]
};
@ -82,20 +83,37 @@ describe('Test the doughnut chart default config', function() {
text: 'label1',
fillStyle: 'red',
hidden: false,
index: 0
index: 0,
strokeStyle: '#000',
lineWidth: 2
}, {
text: 'label2',
fillStyle: 'green',
hidden: false,
index: 1
index: 1,
strokeStyle: '#000',
lineWidth: 2
}, {
text: 'label3',
fillStyle: 'blue',
hidden: true,
index: 2
index: 2,
strokeStyle: '#000',
lineWidth: 2
}];
expect(config.legend.labels.generateLabels(data)).toEqual(expected);
var chart = {
data: data,
options: {
elements: {
arc: {
borderWidth: 2,
borderColor: '#000'
}
}
}
};
expect(config.legend.labels.generateLabels.call({ chart: chart }, data)).toEqual(expected);
});
it('should hide the correct arc when a legend item is clicked', function() {
@ -189,7 +207,8 @@ describe('Test the polar area chart default config', function() {
labels: ['label1', 'label2', 'label3'],
datasets: [{
data: [10, 20, NaN],
backgroundColor: ['red', 'green', 'blue']
backgroundColor: ['red', 'green', 'blue'],
metaData: [{}, {}, {}]
}]
};
@ -197,20 +216,37 @@ describe('Test the polar area chart default config', function() {
text: 'label1',
fillStyle: 'red',
hidden: false,
index: 0
index: 0,
strokeStyle: '#000',
lineWidth: 2
}, {
text: 'label2',
fillStyle: 'green',
hidden: false,
index: 1
index: 1,
strokeStyle: '#000',
lineWidth: 2
}, {
text: 'label3',
fillStyle: 'blue',
hidden: true,
index: 2
index: 2,
strokeStyle: '#000',
lineWidth: 2
}];
expect(config.legend.labels.generateLabels(data)).toEqual(expected);
var chart = {
data: data,
options: {
elements: {
arc: {
borderWidth: 2,
borderColor: '#000'
}
}
}
};
expect(config.legend.labels.generateLabels.call({ chart: chart }, data)).toEqual(expected);
});
it('should hide the correct arc when a legend item is clicked', function() {
@ -254,4 +290,4 @@ describe('Test the polar area chart default config', function() {
config.legend.onClick.call(scope, null, legendItem);
expect(chart.data.datasets[0].data).toEqual([10, 20, NaN]);
});
});
});

View file

@ -57,7 +57,7 @@
},
});
};
Context.prototype._initMethods = function() {
// define methods to test here
// no way to introspect so we have to do some extra work :(
@ -121,4 +121,118 @@
window.createMockContext = function() {
return new Context();
};
})();
// Custom matcher
function toBeCloseToPixel() {
return {
compare: function(actual, expected) {
var result = false;
if (!isNaN(actual) && !isNaN(expected)) {
var diff = Math.abs(actual - expected);
var A = Math.abs(actual);
var B = Math.abs(expected);
var percentDiff = 0.005; // 0.5% diff
result = (diff <= (A > B ? A : B) * percentDiff) || diff < 2; // 2 pixels is fine
}
return { pass: result };
}
}
};
function toEqualOneOf() {
return {
compare: function(actual, expecteds) {
var result = false;
for (var i = 0, l = expecteds.length; i < l; i++) {
if (actual === expecteds[i]) {
result = true;
break;
}
}
return {
pass: result
};
}
};
}
window.addDefaultMatchers = function(jasmine) {
jasmine.addMatchers({
toBeCloseToPixel: toBeCloseToPixel,
toEqualOneOf: toEqualOneOf
});
}
// Canvas injection helpers
var charts = {};
function acquireChart(config, style) {
var wrapper = document.createElement("div");
var canvas = document.createElement("canvas");
wrapper.className = 'chartjs-wrapper';
style = style || { height: '512px', width: '512px' };
for (var k in style) {
wrapper.style[k] = style[k];
canvas.style[k] = style[k];
}
canvas.height = canvas.style.height && parseInt(canvas.style.height);
canvas.width = canvas.style.width && parseInt(canvas.style.width);
// by default, remove chart animation and auto resize
var options = config.options = config.options || {};
options.animation = options.animation === undefined? false : options.animation;
options.responsive = options.responsive === undefined? false : options.responsive;
options.defaultFontFamily = options.defaultFontFamily || 'Arial';
wrapper.appendChild(canvas);
window.document.body.appendChild(wrapper);
var chart = new Chart(canvas.getContext("2d"), config);
charts[chart.id] = chart;
return chart;
}
function releaseChart(chart) {
chart.chart.canvas.parentNode.remove();
delete charts[chart.id];
delete chart;
}
function releaseAllCharts(scope) {
for (var id in charts) {
var chart = charts[id];
releaseChart(chart);
}
}
function injectCSS(css) {
// http://stackoverflow.com/q/3922139
var head = document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.setAttribute('type', 'text/css');
if (style.styleSheet) { // IE
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
}
window.acquireChart = acquireChart;
window.releaseChart = releaseChart;
window.releaseAllCharts = releaseAllCharts;
// some style initialization to limit differences between browsers across different plateforms.
injectCSS(
'.chartjs-wrapper, .chartjs-wrapper canvas {' +
'border: 0;' +
'margin: 0;' +
'padding: 0;' +
'}' +
'.chartjs-wrapper {' +
'position: absolute' +
'}');
})();

View file

@ -16,6 +16,7 @@ describe('Category scale tests', function() {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
tickMarkLength: 10,
lineWidth: 1,
offsetGridLines: false,
display: true,
@ -66,6 +67,7 @@ describe('Category scale tests', function() {
id: scaleID
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.labels);
});
@ -92,6 +94,7 @@ describe('Category scale tests', function() {
id: scaleID
});
scale.determineDataLimits();
scale.buildTicks();
expect(scale.getLabelForIndex(1)).toBe('tick2');
@ -143,17 +146,23 @@ describe('Category scale tests', function() {
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(85);
expect(scale.getValueForPixel(33)).toBe(0);
expect(scale.getValueForPixel(85)).toBe(0);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(452);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(505);
expect(scale.getValueForPixel(452)).toBe(4);
expect(scale.getValueForPixel(505)).toBe(4);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(33);
expect(scale.getValueForPixel(33)).toBe(0);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(557);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(557);
expect(scale.getValueForPixel(557)).toBe(4);
});
it ('Should get the correct pixel for a value when horizontal and zoomed', function() {
@ -265,17 +274,22 @@ describe('Category scale tests', function() {
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(30);
expect(scale.getValueForPixel(11)).toBe(0);
expect(scale.getValueForPixel(30)).toBe(0);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(161);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(180);
expect(scale.getValueForPixel(161)).toBe(4);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(11);
expect(scale.getValueForPixel(11)).toBe(0);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(199);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(199);
expect(scale.getValueForPixel(199)).toBe(4);
});
it ('should get the correct pixel for a value when vertical and zoomed', function() {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,27 +1,36 @@
// Time scale tests
describe('Time scale tests', function() {
var chartInstance;
beforeEach(function() {
window.addDefaultMatchers(jasmine);
// Need a time matcher for getValueFromPixel
jasmine.addMatchers({
toEqualOneOf: function() {
toBeCloseToTime: function() {
return {
compare: function(actual, expecteds) {
compare: function(actual, expected) {
var result = false;
for (var i = 0, l = expecteds.length; i < l; i++) {
if (actual === expecteds[i]) {
result = true;
break;
}
}
var diff = actual.diff(expected.value, expected.unit, true);
result = Math.abs(diff) < (expected.threshold !== undefined ? expected.threshold : 0.5);
return {
pass: result
};
}
};
}
}
});
});
afterEach(function() {
if (chartInstance)
{
releaseChart(chartInstance);
}
});
it('Should load moment.js as a dependency', function() {
expect(window.moment).not.toBe(undefined);
});
@ -40,6 +49,7 @@ describe('Time scale tests', function() {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true,
tickMarkLength: 10,
lineWidth: 1,
offsetGridLines: false,
display: true,
@ -108,7 +118,7 @@ describe('Time scale tests', function() {
scale.update(400, 50);
// Counts down because the lines are drawn top to bottom
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 6, 2015', 'Jan 11, 2015' ]);
expect(scale.ticks).toEqual([ 'Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015' ]);
});
it('should build ticks using date objects', function() {
@ -136,7 +146,7 @@ describe('Time scale tests', function() {
scale.update(400, 50);
// Counts down because the lines are drawn top to bottom
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 6, 2015', 'Jan 11, 2015' ]);
expect(scale.ticks).toEqual([ 'Dec 28, 2014', 'Jan 4, 2015', 'Jan 11, 2015' ]);
});
it('should build ticks when the data is xy points', function() {
@ -145,86 +155,97 @@ describe('Time scale tests', function() {
return moment('01/01/2015 12:00', 'DD/MM/YYYY HH:mm').add(days, 'd').toDate();
}
var scaleID = 'myScale';
var mockData = {
datasets: [{
data: [{
x: newDateFromRef(0),
y: 1
}, {
x: newDateFromRef(1),
y: 10
}, {
x: newDateFromRef(2),
y: 0
}, {
x: newDateFromRef(4),
y: 5
}, {
x: newDateFromRef(6),
y: 77
}, {
x: newDateFromRef(7),
y: 9
}, {
x: newDateFromRef(9),
y: 5
}], // days
}]
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('time');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('time'), // use default config for scale
chart: {
data: mockData
chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [{
x: newDateFromRef(0),
y: 1
}, {
x: newDateFromRef(1),
y: 10
}, {
x: newDateFromRef(2),
y: 0
}, {
x: newDateFromRef(4),
y: 5
}, {
x: newDateFromRef(6),
y: 77
}, {
x: newDateFromRef(7),
y: 9
}, {
x: newDateFromRef(9),
y: 5
}]
}],
},
id: scaleID
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'time',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'linear'
}]
}
}
});
scale.update(400, 50);
// Counts down because the lines are drawn top to bottom
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 6, 2015', 'Jan 11, 2015' ]);
var xScale = chartInstance.scales.xScale0;
expect(xScale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 3, 2015', 'Jan 5, 2015', 'Jan 7, 2015', 'Jan 9, 2015', 'Jan 11, 2015' ]);
});
it('should allow custom time parsers', function() {
// Helper to build date objects
var scaleID = 'myScale';
var mockData = {
datasets: [{
data: [{
x: 375068900,
y: 1
chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: [{
x: 375068900,
y: 1
}]
}],
}]
};
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
verticalScaleConfig.time.unit = 'day';
verticalScaleConfig.time.round = true;
verticalScaleConfig.time.parser = function customTimeParser(label) {
return moment.unix(label);
}
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('time');
var scale = new Constructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: mockData
},
id: scaleID
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'time',
position: 'bottom',
time: {
unit: 'day',
round: true,
parser: function customTimeParser(label) {
return moment.unix(label);
}
}
}],
yAxes: [{
id: 'yScale0',
type: 'linear'
}]
}
}
});
scale.update(400, 50);
// Counts down because the lines are drawn top to bottom
expect(scale.ticks[0]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981']); // handle time zone changes
expect(scale.ticks[1]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981']); // handle time zone changes
var xScale = chartInstance.scales.xScale0;
// Counts down because the lines are drawn top to bottom
expect(xScale.ticks[0]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
expect(xScale.ticks[1]).toEqualOneOf(['Nov 19, 1981', 'Nov 20, 1981', 'Nov 21, 1981']); // handle time zone changes
});
it('should build ticks using the config unit', function() {
@ -302,97 +323,82 @@ describe('Time scale tests', function() {
});
scale.update(400, 50);
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 3, 2015', 'Jan 5, 2015' ]);
expect(scale.ticks).toEqual([ 'Jan 1, 2015', 'Jan 5, 2015' ]);
});
it('should get the correct pixel for a value', function() {
var scaleID = 'myScale';
var mockData = {
labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days
datasets: [{
data: [],
}]
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('time');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('time'), // use default config for scale
chart: {
data: mockData
chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: []
}],
labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days
},
id: scaleID
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'time',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'linear',
position: 'left'
}]
}
}
});
scale.update(400, 50);
var xScale = chartInstance.scales.xScale0;
expect(scale.width).toBe(400);
expect(scale.height).toBe(28);
scale.left = 0;
scale.right = 400;
scale.top = 10;
scale.bottom = 38;
expect(xScale.getPixelForValue('', 0, 0)).toBeCloseToPixel(78);
expect(xScale.getPixelForValue('', 6, 0)).toBeCloseToPixel(452);
expect(scale.getPixelForValue('', 0, 0)).toBe(81);
expect(scale.getPixelForValue('', 6, 0)).toBe(323);
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('time'));
verticalScaleConfig.position = "left";
var verticalScale = new Constructor({
ctx: mockContext,
options: verticalScaleConfig,
chart: {
data: mockData
},
id: scaleID
expect(xScale.getValueForPixel(78)).toBeCloseToTime({
value: moment(chartInstance.data.labels[0]),
unit: 'hour',
threshold: 0.75
});
expect(xScale.getValueForPixel(452)).toBeCloseToTime({
value: moment(chartInstance.data.labels[6]),
unit: 'hour'
});
verticalScale.update(50, 400);
expect(verticalScale.width).toBe(50);
expect(verticalScale.height).toBe(400);
verticalScale.top = 0;
verticalScale.left = 0;
verticalScale.right = 50;
verticalScale.bottom = 400;
expect(verticalScale.getPixelForValue('', 0, 0)).toBe(38);
expect(verticalScale.getPixelForValue('', 6, 0)).toBe(375);
});
it('should get the correct label for a data value', function() {
var scaleID = 'myScale';
var mockData = {
labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days
datasets: [{
data: [],
}]
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('time');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('time'), // use default config for scale
chart: {
data: mockData
chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
xAxisID: 'xScale0',
yAxisID: 'yScale0',
data: []
}],
labels: ["2015-01-01T20:00:00", "2015-01-02T21:00:00", "2015-01-03T22:00:00", "2015-01-05T23:00:00", "2015-01-07T03:00", "2015-01-08T10:00", "2015-01-10T12:00"], // days
},
id: scaleID
options: {
scales: {
xAxes: [{
id: 'xScale0',
type: 'time',
position: 'bottom'
}],
yAxes: [{
id: 'yScale0',
type: 'linear',
position: 'left'
}]
}
}
});
scale.update(400, 50);
expect(scale.width).toBe(400);
expect(scale.height).toBe(28);
scale.left = 0;
scale.right = 400;
scale.top = 10;
scale.bottom = 38;
expect(scale.getLabelForIndex(0, 0)).toBe('2015-01-01T20:00:00');
expect(scale.getLabelForIndex(6, 0)).toBe('2015-01-10T12:00');
var xScale = chartInstance.scales.xScale0;
expect(xScale.getLabelForIndex(0, 0)).toBe('2015-01-01T20:00:00');
expect(xScale.getLabelForIndex(6, 0)).toBe('2015-01-10T12:00');
});
});

View file

@ -1,7 +1,7 @@
{
"name": "fullcalendar",
"title": "FullCalendar",
"version": "2.7.0",
"version": "2.7.1",
"description": "Full-sized drag & drop event calendar",
"keywords": [
"calendar",
@ -15,16 +15,13 @@
"type": "git",
"url": "https://github.com/fullcalendar/fullcalendar.git"
},
"license": {
"type": "MIT",
"url": "https://github.com/fullcalendar/fullcalendar/blob/master/LICENSE.txt"
},
"license": "MIT",
"author": {
"name": "Adam Shaw",
"email": "arshaw@arshaw.com",
"url": "http://arshaw.com/"
},
"copyright": "2015 Adam Shaw",
"copyright": "2016 Adam Shaw",
"dependencies": {
"jquery": ">=1.7.1",
"moment": ">=2.5.0"
@ -32,11 +29,11 @@
"devDependencies": {
"jquery-ui": ">=1.11.1",
"jquery-simulate": "~1.0.1",
"jquery-mockjax": "~1.5.4",
"jasmine-jquery": "~2.0.3",
"jasmine-fixture": "~1.2.0",
"moment-timezone": "~0.2.1",
"bootstrap": "~3.2.0"
"bootstrap": "~3.2.0",
"jquery-mockjax": "~2.1.1"
},
"main": [
"dist/fullcalendar.js",
@ -51,11 +48,11 @@
"!/CHANGELOG.*",
"!/CONTRIBUTING.*"
],
"_release": "2.7.0",
"_release": "2.7.1",
"_resolution": {
"type": "version",
"tag": "v2.7.0",
"commit": "74d80c00d45e5380ef7e4d86195a0e7495c193af"
"tag": "v2.7.1",
"commit": "c0cf46d19d632bf4402ef7198b3619ad63953582"
},
"_source": "https://github.com/arshaw/fullcalendar.git",
"_target": "^2.6.1",

View file

@ -1,4 +1,16 @@
v2.7.1 (2016-05-01)
-------------------
- dayClick not firing on touch devices (#3138)
- icons for prev/next not working in MS Edge (#2852)
- fix bad languages troubles with firewalls (#3133, #3132)
- update all dev dependencies (#3145, #3010, #2901, #251)
- git-ignore npm debug logs (#3011)
- misc automated test updates (#3139, #3147)
- Google Calendar htmlLink not always defined (#2844)
v2.7.0 (2016-04-23)
-------------------

View file

@ -41,7 +41,7 @@ Also, you will need the [grunt-cli][grunt-cli] and [bower][bower] packages insta
Then, clone FullCalendar's git repo:
git clone git://github.com/arshaw/fullcalendar.git
git clone git://github.com/fullcalendar/fullcalendar.git
Enter the directory and install FullCalendar's development dependencies:

View file

@ -1,7 +1,7 @@
{
"name": "fullcalendar",
"title": "FullCalendar",
"version": "2.7.0",
"version": "2.7.1",
"description": "Full-sized drag & drop event calendar",
"keywords": [
"calendar",
@ -15,16 +15,13 @@
"type": "git",
"url": "https://github.com/fullcalendar/fullcalendar.git"
},
"license": {
"type": "MIT",
"url": "https://github.com/fullcalendar/fullcalendar/blob/master/LICENSE.txt"
},
"license": "MIT",
"author": {
"name": "Adam Shaw",
"email": "arshaw@arshaw.com",
"url": "http://arshaw.com/"
},
"copyright": "2015 Adam Shaw",
"copyright": "2016 Adam Shaw",
"dependencies": {
"jquery": ">=1.7.1",
"moment": ">=2.5.0"
@ -32,11 +29,11 @@
"devDependencies": {
"jquery-ui": ">=1.11.1",
"jquery-simulate": "~1.0.1",
"jquery-mockjax": "~1.5.4",
"jasmine-jquery": "~2.0.3",
"jasmine-fixture": "~1.2.0",
"moment-timezone": "~0.2.1",
"bootstrap": "~3.2.0"
"bootstrap": "~3.2.0",
"jquery-mockjax": "~2.1.1"
},
"main": [
"dist/fullcalendar.js",

View file

@ -1,7 +1,7 @@
/*!
* FullCalendar v2.7.0 Stylesheet
* FullCalendar v2.7.1 Stylesheet
* Docs & License: http://fullcalendar.io/
* (c) 2015 Adam Shaw
* (c) 2016 Adam Shaw
*/
@ -73,7 +73,6 @@ body .fc { /* extra precedence to overcome jqui */
.fc-icon {
display: inline-block;
width: 1em;
height: 1em;
line-height: 1em;
font-size: 1em;
@ -100,7 +99,6 @@ NOTE: use percentage font sizes or else old IE chokes
.fc-icon:after {
position: relative;
margin: 0 -1em; /* ensures character will be centered, regardless of width */
}
.fc-icon-left-single-arrow:after {
@ -108,7 +106,6 @@ NOTE: use percentage font sizes or else old IE chokes
font-weight: bold;
font-size: 200%;
top: -7%;
left: 3%;
}
.fc-icon-right-single-arrow:after {
@ -116,7 +113,6 @@ NOTE: use percentage font sizes or else old IE chokes
font-weight: bold;
font-size: 200%;
top: -7%;
left: -3%;
}
.fc-icon-left-double-arrow:after {
@ -135,14 +131,12 @@ NOTE: use percentage font sizes or else old IE chokes
content: "\25C4";
font-size: 125%;
top: 3%;
left: -2%;
}
.fc-icon-right-triangle:after {
content: "\25BA";
font-size: 125%;
top: 3%;
left: 2%;
}
.fc-icon-down-triangle:after {

View file

@ -1,7 +1,7 @@
/*!
* FullCalendar v2.7.0
* FullCalendar v2.7.1
* Docs & License: http://fullcalendar.io/
* (c) 2015 Adam Shaw
* (c) 2016 Adam Shaw
*/
(function(factory) {
@ -19,7 +19,7 @@
;;
var FC = $.fullCalendar = {
version: "2.7.0",
version: "2.7.1",
internalApiVersion: 3
};
var fcViews = FC.views = {};
@ -271,7 +271,7 @@ function subtractInnerElHeight(outerEl, innerEl) {
var both = outerEl.add(innerEl);
var diff;
// fuckin IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
// effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
both.css({
position: 'relative', // cause a reflow, which will force fresh dimension recalculation
left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
@ -2931,8 +2931,6 @@ var HitDragListener = DragListener.extend({
var origPoint;
var point;
DragListener.prototype.handleInteractionStart.apply(this, arguments); // call the super-method
this.computeCoords();
if (ev) {
@ -2966,6 +2964,9 @@ var HitDragListener = DragListener.extend({
this.origHit = null;
this.coordAdjust = null;
}
// call the super-method. do it after origHit has been computed
DragListener.prototype.handleInteractionStart.apply(this, arguments);
},
@ -3591,12 +3592,20 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, {
// if 'selectable' is enabled, this listener also detects selections.
var dragListener = this.dayDragListener = new HitDragListener(this, {
scroll: view.opt('dragScroll'),
interactionStart: function() {
dayClickHit = dragListener.origHit;
},
dragStart: function() {
view.unselect(); // since we could be rendering a new selection, we want to clear any old one
},
hitOver: function(hit, isOrig, origHit) {
if (origHit) { // click needs to have started on a hit
dayClickHit = isOrig ? hit : null; // single-hit selection is a day click
// if user dragged to another cell at any point, it can no longer be a dayClick
if (!isOrig) {
dayClickHit = null;
}
if (isSelectable) {
selectionSpan = _this.computeSelection(
_this.getHitSpan(origHit),

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
/*!
* FullCalendar v2.7.0 Print Stylesheet
* FullCalendar v2.7.1 Print Stylesheet
* Docs & License: http://fullcalendar.io/
* (c) 2015 Adam Shaw
* (c) 2016 Adam Shaw
*/
/*

View file

@ -1,7 +1,7 @@
/*!
* FullCalendar v2.7.0 Google Calendar Plugin
* FullCalendar v2.7.1 Google Calendar Plugin
* Docs & License: http://fullcalendar.io/
* (c) 2015 Adam Shaw
* (c) 2016 Adam Shaw
*/
(function(factory) {
@ -136,10 +136,10 @@ function transformOptions(sourceOptions, start, end, timezone, calendar) {
}
else if (data.items) {
$.each(data.items, function(i, entry) {
var url = entry.htmlLink;
var url = entry.htmlLink || null;
// make the URLs for each event show times in the correct timezone
if (timezoneArg) {
if (timezoneArg && url !== null) {
url = injectQsComponent(url, 'ctz=' + timezoneArg);
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}});return a}(),a.fullCalendar.datepickerLang("ar-ma","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-ma",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}});return a}(),a.fullCalendar.datepickerLang("ar-ma","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-ma",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=(b.defineLocale||b.lang).call(b,"ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("ar-sa","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-sa",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=(b.defineLocale||b.lang).call(b,"ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("ar-sa","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-sa",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-tn",{months:انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ar-tn","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-tn",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ar-tn",{months:انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:انفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ar-tn","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar-tn",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5},e={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},f=function(a){return function(b,c,f,g){var h=d(b),i=e[a][d(b)];return 2===h&&(i=i[c?0:1]),i.replace(/%d/i,b)}},g=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"],h=(b.defineLocale||b.lang).call(b,"ar",{months:g,monthsShort:g,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:f("s"),m:f("m"),mm:f("m"),h:f("h"),hh:f("h"),d:f("d"),dd:f("d"),M:f("M"),MM:f("M"),y:f("y"),yy:f("y")},preparse:function(a){return a.replace(/\u200f/g,"").replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return h}(),a.fullCalendar.datepickerLang("ar","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&10>=a%100?3:a%100>=11?4:5},e={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},f=function(a){return function(b,c,f,g){var h=d(b),i=e[a][d(b)];return 2===h&&(i=i[c?0:1]),i.replace(/%d/i,b)}},g=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"],h=(b.defineLocale||b.lang).call(b,"ar",{months:g,monthsShort:g,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return 12>a?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:f("s"),m:f("m"),mm:f("m"),h:f("h"),hh:f("h"),d:f("d"),dd:f("d"),M:f("M"),MM:f("M"),y:f("y"),yy:f("y")},preparse:function(a){return a.replace(/\u200f/g,"").replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return h}(),a.fullCalendar.datepickerLang("ar","ar",{closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة","سبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ar",{buttonText:{month:"شهر",week:"أسبوع",day:"يوم",list:"أجندة"},allDayText:"اليوم كله",eventLimitText:"أخرى"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(a,b){var c=1===a?"r":2===a?"n":3===a?"r":4===a?"t":"è";return("w"===b||"W"===b)&&(c="a"),a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ca","ca",{closeText:"Tanca",prevText:"Anterior",nextText:"Següent",currentText:"Avui",monthNames:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthNamesShort:["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des"],dayNames:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],dayNamesShort:["dg","dl","dt","dc","dj","dv","ds"],dayNamesMin:["dg","dl","dt","dc","dj","dv","ds"],weekHeader:"Set",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ca",{buttonText:{month:"Mes",week:"Setmana",day:"Dia",list:"Agenda"},allDayText:"Tot el dia",eventLimitText:"més"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(a,b){var c=1===a?"r":2===a?"n":3===a?"r":4===a?"t":"è";return"w"!==b&&"W"!==b||(c="a"),a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("ca","ca",{closeText:"Tanca",prevText:"Anterior",nextText:"Següent",currentText:"Avui",monthNames:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthNamesShort:["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des"],dayNames:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],dayNamesShort:["dg","dl","dt","dc","dj","dv","ds"],dayNamesMin:["dg","dl","dt","dc","dj","dv","ds"],weekHeader:"Set",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("ca",{buttonText:{month:"Mes",week:"Setmana",day:"Dia",list:"Agenda"},allDayText:"Tot el dia",eventLimitText:"més"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de-at","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de-at",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de-at","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de-at",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=(b.defineLocale||b.lang).call(b,"de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:a,mm:"%d Minuten",h:a,hh:"%d Stunden",d:a,dd:a,M:a,MM:a,y:a,yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c}(),a.fullCalendar.datepickerLang("de","de",{closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("de",{buttonText:{month:"Monat",week:"Woche",day:"Tag",list:"Terminübersicht"},allDayText:"Ganztägig",eventLimitText:function(a){return"+ weitere "+a}})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sept_Oct_Nov_Dec".split("_"),monthsParse:[/^jan/i,/^feb/i,/^mar/i,/^apr/i,/^may/i,/^jun/i,/^jul/i,/^aug/i,/^sep/i,/^oct/i,/^nov/i,/^dec/i],longMonthsParse:[/^january$/i,/^february$/i,/^march$/i,/^april$/i,/^may$/i,/^june$/i,/^july$/i,/^august$/i,/^september$/i,/^october$/i,/^november$/i,/^december$/i],shortMonthsParse:[/^jan$/i,/^feb$/i,/^mar$/i,/^apr$/i,/^may$/i,/^jun$/i,/^jul$/i,/^aug/i,/^sept?$/i,/^oct$/i,/^nov$/i,/^dec$/i],weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-au","en-AU",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-au")});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-au","en-AU",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-au")});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sept_Oct_Nov_Dec".split("_"),monthsParse:[/^jan/i,/^feb/i,/^mar/i,/^apr/i,/^may/i,/^jun/i,/^jul/i,/^aug/i,/^sep/i,/^oct/i,/^nov/i,/^dec/i],longMonthsParse:[/^january$/i,/^february$/i,/^march$/i,/^april$/i,/^may$/i,/^june$/i,/^july$/i,/^august$/i,/^september$/i,/^october$/i,/^november$/i,/^december$/i],shortMonthsParse:[/^jan$/i,/^feb$/i,/^mar$/i,/^apr$/i,/^may$/i,/^jun$/i,/^jul$/i,/^aug/i,/^sept?$/i,/^oct$/i,/^nov$/i,/^dec$/i],weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"D MMMM, YYYY",LLL:"D MMMM, YYYY h:mm A",LLLL:"dddd, D MMMM, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}});return a}(),a.fullCalendar.lang("en-ca")});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}});return a}(),a.fullCalendar.lang("en-ca")});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sept_Oct_Nov_Dec".split("_"),monthsParse:[/^jan/i,/^feb/i,/^mar/i,/^apr/i,/^may/i,/^jun/i,/^jul/i,/^aug/i,/^sep/i,/^oct/i,/^nov/i,/^dec/i],longMonthsParse:[/^january$/i,/^february$/i,/^march$/i,/^april$/i,/^may$/i,/^june$/i,/^july$/i,/^august$/i,/^september$/i,/^october$/i,/^november$/i,/^december$/i],shortMonthsParse:[/^jan$/i,/^feb$/i,/^mar$/i,/^apr$/i,/^may$/i,/^jun$/i,/^jul$/i,/^aug/i,/^sept?$/i,/^oct$/i,/^nov$/i,/^dec$/i],weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-gb","en-GB",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-gb")});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-gb","en-GB",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-gb")});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsParse:[/^jan/i,/^feb/i,/^mar/i,/^apr/i,/^may/i,/^jun/i,/^jul/i,/^aug/i,/^sep/i,/^oct/i,/^nov/i,/^dec/i],longMonthsParse:[/^january$/i,/^february$/i,/^march$/i,/^april$/i,/^may$/i,/^june$/i,/^july$/i,/^august$/i,/^september$/i,/^october$/i,/^november$/i,/^december$/i],shortMonthsParse:[/^jan$/i,/^feb$/i,/^mar$/i,/^apr$/i,/^may$/i,/^jun$/i,/^jul$/i,/^aug/i,/^sept?$/i,/^oct$/i,/^nov$/i,/^dec$/i],weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.lang("en-ie")});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.lang("en-ie")});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sept_Oct_Nov_Dec".split("_"),monthsParse:[/^jan/i,/^feb/i,/^mar/i,/^apr/i,/^may/i,/^jun/i,/^jul/i,/^aug/i,/^sep/i,/^oct/i,/^nov/i,/^dec/i],longMonthsParse:[/^january$/i,/^february$/i,/^march$/i,/^april$/i,/^may$/i,/^june$/i,/^july$/i,/^august$/i,/^september$/i,/^october$/i,/^november$/i,/^december$/i],shortMonthsParse:[/^jan$/i,/^feb$/i,/^mar$/i,/^apr$/i,/^may$/i,/^jun$/i,/^jul$/i,/^aug/i,/^sept?$/i,/^oct$/i,/^nov$/i,/^dec$/i],weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-nz","en-NZ",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-nz")});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("en-nz","en-NZ",{closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("en-nz")});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),c="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=(b.defineLocale||b.lang).call(b,"es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"&#x3C;Ant",nextText:"Sig&#x3E;",currentText:"Hoy",monthNames:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthNamesShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("es",{buttonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),c="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),d=(b.defineLocale||b.lang).call(b,"es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(b,d){return/-MMM-/.test(d)?c[b.month()]:a[b.month()]},monthsParseExact:!0,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(1!==this.hours()?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(1!==this.hours()?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(1!==this.hours()?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(1!==this.hours()?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(1!==this.hours()?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},ordinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}});return d}(),a.fullCalendar.datepickerLang("es","es",{closeText:"Cerrar",prevText:"&#x3C;Ant",nextText:"Sig&#x3E;",currentText:"Hoy",monthNames:["enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre"],monthNamesShort:["ene","feb","mar","abr","may","jun","jul","ago","sep","oct","nov","dic"],dayNames:["domingo","lunes","martes","miércoles","jueves","viernes","sábado"],dayNamesShort:["dom","lun","mar","mié","jue","vie","sáb"],dayNamesMin:["D","L","M","X","J","V","S"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("es",{buttonText:{month:"Mes",week:"Semana",day:"Día",list:"Agenda"},allDayHtml:"Todo<br/>el día",eventLimitText:"más"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},c={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},d=(b.defineLocale||b.lang).call(b,"fa",{months:انویه_فوریهارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:انویه_فوریهارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یکشنبه_دوشنبههشنبههارشنبه_پنجشنبه_جمعه_شنبه".split("_"),weekdaysShort:"یکشنبه_دوشنبههشنبههارشنبه_پنجشنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(a){return/بعد از ظهر/.test(a)},meridiem:function(a,b,c){return 12>a?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(a){return a.replace(/[۰-۹]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("fa","fa",{closeText:"بستن",prevText:"&#x3C;قبلی",nextText:"بعدی&#x3E;",currentText:"امروز",monthNames:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["يکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayNamesShort:["ی","د","س","چ","پ","ج","ش"],dayNamesMin:["ی","د","س","چ","پ","ج","ش"],weekHeader:"هف",dateFormat:"yy/mm/dd",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fa",{buttonText:{month:"ماه",week:"هفته",day:"روز",list:"برنامه"},allDayText:"تمام روز",eventLimitText:function(a){return"بیش از "+a}})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},c={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},d=(b.defineLocale||b.lang).call(b,"fa",{months:انویه_فوریهارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:انویه_فوریهارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یکشنبه_دوشنبههشنبههارشنبه_پنجشنبه_جمعه_شنبه".split("_"),weekdaysShort:"یکشنبه_دوشنبههشنبههارشنبه_پنجشنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(a){return/بعد از ظهر/.test(a)},meridiem:function(a,b,c){return 12>a?"قبل از ظهر":"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چندین ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(a){return a.replace(/[۰-۹]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]}).replace(/,/g,"،")},ordinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}});return d}(),a.fullCalendar.datepickerLang("fa","fa",{closeText:"بستن",prevText:"&#x3C;قبلی",nextText:"بعدی&#x3E;",currentText:"امروز",monthNames:["ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["يکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayNamesShort:["ی","د","س","چ","پ","ج","ش"],dayNamesMin:["ی","د","س","چ","پ","ج","ش"],weekHeader:"هف",dateFormat:"yy/mm/dd",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fa",{buttonText:{month:"ماه",week:"هفته",day:"روز",list:"برنامه"},allDayText:"تمام روز",eventLimitText:function(a){return"بیش از "+a}})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")}});return a}(),a.fullCalendar.datepickerLang("fr-ca","fr-CA",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ca",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")}});return a}(),a.fullCalendar.datepickerLang("fr-ca","fr-CA",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ca",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr-ch","fr-CH",{closeText:"Fermer",prevText:"&#x3C;Préc",nextText:"Suiv&#x3E;",currentText:"Courant",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sm",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ch",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|e)/,ordinal:function(a){return a+(1===a?"er":"e")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr-ch","fr-CH",{closeText:"Fermer",prevText:"&#x3C;Préc",nextText:"Suiv&#x3E;",currentText:"Courant",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sm",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr-ch",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:!0,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd'hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},ordinalParse:/\d{1,2}(er|)/,ordinal:function(a){return a+(1===a?"er":"")},week:{dow:1,doy:4}});return a}(),a.fullCalendar.datepickerLang("fr","fr",{closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("fr",{buttonText:{month:"Mois",week:"Semaine",day:"Jour",list:"Mon planning"},allDayHtml:"Toute la<br/>journée",eventLimitText:"en plus"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יוליוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יוליוג׳_ספט׳וק׳וב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישיישי_שבת".split("_"),weekdaysShort:׳׳׳׳׳_ו׳׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(a){return 2===a?"שעתיים":a+" שעות"},d:"יום",dd:function(a){return 2===a?"יומיים":a+" ימים"},M:"חודש",MM:function(a){return 2===a?"חודשיים":a+" חודשים"},y:"שנה",yy:function(a){return 2===a?"שנתיים":a%10===0&&10!==a?a+" שנה":a+" שנים"}}});return a}(),a.fullCalendar.datepickerLang("he","he",{closeText:"סגור",prevText:"&#x3C;הקודם",nextText:"הבא&#x3E;",currentText:"היום",monthNames:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthNamesShort:["ינו","פבר","מרץ","אפר","מאי","יוני","יולי","אוג","ספט","אוק","נוב","דצמ"],dayNames:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],dayNamesShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayNamesMin:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("he",{defaultButtonText:{month:"חודש",week:"שבוע",day:"יום",list:"סדר יום"},weekNumberTitle:"שבוע",allDayText:"כל היום",eventLimitText:"אחר"})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a=(b.defineLocale||b.lang).call(b,"he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יוליוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יוליוג׳_ספט׳וק׳וב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישיישי_שבת".split("_"),weekdaysShort:׳׳׳׳׳_ו׳׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(a){return 2===a?"שעתיים":a+" שעות"},d:"יום",dd:function(a){return 2===a?"יומיים":a+" ימים"},M:"חודש",MM:function(a){return 2===a?"חודשיים":a+" חודשים"},y:"שנה",yy:function(a){return 2===a?"שנתיים":a%10===0&&10!==a?a+" שנה":a+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(a){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(a)},meridiem:function(a,b,c){return 5>a?"לפנות בוקר":10>a?"בבוקר":12>a?c?'לפנה"צ':"לפני הצהריים":18>a?c?'אחה"צ':"אחרי הצהריים":"בערב"}});return a}(),a.fullCalendar.datepickerLang("he","he",{closeText:"סגור",prevText:"&#x3C;הקודם",nextText:"הבא&#x3E;",currentText:"היום",monthNames:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthNamesShort:["ינו","פבר","מרץ","אפר","מאי","יוני","יולי","אוג","ספט","אוק","נוב","דצמ"],dayNames:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],dayNamesShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayNamesMin:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("he",{defaultButtonText:{month:"חודש",week:"שבוע",day:"יום",list:"סדר יום"},weekNumberTitle:"שבוע",allDayText:"כל היום",eventLimitText:"אחר"})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:""},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","":"0"},d=(b.defineLocale||b.lang).call(b,"hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात"===b?4>a?a:a+12:"सुबह"===b?a:"दोपहर"===b?a>=10?a:a+12:"शाम"===b?a+12:void 0},meridiem:function(a,b,c){return 4>a?"रात":10>a?"सुबह":17>a?"दोपहर":20>a?"शाम":"रात"},week:{dow:0,doy:6}});return d}(),a.fullCalendar.datepickerLang("hi","hi",{closeText:"बंद",prevText:"पिछला",nextText:"अगला",currentText:"आज",monthNames:["जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून","जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर"],monthNamesShort:["जन","फर","मार्च","अप्रेल","मई","जून","जूलाई","अग","सित","अक्ट","नव","दि"],dayNames:["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],dayNamesShort:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],dayNamesMin:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],weekHeader:"हफ्ता",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hi",{buttonText:{month:"महीना",week:"सप्ताह",day:"दिन",list:"कार्यसूची"},allDayText:"सभी दिन",eventLimitText:function(a){return"+अधिक "+a}})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";var a={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:""},c={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","":"0"},d=(b.defineLocale||b.lang).call(b,"hi",{months:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),monthsParseExact:!0,weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(a){return a.replace(/[१२३४५६७८९०]/g,function(a){return c[a]})},postformat:function(b){return b.replace(/\d/g,function(b){return a[b]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(a,b){return 12===a&&(a=0),"रात"===b?4>a?a:a+12:"सुबह"===b?a:"दोपहर"===b?a>=10?a:a+12:"शाम"===b?a+12:void 0},meridiem:function(a,b,c){return 4>a?"रात":10>a?"सुबह":17>a?"दोपहर":20>a?"शाम":"रात"},week:{dow:0,doy:6}});return d}(),a.fullCalendar.datepickerLang("hi","hi",{closeText:"बंद",prevText:"पिछला",nextText:"अगला",currentText:"आज",monthNames:["जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून","जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर"],monthNamesShort:["जन","फर","मार्च","अप्रेल","मई","जून","जूलाई","अग","सित","अक्ट","नव","दि"],dayNames:["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],dayNamesShort:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],dayNamesMin:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],weekHeader:"हफ्ता",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hi",{buttonText:{month:"महीना",week:"सप्ताह",day:"दिन",list:"कार्यसूची"},allDayText:"सभी दिन",eventLimitText:function(a){return"+अधिक "+a}})});

View file

@ -1 +1 @@
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}var c=(b.defineLocale||b.lang).call(b,"hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:a,mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("hr","hr",{closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],monthNamesShort:["Sij","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],dayNames:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Tje",dateFormat:"dd.mm.yy.",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hr",{buttonText:{month:"Mjesec",week:"Tjedan",day:"Dan",list:"Raspored"},allDayText:"Cijeli dan",eventLimitText:function(a){return"+ još "+a}})});
!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){!function(){"use strict";function a(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}var c=(b.defineLocale||b.lang).call(b,"hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:a,mm:a,h:a,hh:a,d:"dan",dd:a,M:"mjesec",MM:a,y:"godinu",yy:a},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c}(),a.fullCalendar.datepickerLang("hr","hr",{closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],monthNamesShort:["Sij","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],dayNames:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Tje",dateFormat:"dd.mm.yy.",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""}),a.fullCalendar.lang("hr",{buttonText:{month:"Mjesec",week:"Tjedan",day:"Dan",list:"Raspored"},allDayText:"Cijeli dan",eventLimitText:function(a){return"+ još "+a}})});

Some files were not shown because too many files have changed in this diff Show more