Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: chartjs/Chart.js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: chartjs/Chart.js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 2.9
Choose a head ref

Commits on Sep 21, 2016

  1. Merge pull request #3321 from chartjs/master

    Version 2.3.0 Release Candidate 1
    simonbrunel authored Sep 21, 2016
    Copy the full SHA
    64f37a3 View commit details

Commits on Sep 22, 2016

  1. Copy the full SHA
    57d8ab2 View commit details

Commits on Nov 12, 2016

  1. Merge pull request #3551 from chartjs/master

    Version 2.4.0
    simonbrunel authored Nov 12, 2016
    Copy the full SHA
    0515700 View commit details

Commits on Feb 8, 2017

  1. Copy the full SHA
    57797a9 View commit details

Commits on May 25, 2017

  1. Merge pull request #4236 from chartjs/master

    Version 2.6.0
    simonbrunel authored May 25, 2017
    Copy the full SHA
    2798861 View commit details
  2. Copy the full SHA
    4d55315 View commit details

Commits on Sep 10, 2017

  1. Merge pull request #4706 from chartjs/master

    Version 2.7.0
    etimberg authored Sep 10, 2017
    Copy the full SHA
    5a2ffe4 View commit details

Commits on Oct 28, 2017

  1. Merge pull request #4876 from chartjs/master

    Version 2.7.1
    simonbrunel authored Oct 28, 2017
    Copy the full SHA
    1e09823 View commit details

Commits on Mar 1, 2018

  1. Merge pull request #5145 from chartjs/master

    Version 2.7.2
    simonbrunel authored Mar 1, 2018
    Copy the full SHA
    1a5dca8 View commit details

Commits on Oct 15, 2018

  1. Merge pull request #5732 from chartjs/master

    Version 2.7.3
    simonbrunel authored Oct 15, 2018
    2
    Copy the full SHA
    7065c43 View commit details

Commits on Mar 14, 2019

  1. Merge pull request #6092 from chartjs/master

    Version 2.8.0
    simonbrunel authored Mar 14, 2019
    Copy the full SHA
    d224e25 View commit details

Commits on Oct 26, 2019

  1. Merge pull request #6601 from chartjs/master

    Version 2.9.0
    etimberg authored Oct 26, 2019
    Copy the full SHA
    26b9d1f View commit details

Commits on Oct 27, 2019

  1. Release v2.9.1 (#6618)

    Release v2.9.1
    etimberg authored Oct 27, 2019
    Copy the full SHA
    a92dd7b View commit details

Commits on Nov 2, 2019

  1. Copy the full SHA
    65421bb View commit details
  2. Combine performance docs (#6643)

    benmccann authored and etimberg committed Nov 2, 2019
    Copy the full SHA
    45550ed View commit details
  3. Copy the full SHA
    8abfbcb View commit details
  4. Copy the full SHA
    ad26311 View commit details
  5. Versatile clipping for lines (#6660)

    kurkle authored and etimberg committed Nov 2, 2019
    Copy the full SHA
    201fe46 View commit details
  6. Copy the full SHA
    a920bfe View commit details
  7. Backward compatible default fill for radar charts (#6655)

    * Backward compatible fill behavior for radar
    kurkle authored and etimberg committed Nov 2, 2019
    Copy the full SHA
    1cce8a5 View commit details
  8. Copy the full SHA
    a985fec View commit details

Commits on Nov 10, 2019

  1. Fix undefined variable (#6698)

    benmccann authored and etimberg committed Nov 10, 2019
    Copy the full SHA
    c44229f View commit details

Commits on Nov 11, 2019

  1. Copy the full SHA
    a307a2a View commit details
  2. Update version number to 2.9.3 (#6725)

    benmccann authored and etimberg committed Nov 11, 2019
    Copy the full SHA
    26ea9f0 View commit details

Commits on Feb 11, 2020

  1. Copy the full SHA
    2df6986 View commit details

Commits on Jun 4, 2020

  1. Preserve object prototypes when cloning (#7404)

    Co-authored-by: Bryan.Iddings <bryan.iddings@noaa.gov>
    iddings and Bryan.Iddings authored Jun 4, 2020
    Copy the full SHA
    484f0d1 View commit details

Commits on Jul 5, 2020

  1. Copy the full SHA
    679ec4a View commit details

Commits on Oct 8, 2020

  1. Use node v12.18.2 on Travis CI (#7864)

    Due to an issue with deprecated deps (gitbook-cli), forcing travis to and older
    compatible version of nodejs.
    
    Fixes #7863
    alessandroasm authored Oct 8, 2020
    Copy the full SHA
    2493cb5 View commit details

Commits on Oct 9, 2020

  1. [2.9] FitBoxes recursion when dimensions are NaN (#7853)

    * Infinite recursion when dimensions are NaN
    
    Adding a verification on updateDims that handles a case when dimensions are both
    NaN. This caused an infinite recursion on fitBoxes when calculating the layout
    for a chart that is mounted on an element that is not yet in DOM.
    
    Fixes #7761
    alessandroasm authored Oct 9, 2020
    Copy the full SHA
    063b7dc View commit details

Commits on Oct 17, 2020

  1. Fix Maximum call stack size exception in computeLabelSizes (#7883)

    Calling Math.max with a large number of values was throwing an exception.
    Tracking the current largest width and height as the widths and heights are
    built up should be faster and avoids the exception.
    silentmatt authored Oct 17, 2020
    Copy the full SHA
    42ed589 View commit details

Commits on Oct 18, 2020

  1. Copy the full SHA
    d919188 View commit details
  2. When objects are merged together, the target prototype can be pollute…

    …d. (#7918)
    
    * When objects are merged together, the target prototype can be polluted.
    
    This change blocks updates to the `__proto__` key during config merge
    etimberg authored Oct 18, 2020
    Copy the full SHA
    dff7140 View commit details
  3. Copy the full SHA
    1d92605 View commit details

Commits on Oct 24, 2020

  1. Copy the full SHA
    df942bb View commit details

Commits on Dec 28, 2020

  1. Copy the full SHA
    171a7e3 View commit details
Showing with 902 additions and 367 deletions.
  1. +3 −1 .travis.yml
  2. +1 −1 docs/README.md
  3. +1 −0 docs/SUMMARY.md
  4. +2 −72 docs/charts/line.md
  5. +1 −0 docs/general/README.md
  6. +81 −6 docs/general/performance.md
  7. +1 −3 docs/getting-started/integration.md
  8. +207 −206 package-lock.json
  9. +1 −1 package.json
  10. +1 −1 scripts/deploy.sh
  11. +1 −1 scripts/release.sh
  12. +2 −1 src/controllers/controller.doughnut.js
  13. +9 −3 src/controllers/controller.horizontalBar.js
  14. +60 −11 src/controllers/controller.line.js
  15. +3 −1 src/controllers/controller.polarArea.js
  16. +1 −0 src/controllers/controller.radar.js
  17. +4 −4 src/core/core.controller.js
  18. +2 −2 src/core/core.datasetController.js
  19. +2 −1 src/core/core.layouts.js
  20. +8 −4 src/core/core.scale.js
  21. +1 −1 src/core/core.scaleService.js
  22. +17 −1 src/helpers/helpers.core.js
  23. +1 −1 src/platforms/platform.dom.js
  24. +5 −4 src/plugins/plugin.legend.js
  25. +3 −3 test/fixtures/controller.bar/bar-thickness-absolute.json
  26. +3 −3 test/fixtures/controller.bar/bar-thickness-flex-offset.json
  27. +3 −3 test/fixtures/controller.bar/bar-thickness-flex-single-reverse.json
  28. +3 −3 test/fixtures/controller.bar/bar-thickness-flex-single.json
  29. +3 −3 test/fixtures/controller.bar/bar-thickness-flex.json
  30. +3 −3 test/fixtures/controller.bar/bar-thickness-max.json
  31. +2 −2 test/fixtures/controller.bar/bar-thickness-min-interval.json
  32. +6 −2 test/fixtures/controller.bar/bar-thickness-multiple.json
  33. +6 −2 test/fixtures/controller.bar/bar-thickness-no-overlap.json
  34. +6 −2 test/fixtures/controller.bar/bar-thickness-offset.json
  35. +6 −2 test/fixtures/controller.bar/bar-thickness-reverse.json
  36. +2 −2 test/fixtures/controller.bar/bar-thickness-single-xy.json
  37. +2 −2 test/fixtures/controller.bar/bar-thickness-single.json
  38. +6 −2 test/fixtures/controller.bar/bar-thickness-stacked.json
  39. +38 −0 test/fixtures/controller.line/clip/default-x-max.json
  40. BIN test/fixtures/controller.line/clip/default-x-max.png
  41. +38 −0 test/fixtures/controller.line/clip/default-x-min.json
  42. BIN test/fixtures/controller.line/clip/default-x-min.png
  43. +39 −0 test/fixtures/controller.line/clip/default-x.json
  44. BIN test/fixtures/controller.line/clip/default-x.png
  45. +38 −0 test/fixtures/controller.line/clip/default-y-max.json
  46. BIN test/fixtures/controller.line/clip/default-y-max.png
  47. +38 −0 test/fixtures/controller.line/clip/default-y-min.json
  48. BIN test/fixtures/controller.line/clip/default-y-min.png
  49. +39 −0 test/fixtures/controller.line/clip/default-y.json
  50. BIN test/fixtures/controller.line/clip/default-y.png
  51. +77 −0 test/fixtures/controller.line/clip/specified.json
  52. BIN test/fixtures/controller.line/clip/specified.png
  53. +34 −0 test/fixtures/controller.line/non-numeric-y.json
  54. BIN test/fixtures/controller.line/non-numeric-y.png
  55. +1 −0 test/fixtures/controller.radar/backgroundColor/scriptable.js
  56. +1 −0 test/fixtures/controller.radar/backgroundColor/value.js
  57. +1 −0 test/fixtures/controller.radar/borderDash/scriptable.js
  58. +18 −5 test/specs/controller.bar.tests.js
  59. +40 −0 test/specs/core.layouts.tests.js
  60. +29 −0 test/specs/helpers.core.tests.js
  61. +2 −2 test/specs/plugin.legend.tests.js
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
language: node_js
node_js:
- lts/*
# Using node 12.18.2 instead of lts
# https://github.com/chartjs/Chart.js/issues/7863#issuecomment-705222874
- "12.18.2"

before_install:
- "export CHROME_BIN=/usr/bin/google-chrome"
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ var myChart = new Chart(ctx, {

## 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/chartjs/Chart.js/blob/master/docs/developers/contributing.md) first.
Before submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](./developers/contributing.md) first.

For support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](https://stackoverflow.com/questions/tagged/chartjs).

1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
* [Options](general/options.md)
* [Colors](general/colors.md)
* [Fonts](general/fonts.md)
* [Performance](general/performance.md)
* [Configuration](configuration/README.md)
* [Animations](configuration/animations.md)
* [Layout](configuration/layout.md)
74 changes: 2 additions & 72 deletions docs/charts/line.md
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ The line chart allows a number of properties to be specified for each dataset. T
| [`borderJoinStyle`](#line-styling) | `string` | Yes | - | `'miter'`
| [`borderWidth`](#line-styling) | `number` | Yes | - | `3`
| [`cubicInterpolationMode`](#cubicinterpolationmode) | `string` | Yes | - | `'default'`
| [`clip`](#line-styling) | <code>number&#124;object</code> | - | - | `borderWidth / 2`
| [`fill`](#line-styling) | <code>boolean&#124;string</code> | Yes | - | `true`
| [`hoverBackgroundColor`](#line-styling) | [`Color`](../general/colors.md) | Yes | - | `undefined`
| [`hoverBorderCapStyle`](#line-styling) | `string` | Yes | - | `undefined`
@@ -117,6 +118,7 @@ The style of the line can be controlled with the following properties:
| `borderDashOffset` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset).
| `borderJoinStyle` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin).
| `borderWidth` | The line width (in pixels).
| `clip` | How to clip relative to chartArea. Positive value allows overflow, negative value clips that many pixels inside chartArea. `0` = clip at chartArea. Clipping can also be configured per side: `clip: {left: 5, top: false, right: -2, bottom: 0}`
| `fill` | How to fill the area under the line. See [area charts](area.md).
| `lineTension` | Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used.
| `showLine` | If false, the line is not drawn for this dataset.
@@ -216,75 +218,3 @@ var stackedLine = new Chart(ctx, {
}
});
```

## High Performance Line Charts

When charting a lot of data, the chart render time may start to get quite large. In that case, the following strategies can be used to improve performance.

### Data Decimation

Decimating your data will achieve the best results. When there is a lot of data to display on the graph, it doesn't make sense to show tens of thousands of data points on a graph that is only a few hundred pixels wide.

There are many approaches to data decimation and selection of an algorithm will depend on your data and the results you want to achieve. For instance, [min/max](https://digital.ni.com/public.nsf/allkb/F694FFEEA0ACF282862576020075F784) decimation will preserve peaks in your data but could require up to 4 points for each pixel. This type of decimation would work well for a very noisy signal where you need to see data peaks.

### Disable Bezier Curves

If you are drawing lines on your chart, disabling bezier curves will improve render times since drawing a straight line is more performant than a bezier curve.

To disable bezier curves for an entire chart:

```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
elements: {
line: {
tension: 0 // disables bezier curves
}
}
}
});
```

### Disable Line Drawing

If you have a lot of data points, it can be more performant to disable rendering of the line for a dataset and only draw points. Doing this means that there is less to draw on the canvas which will improve render performance.

To disable lines:

```javascript
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
showLine: false // disable for a single dataset
}]
},
options: {
showLines: false // disable for all datasets
}
});
```

### Disable Animations

If your charts have long render times, it is a good idea to disable animations. Doing so will mean that the chart needs to only be rendered once during an update instead of multiple times. This will have the effect of reducing CPU usage and improving general page performance.

To disable animations

```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
animation: {
duration: 0 // general animation time
},
hover: {
animationDuration: 0 // duration of animations when hovering an item
},
responsiveAnimationDuration: 0 // animation duration after a resize
}
});
```
1 change: 1 addition & 0 deletions docs/general/README.md
Original file line number Diff line number Diff line change
@@ -8,3 +8,4 @@ These sections describe general configuration options that can apply elsewhere i
* [Options](./options.md) scriptable and indexable options syntax.
* [Colors](./colors.md) defines acceptable color values.
* [Font](./fonts.md) defines various font options.
* [Performance](./performance.md) gives tips for performance-sensitive applications.
87 changes: 81 additions & 6 deletions docs/general/performance.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,84 @@
# Performance

Chart.js charts are rendered on `canvas` elements, which makes rendering quite fast. For large datasets or performance sensitive applications, you may wish to consider the tips below:
Chart.js charts are rendered on `canvas` elements, which makes rendering quite fast. For large datasets or performance sensitive applications, you may wish to consider the tips below.

* Set `animation: { duration: 0 }` to disable [animations](../configuration/animations.md).
* [Specify a rotation value](https://www.chartjs.org/docs/latest/axes/cartesian/#tick-configuration) by setting `minRotation` and `maxRotation` to the same value
* For large datasets:
* You may wish to sample your data before providing it to Chart.js. E.g. if you have a data point for each day, you may find it more performant to pass in a data point for each week instead
* Set the [`ticks.sampleSize`](../axes/cartesian/README.md#tick-configuration) option in order to render axes more quickly
## Tick Calculation

### Rotation

[Specify a rotation value](https://www.chartjs.org/docs/latest/axes/cartesian/#tick-configuration) by setting `minRotation` and `maxRotation` to the same value, which avoids the chart from having to automatically determine a value to use.

### Sampling

Set the [`ticks.sampleSize`](../axes/cartesian/README.md#tick-configuration) option. This will determine how large your labels are by looking at only a subset of them in order to render axes more quickly. This works best if there is not a large variance in the size of your labels.

## Disable Animations

If your charts have long render times, it is a good idea to disable animations. Doing so will mean that the chart needs to only be rendered once during an update instead of multiple times. This will have the effect of reducing CPU usage and improving general page performance.

To disable animations

```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
animation: {
duration: 0 // general animation time
},
hover: {
animationDuration: 0 // duration of animations when hovering an item
},
responsiveAnimationDuration: 0 // animation duration after a resize
}
});
```

## Data Decimation

Decimating your data will achieve the best results. When there is a lot of data to display on the graph, it doesn't make sense to show tens of thousands of data points on a graph that is only a few hundred pixels wide.

There are many approaches to data decimation and selection of an algorithm will depend on your data and the results you want to achieve. For instance, [min/max](https://digital.ni.com/public.nsf/allkb/F694FFEEA0ACF282862576020075F784) decimation will preserve peaks in your data but could require up to 4 points for each pixel. This type of decimation would work well for a very noisy signal where you need to see data peaks.


## Line Charts

### Disable Bezier Curves

If you are drawing lines on your chart, disabling bezier curves will improve render times since drawing a straight line is more performant than a bezier curve.

To disable bezier curves for an entire chart:

```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
elements: {
line: {
tension: 0 // disables bezier curves
}
}
}
});
```

### Disable Line Drawing

If you have a lot of data points, it can be more performant to disable rendering of the line for a dataset and only draw points. Doing this means that there is less to draw on the canvas which will improve render performance.

To disable lines:

```javascript
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
showLine: false // disable for a single dataset
}]
},
options: {
showLines: false // disable for all datasets
}
});
```
4 changes: 1 addition & 3 deletions docs/getting-started/integration.md
Original file line number Diff line number Diff line change
@@ -39,9 +39,7 @@ var myChart = new Chart(ctx, {...});
```javascript
// Rollup
{
external: {
['moment']
}
external: ['moment']
}
```

413 changes: 207 additions & 206 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
"name": "chart.js",
"homepage": "https://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "2.9.0",
"version": "2.9.4",
"license": "MIT",
"jsdelivr": "dist/Chart.min.js",
"unpkg": "dist/Chart.min.js",
2 changes: 1 addition & 1 deletion scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ TARGET_REPO_URL="https://$GITHUB_AUTH_TOKEN@github.com/chartjs/chartjs.github.io
VERSION_REGEX='[[:digit:]]+.[[:digit:]]+.[[:digit:]]+(-.*)?'

# Make sure that this script is executed only for the release and master branches
if [ "$TRAVIS_BRANCH" == "release" ]; then
if [ "$TRAVIS_BRANCH" =~ ^release.*$ ]; then
# Travis executes this script from the repository root, so at the same level than package.json
VERSION=$(node -p -e "require('./package.json').version")
elif [ "$TRAVIS_BRANCH" == "master" ]; then
2 changes: 1 addition & 1 deletion scripts/release.sh
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

set -e

if [ "$TRAVIS_BRANCH" != "release" ]; then
if [[ ! "$TRAVIS_BRANCH" =~ ^release.*$ ]]; then
echo "Skipping release because this is not the 'release' branch"
exit 0
fi
3 changes: 2 additions & 1 deletion src/controllers/controller.doughnut.js
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ defaults._set('doughnut', {
var list = document.createElement('ul');
var data = chart.data;
var datasets = data.datasets;
var globalDefaults = defaults.global;
var labels = data.labels;
var i, ilen, listItem, listItemSpan;

@@ -33,7 +34,7 @@ defaults._set('doughnut', {
for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {
listItem = list.appendChild(document.createElement('li'));
listItemSpan = listItem.appendChild(document.createElement('span'));
listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];
listItemSpan.style.backgroundColor = valueOrDefault(datasets[0].backgroundColor[i], globalDefaults.defaultColor);
if (labels[i]) {
listItem.appendChild(document.createTextNode(labels[i]));
}
12 changes: 9 additions & 3 deletions src/controllers/controller.horizontalBar.js
Original file line number Diff line number Diff line change
@@ -18,8 +18,6 @@ defaults._set('horizontalBar', {
yAxes: [{
type: 'category',
position: 'left',
categoryPercentage: 0.8,
barPercentage: 0.9,
offset: true,
gridLines: {
offsetGridLines: true
@@ -39,6 +37,15 @@ defaults._set('horizontalBar', {
}
});

defaults._set('global', {
datasets: {
horizontalBar: {
categoryPercentage: 0.8,
barPercentage: 0.9
}
}
});

module.exports = BarController.extend({
/**
* @private
@@ -54,4 +61,3 @@ module.exports = BarController.extend({
return this.getMeta().yAxisID;
}
});

71 changes: 60 additions & 11 deletions src/controllers/controller.line.js
Original file line number Diff line number Diff line change
@@ -29,6 +29,51 @@ defaults._set('line', {
}
});

function scaleClip(scale, halfBorderWidth) {
var tickOpts = scale && scale.options.ticks || {};
var reverse = tickOpts.reverse;
var min = tickOpts.min === undefined ? halfBorderWidth : 0;
var max = tickOpts.max === undefined ? halfBorderWidth : 0;
return {
start: reverse ? max : min,
end: reverse ? min : max
};
}

function defaultClip(xScale, yScale, borderWidth) {
var halfBorderWidth = borderWidth / 2;
var x = scaleClip(xScale, halfBorderWidth);
var y = scaleClip(yScale, halfBorderWidth);

return {
top: y.end,
right: x.end,
bottom: y.start,
left: x.start
};
}

function toClip(value) {
var t, r, b, l;

if (helpers.isObject(value)) {
t = value.top;
r = value.right;
b = value.bottom;
l = value.left;
} else {
t = r = b = l = value;
}

return {
top: t,
right: r,
bottom: b,
left: l
};
}


module.exports = DatasetController.extend({

datasetElementType: elements.Line,
@@ -173,6 +218,7 @@ module.exports = DatasetController.extend({
values.spanGaps = valueOrDefault(config.spanGaps, options.spanGaps);
values.tension = valueOrDefault(config.lineTension, lineOptions.tension);
values.steppedLine = resolve([custom.steppedLine, config.steppedLine, lineOptions.stepped]);
values.clip = toClip(valueOrDefault(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth)));

return values;
},
@@ -183,12 +229,13 @@ module.exports = DatasetController.extend({
var yScale = me._yScale;
var sumPos = 0;
var sumNeg = 0;
var rightValue = +yScale.getRightValue(value);
var metasets = chart._getSortedVisibleDatasetMetas();
var ilen = metasets.length;
var i, ds, dsMeta, stackedRightValue;
var i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen;

if (yScale.options.stacked) {
rightValue = +yScale.getRightValue(value);
metasets = chart._getSortedVisibleDatasetMetas();
ilen = metasets.length;

for (i = 0; i < ilen; ++i) {
dsMeta = metasets[i];
if (dsMeta.index === datasetIndex) {
@@ -209,8 +256,9 @@ module.exports = DatasetController.extend({
if (rightValue < 0) {
return yScale.getPixelForValue(sumNeg + rightValue);
}
return yScale.getPixelForValue(sumPos + rightValue);
}
return yScale.getPixelForValue(sumPos + rightValue);
return yScale.getPixelForValue(value);
},

updateBezierControlPoints: function() {
@@ -274,18 +322,19 @@ module.exports = DatasetController.extend({
var meta = me.getMeta();
var points = meta.data || [];
var area = chart.chartArea;
var canvas = chart.canvas;
var i = 0;
var ilen = points.length;
var halfBorderWidth;
var clip;

if (me._showLine) {
halfBorderWidth = (meta.dataset._model.borderWidth || 0) / 2;
clip = meta.dataset._model.clip;

helpers.canvas.clipArea(chart.ctx, {
left: area.left - halfBorderWidth,
right: area.right + halfBorderWidth,
top: area.top - halfBorderWidth,
bottom: area.bottom + halfBorderWidth
left: clip.left === false ? 0 : area.left - clip.left,
right: clip.right === false ? canvas.width : area.right + clip.right,
top: clip.top === false ? 0 : area.top - clip.top,
bottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom
});

meta.dataset.draw();
4 changes: 3 additions & 1 deletion src/controllers/controller.polarArea.js
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ var elements = require('../elements/index');
var helpers = require('../helpers/index');

var resolve = helpers.options.resolve;
var valueOrDefault = helpers.valueOrDefault;

defaults._set('polarArea', {
scale: {
@@ -35,6 +36,7 @@ defaults._set('polarArea', {
var list = document.createElement('ul');
var data = chart.data;
var datasets = data.datasets;
var globalDefaults = defaults.global;
var labels = data.labels;
var i, ilen, listItem, listItemSpan;

@@ -43,7 +45,7 @@ defaults._set('polarArea', {
for (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {
listItem = list.appendChild(document.createElement('li'));
listItemSpan = listItem.appendChild(document.createElement('span'));
listItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];
listItemSpan.style.backgroundColor = valueOrDefault(datasets[0].backgroundColor[i], globalDefaults.defaultColor);
if (labels[i]) {
listItem.appendChild(document.createTextNode(labels[i]));
}
1 change: 1 addition & 0 deletions src/controllers/controller.radar.js
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ defaults._set('radar', {
},
elements: {
line: {
fill: 'start',
tension: 0 // no bezier in radar
}
}
8 changes: 4 additions & 4 deletions src/core/core.controller.js
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ defaults._set('global', {
* returns a deep copy of the result, thus doesn't alter inputs.
*/
function mergeScaleConfig(/* config objects ... */) {
return helpers.merge({}, [].slice.call(arguments), {
return helpers.merge(Object.create(null), [].slice.call(arguments), {
merger: function(key, target, source, options) {
if (key === 'xAxes' || key === 'yAxes') {
var slen = source[key].length;
@@ -81,9 +81,9 @@ function mergeScaleConfig(/* config objects ... */) {
* a deep copy of the result, thus doesn't alter inputs.
*/
function mergeConfig(/* config objects ... */) {
return helpers.merge({}, [].slice.call(arguments), {
return helpers.merge(Object.create(null), [].slice.call(arguments), {
merger: function(key, target, source, options) {
var tval = target[key] || {};
var tval = target[key] || Object.create(null);
var sval = source[key];

if (key === 'scales') {
@@ -100,7 +100,7 @@ function mergeConfig(/* config objects ... */) {
}

function initConfig(config) {
config = config || {};
config = config || Object.create(null);

// Do NOT use mergeConfig for the data object because this method merges arrays
// and so would change references to labels and datasets, preventing data updates.
4 changes: 2 additions & 2 deletions src/core/core.datasetController.js
Original file line number Diff line number Diff line change
@@ -275,7 +275,7 @@ helpers.extend(DatasetController.prototype, {
*/
_configure: function() {
var me = this;
me._config = helpers.merge({}, [
me._config = helpers.merge(Object.create(null), [
me.chart.options.datasets[me._type],
me.getDataset(),
], {
@@ -347,7 +347,7 @@ helpers.extend(DatasetController.prototype, {
}

if (style.fill === false || style.fill === null) {
style.backgroundColor = 'rgba(0,0,0,0)';
style.backgroundColor = style.borderColor;
}

return style;
3 changes: 2 additions & 1 deletion src/core/core.layouts.js
Original file line number Diff line number Diff line change
@@ -99,7 +99,8 @@ function updateDims(chartArea, params, layout) {
chartArea.h = newHeight;

// return true if chart area changed in layout's direction
return layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h;
var sizes = layout.horizontal ? [newWidth, chartArea.w] : [newHeight, chartArea.h];
return sizes[0] !== sizes[1] && (!isNaN(sizes[0]) || !isNaN(sizes[1]));
}
}

12 changes: 8 additions & 4 deletions src/core/core.scale.js
Original file line number Diff line number Diff line change
@@ -130,6 +130,8 @@ function computeLabelSizes(ctx, tickFonts, ticks, caches) {
var widths = [];
var heights = [];
var offsets = [];
var widestLabelSize = 0;
var highestLabelSize = 0;
var i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel, widest, highest;

for (i = 0; i < length; ++i) {
@@ -157,11 +159,13 @@ function computeLabelSizes(ctx, tickFonts, ticks, caches) {
widths.push(width);
heights.push(height);
offsets.push(lineHeight / 2);
widestLabelSize = Math.max(width, widestLabelSize);
highestLabelSize = Math.max(height, highestLabelSize);
}
garbageCollect(caches, length);

widest = widths.indexOf(Math.max.apply(null, widths));
highest = heights.indexOf(Math.max.apply(null, heights));
widest = widths.indexOf(widestLabelSize);
highest = heights.indexOf(highestLabelSize);

function valueAt(idx) {
return {
@@ -356,7 +360,7 @@ var Scale = Element.extend({
*/
_getLabels: function() {
var data = this.chart.data;
return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];
},

// These methods are ordered by lifecyle. Utilities then follow.
@@ -929,7 +933,7 @@ var Scale = Element.extend({

getDecimalForPixel: function(pixel) {
var decimal = (pixel - this._startPixel) / this._length;
return Math.min(1, Math.max(0, this._reversePixels ? 1 - decimal : decimal));
return this._reversePixels ? 1 - decimal : decimal;
},

/**
2 changes: 1 addition & 1 deletion src/core/core.scaleService.js
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ module.exports = {
},
getScaleDefaults: function(type) {
// Return the scale defaults merged with the global settings so that we always use the latest ones
return this.defaults.hasOwnProperty(type) ? helpers.merge({}, [defaults.scale, this.defaults[type]]) : {};
return this.defaults.hasOwnProperty(type) ? helpers.merge(Object.create(null), [defaults.scale, this.defaults[type]]) : {};
},
updateScaleDefaults: function(type, additions) {
var me = this;
18 changes: 17 additions & 1 deletion src/helpers/helpers.core.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
'use strict';

function isValidKey(key) {
return ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;
}

/**
* @namespace Chart.helpers
*/
@@ -175,7 +179,7 @@ var helpers = {
}

if (helpers.isObject(source)) {
var target = {};
var target = Object.create(source);
var keys = Object.keys(source);
var klen = keys.length;
var k = 0;
@@ -196,6 +200,12 @@ var helpers = {
* @private
*/
_merger: function(key, target, source, options) {
if (!isValidKey(key)) {
// We want to ensure we do not copy prototypes over
// as this can pollute global namespaces
return;
}

var tval = target[key];
var sval = source[key];

@@ -211,6 +221,12 @@ var helpers = {
* @private
*/
_mergerIf: function(key, target, source) {
if (!isValidKey(key)) {
// We want to ensure we do not copy prototypes over
// as this can pollute global namespaces
return;
}

var tval = target[key];
var sval = source[key];

2 changes: 1 addition & 1 deletion src/platforms/platform.dom.js
Original file line number Diff line number Diff line change
@@ -339,7 +339,7 @@ module.exports = {
// If the canvas is in a shadow DOM, then the styles must also be inserted
// into the same shadow DOM.
// https://github.com/chartjs/Chart.js/issues/5763
var root = canvas.getRootNode();
var root = canvas.getRootNode ? canvas.getRootNode() : document;
var targetNode = root.host ? root : document.head;
injectCSS(targetNode, stylesheet);
}
9 changes: 5 additions & 4 deletions src/plugins/plugin.legend.js
Original file line number Diff line number Diff line change
@@ -53,13 +53,13 @@ defaults._set('global', {
var options = chart.options.legend || {};
var usePointStyle = options.labels && options.labels.usePointStyle;

return chart._getSortedDatasetMetas().map(function(meta, i) {
return chart._getSortedDatasetMetas().map(function(meta) {
var style = meta.controller.getStyle(usePointStyle ? 0 : undefined);

return {
text: datasets[meta.index].label,
fillStyle: style.backgroundColor,
hidden: !chart.isDatasetVisible(i),
hidden: !chart.isDatasetVisible(meta.index),
lineCap: style.borderCapStyle,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
@@ -70,7 +70,7 @@ defaults._set('global', {
rotation: style.rotation,

// Below is extra data used for toggling the datasets
datasetIndex: i
datasetIndex: meta.index
};
}, this);
}
@@ -80,14 +80,15 @@ defaults._set('global', {
legendCallback: function(chart) {
var list = document.createElement('ul');
var datasets = chart.data.datasets;
var globalDefaults = defaults.global;
var i, ilen, listItem, listItemSpan;

list.setAttribute('class', chart.id + '-legend');

for (i = 0, ilen = datasets.length; i < ilen; i++) {
listItem = list.appendChild(document.createElement('li'));
listItemSpan = listItem.appendChild(document.createElement('span'));
listItemSpan.style.backgroundColor = datasets[i].backgroundColor;
listItemSpan.style.backgroundColor = valueOrDefault(datasets[i].backgroundColor, globalDefaults.defaultColor);
if (datasets[i].label) {
listItem.appendChild(document.createTextNode(datasets[i].label));
}
6 changes: 3 additions & 3 deletions test/fixtures/controller.bar/bar-thickness-absolute.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2017", "2018", "2019", "2024", "2025"],
"datasets": [{
"backgroundColor": "rgba(255, 99, 132, 0.5)",
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": 128,
"data": [1, null, 3, 4, 5]
}]
},
@@ -17,9 +20,6 @@
"type": "time",
"offset": true,
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": 128,
"time": {
"parser": "YYYY"
},
6 changes: 3 additions & 3 deletions test/fixtures/controller.bar/bar-thickness-flex-offset.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2017", "2018", "2020", "2024", "2038"],
"datasets": [{
"backgroundColor": "#FF6384",
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": "flex",
"data": [1, null, 3, 4, 5]
}]
},
@@ -17,9 +20,6 @@
"type": "time",
"offset": true,
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": "flex",
"time": {
"parser": "YYYY"
},
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"backgroundColor": "#FF6384",
"barThickness": "flex",
"barPercentage": 1,
"categoryPercentage": 1,
"data": [1]
}]
},
@@ -16,9 +19,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barThickness": "flex",
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
6 changes: 3 additions & 3 deletions test/fixtures/controller.bar/bar-thickness-flex-single.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"backgroundColor": "#FF6384",
"barThickness": "flex",
"barPercentage": 1,
"categoryPercentage": 1,
"data": [1]
}]
},
@@ -16,9 +19,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barThickness": "flex",
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
6 changes: 3 additions & 3 deletions test/fixtures/controller.bar/bar-thickness-flex.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2017", "2018", "2020", "2024", "2038"],
"datasets": [{
"backgroundColor": "#FF6384",
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": "flex",
"data": [1, null, 3, 4, 5]
}]
},
@@ -16,9 +19,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"barThickness": "flex",
"time": {
"parser": "YYYY"
},
6 changes: 3 additions & 3 deletions test/fixtures/controller.bar/bar-thickness-max.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"backgroundColor": "#FF6384",
"barPercentage": 1,
"categoryPercentage": 1,
"maxBarThickness": 8,
"data": [1, null, 3, 4, 5]
}]
},
@@ -16,9 +19,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"maxBarThickness": 8,
"time": {
"parser": "YYYY"
},
4 changes: 2 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-min-interval.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"backgroundColor": "#FF6384",
"barPercentage": 1,
"categoryPercentage": 1,
"data": [1, null, 3, 4, 5]
}]
},
@@ -16,8 +18,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
8 changes: 6 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-multiple.json
Original file line number Diff line number Diff line change
@@ -18,12 +18,16 @@
"responsive": false,
"legend": false,
"title": false,
"datasets": {
"bar": {
"barPercentage": 1,
"categoryPercentage": 1
}
},
"scales": {
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
8 changes: 6 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-no-overlap.json
Original file line number Diff line number Diff line change
@@ -18,12 +18,16 @@
"responsive": false,
"legend": false,
"title": false,
"datasets": {
"bar": {
"barPercentage": 1,
"categoryPercentage": 1
}
},
"scales": {
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY-MM"
},
8 changes: 6 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-offset.json
Original file line number Diff line number Diff line change
@@ -18,13 +18,17 @@
"responsive": false,
"legend": false,
"title": false,
"datasets": {
"bar": {
"barPercentage": 1,
"categoryPercentage": 1
}
},
"scales": {
"xAxes": [{
"type": "time",
"offset": true,
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
8 changes: 6 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-reverse.json
Original file line number Diff line number Diff line change
@@ -18,12 +18,16 @@
"responsive": false,
"legend": false,
"title": false,
"datasets": {
"bar": {
"barPercentage": 1,
"categoryPercentage": 1
}
},
"scales": {
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
4 changes: 2 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-single-xy.json
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@
"data": {
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"barPercentage": 1,
"categoryPercentage": 1,
"backgroundColor": "#FF6384",
"data": [{"x": "2022", "y": 42}]
}]
@@ -16,8 +18,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
4 changes: 2 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-single.json
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@
"data": {
"labels": ["2016", "2018", "2020", "2024", "2030"],
"datasets": [{
"barPercentage": 1,
"categoryPercentage": 1,
"backgroundColor": "#FF6384",
"data": [1]
}]
@@ -16,8 +18,6 @@
"xAxes": [{
"type": "time",
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
8 changes: 6 additions & 2 deletions test/fixtures/controller.bar/bar-thickness-stacked.json
Original file line number Diff line number Diff line change
@@ -18,13 +18,17 @@
"responsive": false,
"legend": false,
"title": false,
"datasets": {
"bar": {
"barPercentage": 1,
"categoryPercentage": 1
}
},
"scales": {
"xAxes": [{
"type": "time",
"stacked": true,
"display": false,
"barPercentage": 1,
"categoryPercentage": 1,
"time": {
"parser": "YYYY"
},
38 changes: 38 additions & 0 deletions test/fixtures/controller.line/clip/default-x-max.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{
"ticks": {
"max": 3,
"display": false
}
}],
"yAxes": [{"ticks": {"display": false}}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions test/fixtures/controller.line/clip/default-x-min.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{
"ticks": {
"min": -2,
"display": false
}
}],
"yAxes": [{"ticks": {"display": false}}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions test/fixtures/controller.line/clip/default-x.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{
"ticks": {
"min": -2,
"max": 3,
"display": false
}
}],
"yAxes": [{"ticks": {"display": false}}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Binary file added test/fixtures/controller.line/clip/default-x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions test/fixtures/controller.line/clip/default-y-max.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{"ticks": {"display": false}}],
"yAxes": [{
"ticks": {
"max": 6,
"display": false
}
}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions test/fixtures/controller.line/clip/default-y-min.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{"ticks": {"display": false}}],
"yAxes": [{
"ticks": {
"min": 2,
"display": false
}
}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions test/fixtures/controller.line/clip/default-y.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [{
"borderColor": "red",
"data": [{"x":-5,"y":5},{"x":-4,"y":6},{"x":-3,"y":7},{"x":-2,"y":6},{"x":-1,"y":5},{"x":0,"y":4},{"x":1,"y":3},{"x":2,"y":2},{"x":3,"y":5},{"x":4,"y":7},{"x":5,"y":9}],
"fill": false,
"showLine": true,
"borderWidth": 20,
"pointRadius": 0
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{"ticks": {"display": false}}],
"yAxes": [{
"ticks": {
"min": 2,
"max": 6,
"display": false
}
}]
},
"layout": {
"padding": 24
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Binary file added test/fixtures/controller.line/clip/default-y.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
77 changes: 77 additions & 0 deletions test/fixtures/controller.line/clip/specified.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{
"config": {
"type": "scatter",
"data": {
"datasets": [
{
"showLine": true,
"borderColor": "red",
"data": [{"x":-4,"y":-4},{"x":4,"y":4}],
"clip": false
},
{
"showLine": true,
"borderColor": "green",
"data": [{"x":-4,"y":-5},{"x":4,"y":3}],
"clip": 5
},
{
"showLine": true,
"borderColor": "blue",
"data": [{"x":-4,"y":-3},{"x":4,"y":5}],
"clip": -5
},
{
"showLine": true,
"borderColor": "brown",
"data": [{"x":-3,"y":-3},{"x":-1,"y":3},{"x":1,"y":-2},{"x":2,"y":3}],
"clip": {
"top": 8,
"left": false,
"right": -20,
"bottom": -20
}
}
]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{
"ticks": {
"min": -2,
"max": 2,
"display": false
}
}],
"yAxes": [{
"ticks": {
"min": -2,
"max": 2,
"display": false
}
}]
},
"layout": {
"padding": 24
},
"elements": {
"line": {
"fill": false,
"borderWidth": 20
},
"point": {
"radius": 0
}
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Binary file added test/fixtures/controller.line/clip/specified.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/controller.line/non-numeric-y.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"config": {
"type": "line",
"data": {
"xLabels": ["January", "February", "March", "April", "May", "June", "July"],
"yLabels": ["", "Request Added", "Request Viewed", "Request Accepted", "Request Solved", "Solving Confirmed"],
"datasets": [{
"label": "My First dataset",
"data": ["", "Request Added", "Request Added", "Request Added", "Request Viewed", "Request Viewed", "Request Viewed"],
"fill": false,
"borderColor": "red",
"backgroundColor": "red"
}]
},
"options": {
"responsive": false,
"legend": false,
"title": false,
"scales": {
"xAxes": [{"display": false}],
"yAxes": [{
"type": "category",
"display": false
}]
}
}
},
"options": {
"canvas": {
"height": 256,
"width": 512
}
}
}
Binary file added test/fixtures/controller.line/non-numeric-y.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ module.exports = {
title: false,
elements: {
line: {
fill: true,
backgroundColor: function(ctx) {
var index = (ctx.dataIndex === undefined ? ctx.datasetIndex : ctx.dataIndex);
return index === 0 ? '#ff0000'
1 change: 1 addition & 0 deletions test/fixtures/controller.radar/backgroundColor/value.js
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ module.exports = {
title: false,
elements: {
line: {
fill: true,
backgroundColor: '#00ff00'
},
point: {
1 change: 1 addition & 0 deletions test/fixtures/controller.radar/borderDash/scriptable.js
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ module.exports = {
title: false,
elements: {
line: {
fill: true,
borderColor: '#00ff00',
borderDash: function(ctx) {
return ctx.datasetIndex === 0 ? [5] : [10];
23 changes: 18 additions & 5 deletions test/specs/controller.bar.tests.js
Original file line number Diff line number Diff line change
@@ -1214,12 +1214,16 @@ describe('Chart.controllers.bar', function() {
options: {
legend: false,
title: false,
datasets: {
bar: {
barPercentage: 1,
}
},
scales: {
xAxes: [{
type: 'category',
display: false,
stacked: true,
barPercentage: 1,
}],
yAxes: [{
type: 'logarithmic',
@@ -1275,12 +1279,16 @@ describe('Chart.controllers.bar', function() {
options: {
legend: false,
title: false,
datasets: {
bar: {
barPercentage: 1,
}
},
scales: {
xAxes: [{
type: 'category',
display: false,
stacked: true,
barPercentage: 1,
}],
yAxes: [{
type: 'logarithmic',
@@ -1593,8 +1601,9 @@ describe('Chart.controllers.bar', function() {
var meta = chart.getDatasetMeta(0);
var yScale = chart.scales[meta.yAxisID];

var categoryPercentage = yScale.options.categoryPercentage;
var barPercentage = yScale.options.barPercentage;
var config = meta.controller._config;
var categoryPercentage = config.categoryPercentage;
var barPercentage = config.barPercentage;
var stacked = yScale.options.stacked;

var totalBarHeight = 0;
@@ -1669,11 +1678,15 @@ describe('Chart.controllers.bar', function() {
options: {
legend: false,
title: false,
datasets: {
bar: {
barThickness: barThickness
}
},
scales: {
xAxes: [{
id: 'x',
type: 'category',
barThickness: barThickness
}],
yAxes: [{
type: 'linear',
40 changes: 40 additions & 0 deletions test/specs/core.layouts.tests.js
Original file line number Diff line number Diff line change
@@ -653,5 +653,45 @@ describe('Chart.layouts', function() {
expect(yAxis.width).toBeCloseToPixel(33);
expect(yAxis.ticks).toEqual(['2.5', '2.0', '1.5', '1.0', '0.5', '0']);
});

it('should correctly handle NaN dimensions', function() {

// issue #7761: Maximum call stack size exceeded
var chartContainer = document.createElement('div');
chartContainer.style.width = '600px';
chartContainer.style.height = '400px';

var chartCanvas = document.createElement('canvas');
chartContainer.appendChild(chartCanvas);

var chart = new Chart(chartCanvas, {
type: 'line',
responsive: true,
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3]
}]
},
options: {
scales: {
yAxes: [{
type: 'linear',
label: 'first axis',
position: 'right'
}, {
type: 'linear',
label: 'second axis',
position: 'right'
}]
}
}
});

expect(chart.width).toBeNaN();
expect(chart.height).toBeNaN();

});
});
});
29 changes: 29 additions & 0 deletions test/specs/helpers.core.tests.js
Original file line number Diff line number Diff line change
@@ -265,6 +265,11 @@ describe('Chart.helpers.core', function() {
});

describe('clone', function() {
it('should not allow prototype pollution', function() {
var test = helpers.clone(JSON.parse('{"__proto__":{"polluted": true}}'));
expect(test.prototype).toBeUndefined();
expect(Object.prototype.polluted).toBeUndefined();
});
it('should clone primitive values', function() {
expect(helpers.clone()).toBe(undefined);
expect(helpers.clone(null)).toBe(null);
@@ -301,9 +306,33 @@ describe('Chart.helpers.core', function() {
expect(output.o.a).not.toBe(a1);
expect(output.a).not.toBe(a0);
});
it('should preserve prototype of objects', function() {
// https://github.com/chartjs/Chart.js/issues/7340
function MyConfigObject(s) {
this._s = s;
}
MyConfigObject.prototype.func = function() {
return 10;
};
var original = new MyConfigObject('something');
var output = helpers.merge({}, {
plugins: [{
test: original
}]
});
var clone = output.plugins[0].test;
expect(clone).toBeInstanceOf(MyConfigObject);
expect(clone).toEqual(original);
expect(clone === original).toBeFalse();
});
});

describe('merge', function() {
it('should not allow prototype pollution', function() {
var test = helpers.merge({}, JSON.parse('{"__proto__":{"polluted": true}}'));
expect(test.prototype).toBeUndefined();
expect(Object.prototype.polluted).toBeUndefined();
});
it('should update target and return it', function() {
var target = {a: 1};
var result = helpers.merge(target, {a: 2, b: 'foo'});
4 changes: 2 additions & 2 deletions test/specs/plugin.legend.tests.js
Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ describe('Legend block tests', function() {
datasetIndex: 1
}, {
text: 'dataset3',
fillStyle: 'rgba(0,0,0,0)',
fillStyle: 'green',
hidden: false,
lineCap: 'butt',
lineDash: [],
@@ -198,7 +198,7 @@ describe('Legend block tests', function() {

expect(chart.legend.legendItems).toEqual([{
text: 'dataset3',
fillStyle: 'rgba(0,0,0,0)',
fillStyle: 'green',
hidden: false,
lineCap: 'butt',
lineDash: [],