Merge pull request #3551 from chartjs/master

Version 2.4.0
This commit is contained in:
Simon Brunel
2016-11-12 18:53:27 +01:00
committed by GitHub
135 changed files with 9420 additions and 5392 deletions

View File

@@ -6,6 +6,7 @@ engines:
- javascript
eslint:
enabled: true
channel: "eslint-3"
fixme:
enabled: true
ratings:

View File

@@ -1,9 +1,40 @@
<!--
Please consider the following before submitting an issue:
Guidelines for contributing: https://github.com/chartjs/Chart.js/blob/master/CONTRIBUTING.md
- Issues are reserved for BUG reports and FEATURE requests, DO NOT create issues for questions or support requests.
- Most features should start as plugins outside of Chart.js (http://www.chartjs.org/docs/#advanced-usage-creating-plugins).
- Bug reports MUST be submitted with an interactive example (http://codepen.io/pen?template=JXVYzq).
- Chart.js 1.x is NOT supported anymore, new issues will be disregarded.
-->
Example of issue on an interactive website such as the following:
- http://jsbin.com/
- http://jsfiddle.net/
- http://codepen.io/pen/
- Premade template: http://codepen.io/pen?template=JXVYzq
<!--- Provide a general summary of the issue in the Title above prefixed by [BUG] or [FEATURE] -->
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->
## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
## Steps to Reproduce (for bugs)
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
1.
2.
3.
4.
## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
## Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Chart.js version:
* Browser name and version:
* Link to your project:

1
.gitignore vendored
View File

@@ -6,4 +6,5 @@
.DS_Store
.idea
.vscode
bower.json

View File

@@ -21,7 +21,7 @@ Reporting bugs
Well structured, detailed bug reports are hugely valuable for the project.
Guidlines for reporting bugs:
Guidelines for reporting bugs:
- Check the issue search to see if it has already been reported
- Isolate the problem to a simple test case

View File

@@ -8,7 +8,7 @@
## Installation
You can download the latest version of [Chart.js on GitHub](https://github.com/chartjs/Chart.js/releases/latest) or just use these [Chart.js CDN](https://cdnjs.com/libraries/Chart.js) links.
You can download the latest version of Chart.js from the [GitHub releases](https://github.com/chartjs/Chart.js/releases/latest) or use a [Chart.js CDN](https://cdnjs.com/libraries/Chart.js).
To install via npm:
@@ -16,7 +16,16 @@ To install via npm:
npm install chart.js --save
```
To Install via bower, please follow [these instructions](http://www.chartjs.org/docs/#getting-started-installation).
To install via bower:
```bash
bower install chart.js --save
```
#### Selecting the Correct Build
Chart.js provides two different builds that are available for your use. The `Chart.js` and `Chart.min.js` files include Chart.js and the accompanying color parsing library. If this version is used and you require the use of the time axis, [Moment.js](http://momentjs.com/) will need to be included before Chart.js.
The `Chart.bundle.js` and `Chart.bundle.min.js` builds include Moment.js in a single file. This version should be used if you require time axes and want a single file to include, select this version. Do not use this build if your application already includes Moment.js. If you do, Moment.js will be included twice, increasing the page load time and potentially introducing version issues.
## Documentation

View File

@@ -71,6 +71,7 @@ To create a chart, we need to instantiate the `Chart` class. To do this, we need
var ctx = document.getElementById("myChart");
var ctx = document.getElementById("myChart").getContext("2d");
var ctx = $("#myChart");
var ctx = "myChart";
```
Once you have the element or context, you're ready to instantiate a pre-defined chart-type or create your own!

View File

@@ -36,13 +36,13 @@ This concept was introduced in Chart.js 1.0 to keep configuration [DRY](https://
Chart.js merges the options object passed to the chart with the global configuration using chart type defaults and scales defaults appropriately. This way you can be as specific as you would like in your individual chart configuration, while still changing the defaults for all chart types where applicable. The global general options are defined in `Chart.defaults.global`. The defaults for each chart type are discussed in the documentation for that chart type.
The following example would set the hover mode to 'single' for all charts where this was not overridden by the chart type defaults or the options passed to the constructor on creation.
The following example would set the hover mode to 'nearest' for all charts where this was not overridden by the chart type defaults or the options passed to the constructor on creation.
```javascript
Chart.defaults.global.hover.mode = 'single';
Chart.defaults.global.hover.mode = 'nearest';
// Hover mode is set to single because it was not overridden here
var chartInstanceHoverModeSingle = new Chart(ctx, {
// Hover mode is set to nearest because it was not overridden here
var chartInstanceHoverModeNearest = new Chart(ctx, {
type: 'line',
data: data,
});
@@ -54,7 +54,7 @@ var chartInstanceDifferentHoverMode = new Chart(ctx, {
options: {
hover: {
// Overrides the global setting
mode: 'label'
mode: 'index'
}
}
})
@@ -83,7 +83,16 @@ maintainAspectRatio | Boolean | true | Maintain the original canvas aspect ratio
events | Array[String] | `["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]` | Events that the chart should listen to for tooltips and hovering
onClick | Function | null | Called if the event is of type 'mouseup' or 'click'. Called in the context of the chart and passed an array of active elements
legendCallback | Function | ` function (chart) { }` | Function to generate a legend. Receives the chart object to generate a legend from. Default implementation returns an HTML string.
onResize | Function | null | Called when a resize occurs. Gets passed two arguemnts: the chart instance and the new size.
onResize | Function | null | Called when a resize occurs. Gets passed two arguments: the chart instance and the new size.
### Layout Configuration
The layout configuration is passed into the `options.layout` namespace. The global options for the chart layout is defined in `Chart.defaults.global.layout`.
Name | Type | Default | Description
--- | --- | --- | ---
padding | Number or Object | 0 | The padding to add inside the chart. If this value is a number, it is applied to all sides of the chart (left, top, right, bottom). If this value is an object, the `left` property defines the left padding. Similarly the `right`, `top`, and `bottom` properties can also be specified.
### Title Configuration
@@ -130,6 +139,7 @@ fullWidth | Boolean | true | Marks that this box should take the full width of t
onClick | Function | `function(event, legendItem) {}` | A callback that is called when a 'click' event is registered on top of a label item
onHover | Function | `function(event, legendItem) {}` | A callback that is called when a 'mousemove' event is registered on top of a label item
labels |Object|-| See the [Legend Label Configuration](#chart-configuration-legend-label-configuration) section below.
reverse | Boolean | false | Legend will show datasets in reverse order
#### Legend Label Configuration
@@ -145,7 +155,6 @@ fontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | Fon
padding | Number | 10 | Padding between rows of colored boxes
generateLabels: | Function | `function(chart) { }` | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. See [Legend Item](#chart-configuration-legend-item-interface) for details.
usePointStyle | Boolean | false | Label style will match corresponding point style (size is based on fontSize, boxWidth is not used in this case).
reverse | Boolean | false | Legend will show datasets in reverse order
#### Legend Item Interface
@@ -200,7 +209,7 @@ var chartInstance = new Chart(ctx, {
fontColor: 'rgb(255, 99, 132)'
}
}
}
}
});
```
@@ -212,8 +221,11 @@ Name | Type | Default | Description
--- | --- | --- | ---
enabled | Boolean | true | Are tooltips enabled
custom | Function | null | See [section](#advanced-usage-external-tooltips) below
mode | String | 'single' | Sets which elements appear in the tooltip. Acceptable options are `'single'`, `'label'` or `'x-axis'`. <br>&nbsp;<br>`single` highlights the closest element. <br>&nbsp;<br>`label` highlights elements in all datasets at the same `X` value. <br>&nbsp;<br>`'x-axis'` also highlights elements in all datasets at the same `X` value, but activates when hovering anywhere within the vertical slice of the x-axis representing that `X` value.
mode | String | 'nearest' | Sets which elements appear in the tooltip. See [Interaction Modes](#interaction-modes) for details
intersect | Boolean | true | if true, the tooltip mode applies only when the mouse position intersects with an element. If false, the mode will be applied at all times.
position | String | 'average' | The mode for positioning the tooltip. 'average' mode will place the tooltip at the average position of the items displayed in the tooltip. 'nearest' will place the tooltip at the position of the element closest to the event position. New modes can be defined by adding functions to the Chart.Tooltip.positioners map.
itemSort | Function | undefined | Allows sorting of [tooltip items](#chart-configuration-tooltip-item-interface). Must implement at minimum a function that can be passed to [Array.prototype.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort). This function can also accept a third parameter that is the data object passed to the chart.
filter | Function | undefined | Allows filtering of [tooltip items](#chart-configuration-tooltip-item-interface). Must implement at minimum a function that can be passed to [Array.prototype.filter](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). This function can also accept a second parameter that is the data object passed to the chart.
backgroundColor | Color | 'rgba(0,0,0,0.8)' | Background color of the tooltip
titleFontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | Font family for tooltip title inherited from global font family
titleFontSize | Number | 12 | Font size for tooltip title inherited from global font size
@@ -237,6 +249,7 @@ yPadding | Number | 6 | Padding to add on top and bottom of tooltip
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
displayColors | Boolean | true | if true, color boxes are shown in the tooltip
callbacks | Object | | See the [callbacks section](#chart-configuration-tooltip-callbacks) below
#### Tooltip Callbacks
@@ -253,12 +266,13 @@ afterTitle | `Array[tooltipItem], data` | Text to render after the title
beforeBody | `Array[tooltipItem], data` | Text to render before the body section
beforeLabel | `tooltipItem, data` | Text to render before an individual label
label | `tooltipItem, data` | Text to render for an individual item in the tooltip
labelColor | `tooltipItem, chartInstace` | Returns the colors to render for the tooltip item. Return as an object containing two parameters: `borderColor` and `backgroundColor`.
labelColor | `tooltipItem, chartInstance` | Returns the colors to render for the tooltip item. Return as an object containing two parameters: `borderColor` and `backgroundColor`.
afterLabel | `tooltipItem, data` | Text to render after an individual label
afterBody | `Array[tooltipItem], data` | Text to render after the body section
beforeFooter | `Array[tooltipItem], data` | Text to render before the footer section
footer | `Array[tooltipItem], data` | Text to render as the footer
afterFooter | `Array[tooltipItem], data` | Text to render after the footer section
dataPoints | `Array[tooltipItem]` | List of matching point informations.
#### Tooltip Item Interface
@@ -276,7 +290,13 @@ The tooltip items passed to the tooltip callbacks implement the following interf
datasetIndex: Number,
// Index of this data item in the dataset
index: Number
index: Number,
// X position of matching point
x: Number,
// Y position of matching point
y: Number,
}
```
@@ -286,10 +306,28 @@ The hover configuration is passed into the `options.hover` namespace. The global
Name | Type | Default | Description
--- | --- | --- | ---
mode | String | 'single' | Sets which elements hover. Acceptable options are `'single'`, `'label'`, `'x-axis'`, or `'dataset'`. <br>&nbsp;<br>`single` highlights the closest element. <br>&nbsp;<br>`label` highlights elements in all datasets at the same `X` value. <br>&nbsp;<br>`'x-axis'` also highlights elements in all datasets at the same `X` value, but activates when hovering anywhere within the vertical slice of the x-axis representing that `X` value. <br>&nbsp;<br>`dataset` highlights the closest dataset.
mode | String | 'nearest' | Sets which elements appear in the tooltip. See [Interaction Modes](#interaction-modes) for details
intersect | Boolean | true | if true, the hover mode only applies when the mouse position intersects an item on the chart
animationDuration | Number | 400 | Duration in milliseconds it takes to animate hover style changes
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)
### Interaction Modes
When configuring interaction with the graph via hover or tooltips, a number of different modes are available.
The following table details the modes and how they behave in conjunction with the `intersect` setting
Mode | Behaviour
--- | ---
point | Finds all of the items that intersect the point
nearest | Gets the item that is nearest to the point. The nearest item is determined based on the distance to the center of the chart item (point, bar). If 2 or more items are at the same distance, the one with the smallest area is used. If `intersect` is true, this is only triggered when the mouse position intersects an item in the graph. This is very useful for combo charts where points are hidden behind bars.
single (deprecated) | Finds the first item that intersects the point and returns it. Behaves like 'nearest' mode with intersect = true.
label (deprecated) | See `'index'` mode
index | Finds item at the same index. If the `intersect` setting is true, the first intersecting item is used to determine the index in the data. If `intersect` false the nearest item is used to determine the index.
x-axis (deprecated) | Behaves like `'index'` mode with `intersect = true`
dataset | Finds items in the same dataset. If the `intersect` setting is true, the first intersecting item is used to determine the index in the data. If `intersect` false the nearest item is used to determine the index.
x | Returns all items that would intersect based on the `X` coordinate of the position only. Would be useful for a vertical cursor implementation. Note that this only applies to cartesian charts
y | Returns all items that would intersect based on the `Y` coordinate of the position. This would be useful for a horizontal cursor implementation. Note that this only applies to cartesian charts.
### Animation Configuration
The following animation options are available. The global options for are defined in `Chart.defaults.global.animation`.
@@ -305,7 +343,7 @@ onComplete | Function | none | Callback called at the end of an animation. Passe
The `onProgress` and `onComplete` callbacks are useful for synchronizing an external draw to the chart animation. The callback is passed an object that implements the following interface. An example usage of these callbacks can be found on [Github](https://github.com/chartjs/Chart.js/blob/master/samples/AnimationCallbacks/progress-bar.html). This sample displays a progress bar showing how far along the animation is.
```javscript
```javascript
{
// Chart object
chartInstance,
@@ -345,7 +383,7 @@ The animation object passed to the callbacks is of type `Chart.Animation`. The o
The global options for elements are defined in `Chart.defaults.global.elements`.
Options can be configured for four different types of elements; arc, lines, points, and rectangles. When set, these options apply to all objects of that type unless specifically overridden by the configuration attached to a dataset.
Options can be configured for four different types of elements: arc, lines, points, and rectangles. When set, these options apply to all objects of that type unless specifically overridden by the configuration attached to a dataset.
#### Arc Configuration
@@ -372,7 +410,7 @@ borderDash | Array | `[]` | Default line dash. See [MDN](https://developer.mozil
borderDashOffset | Number | 0.0 | Default line dash offset. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
borderJoinStyle | String | 'miter' | Default line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
capBezierPoints | Boolean | true | If true, bezier control points are kept inside the chart. If false, no restriction is enforced.
fill | Boolean | true | If true, the line is filled.
fill | Boolean or String | true | If true, the fill is assumed to be to zero. String values are 'zero', 'top', and 'bottom' to fill to different locations. If `false`, no fill is added
stepped | Boolean | false | If true, the line is shown as a stepped line and 'tension' will be ignored
#### Point Configuration
@@ -451,7 +489,7 @@ var chartData = {
### Mixed Chart Types
When creating a chart, you have the option to overlay different chart types on top of eachother as separate datasets.
When creating a chart, you have the option to overlay different chart types on top of each other as separate datasets.
To do this, you must set a `type` for each dataset individually. You can create mixed chart types with bar and line chart types.

View File

@@ -59,7 +59,7 @@ offsetGridLines | Boolean | false | If true, labels are shifted to be between gr
#### Scale Title Configuration
The grid line configuration is nested under the scale configuration in the `scaleLabel` key. It defines options for the scale title.
The scale label configuration is nested under the scale configuration in the `scaleLabel` key. It defines options for the scale title.
Name | Type | Default | Description
--- | --- | --- | ---
@@ -72,11 +72,12 @@ fontStyle | String | "normal" | Font style for the scale title, follows CSS font
#### Tick Configuration
The grid line configuration is nested under the scale configuration in the `ticks` key. It defines options for the tick marks that are generated by the axis.
The tick configuration is nested under the scale configuration in the `ticks` key. It defines options for the tick marks that are generated by the axis.
Name | Type | Default | Description
--- | --- | --- | ---
autoSkip | Boolean | true | If true, automatically calculates how many labels that can be shown and hides labels accordingly. Turn it off to show all labels no matter what
autoSkipPadding | Number | 0 | Padding between the ticks on the horizontal axis when `autoSkip` is enabled. *Note: Only applicable to horizontal scales.*
callback | Function | `function(value) { return helpers.isArray(value) ? value : '' + value; }` | Returns the string representation of the tick value as it should be displayed on the chart. See [callback](#scales-creating-custom-tick-formats) section below.
display | Boolean | true | If true, show the ticks.
fontColor | Color | "#666" | Font color for the tick labels.
@@ -301,7 +302,7 @@ var chartInstance = new Chart(ctx, {
### Radial Linear Scale
The radial linear scale is used specifically for the radar and polar are chart types. It overlays the chart area, rather than being positioned on one of the edges.
The radial linear scale is used specifically for the radar and polar area chart types. It overlays the chart area, rather than being positioned on one of the edges.
#### Configuration Options

View File

@@ -28,19 +28,27 @@ myLineChart.destroy();
Triggers an update of the chart. This can be safely called after replacing the entire data object. This will update all scales, legends, and then re-render the chart.
```javascript
// duration is the time for the animation of the redraw in miliseconds
// lazy is a boolean. if true, the animation can be interupted by other animations
// duration is the time for the animation of the redraw in milliseconds
// lazy is a boolean. if true, the animation can be interrupted by other animations
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
```
#### .reset()
Reset the chart to it's state before the initial animation. A new animation can then be triggered using `update`.
```javascript
myLineChart.reset();
```
#### .render(duration, lazy)
Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use `.update()` in that case.
```javascript
// duration is the time for the animation of the redraw in miliseconds
// lazy is a boolean. if true, the animation can be interupted by other animations
// duration is the time for the animation of the redraw in milliseconds
// lazy is a boolean. if true, the animation can be interrupted by other animations
myLineChart.render(duration, lazy);
```
@@ -165,6 +173,8 @@ var myPieChart = new Chart(ctx, {
// tooltip.text
// tooltip.x
// tooltip.y
// tooltip.caretX
// tooltip.caretY
// etc...
}
}
@@ -216,12 +226,12 @@ Scale instances are given the following properties during the fitting process.
{
left: Number, // left edge of the scale bounding box
right: Number, // right edge of the bounding box'
top: Number,
top: Number,
bottom: Number,
width: Number, // the same as right - left
height: Number, // the same as bottom - top
// Margin on each side. Like css, this is outside the bounding box.
// Margin on each side. Like css, this is outside the bounding box.
margins: {
left: Number,
right: Number,
@@ -238,7 +248,7 @@ Scale instances are given the following properties during the fitting process.
```
#### Scale Interface
To work with Chart.js, custom scale types must implement the following interface.
To work with Chart.js, custom scale types must implement the following interface.
```javascript
{
@@ -273,10 +283,10 @@ To work with Chart.js, custom scale types must implement the following interface
Optionally, the following methods may also be overwritten, but an implementation is already provided by the `Chart.Scale` base class.
```javascript
// Transform the ticks array of the scale instance into strings. The default implementation simply calls this.options.ticks.callback(numericalTick, index, ticks);
// Transform the ticks array of the scale instance into strings. The default implementation simply calls this.options.ticks.callback(numericalTick, index, ticks);
convertTicksToLabels: function() {},
// Determine how much the labels will rotate by. The default implementation will only rotate labels if the scale is horizontal.
// Determine how much the labels will rotate by. The default implementation will only rotate labels if the scale is horizontal.
calculateTickRotation: function() {},
// Fits the scale into the canvas.
@@ -293,7 +303,7 @@ Optionally, the following methods may also be overwritten, but an implementation
The Core.Scale base class also has some utility functions that you may find useful.
```javascript
{
{
// Returns true if the scale instance is horizontal
isHorizontal: function() {},
@@ -363,7 +373,7 @@ The following methods may optionally be overridden by derived dataset controller
// chart types using a single scale
linkScales: function() {},
// Called by the main chart controller when an update is triggered. The default implementation handles the number of data points changing and creating elements appropriately.
// Called by the main chart controller when an update is triggered. The default implementation handles the number of data points changing and creating elements appropriately.
buildOrUpdateElements: function() {}
}
```
@@ -432,7 +442,7 @@ Plugins should derive from Chart.PluginBase and implement the following interfac
### Building Chart.js
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.
Firstly, we need to ensure development dependencies are installed. With node and npm installed, after cloning the Chart.js repo to a local directory, and navigating to that directory in the command line, we can run the following:

View File

@@ -49,31 +49,31 @@ Library Features
| Feature | Chart.js | D3 | HighCharts | Chartist |
| ------- | -------- | --- | ---------- | -------- |
| Completely Free | ✓ | ✓ | | ✓ |
| Canvas | | | | |
| SVG | | ✓ | ✓ | ✓ |
| Built-in Charts | ✓ | | ✓ | ✓ |
| 8+ Chart Types | ✓ | ✓ | ✓ | |
| Extendable to Custom Charts | ✓ | ✓ | | |
| Supports Modern Browsers | ✓ | ✓ | ✓ | ✓ |
| Extensive Documentation | ✓ | ✓ | ✓ | ✓ |
| Open Source | ✓ | ✓ | ✓ | ✓ |
| Completely Free | &check; | &check; | | &check; |
| Canvas | &check; | | | |
| SVG | | &check; | &check; | &check; |
| Built-in Charts | &check; | | &check; | &check; |
| 8+ Chart Types | &check; | &check; | &check; | |
| Extendable to Custom Charts | &check; | &check; | | |
| Supports Modern Browsers | &check; | &check; | &check; | &check; |
| Extensive Documentation | &check; | &check; | &check; | &check; |
| Open Source | &check; | &check; | &check; | &check; |
Built in Chart Types
| Type | Chart.js | HighCharts | Chartist |
| ---- | -------- | ---------- | -------- |
| Combined Types | ✓ | ✓ | |
| Line | ✓ | ✓ | ✓ |
| Bar | ✓ | ✓ | ✓ |
| Horizontal Bar | ✓ | ✓ | ✓ |
| Pie/Doughnut | ✓ | ✓ | ✓ |
| Polar Area | ✓ | ✓ | |
| Radar | | | |
| Scatter | ✓ | ✓ | ✓ |
| Bubble | | | |
| Gauges | | | |
| Maps (Heat/Tree/etc.) | | | |
| Combined Types | &check; | &check; | |
| Line | &check; | &check; | &check; |
| Bar | &check; | &check; | &check; |
| Horizontal Bar | &check; | &check; | &check; |
| Pie/Doughnut | &check; | &check; | &check; |
| Polar Area | &check; | &check; | |
| Radar | &check; | | |
| Scatter | &check; | &check; | &check; |
| Bubble | &check; | | |
| Gauges | | &check; | |
| Maps (Heat/Tree/etc.) | | &check; | |
### Popular Plugins

View File

@@ -17,10 +17,12 @@ var browserify = require('browserify');
var source = require('vinyl-source-stream');
var merge = require('merge-stream');
var collapse = require('bundle-collapser/plugin');
var argv = require('yargs').argv
var package = require('./package.json');
var srcDir = './src/';
var outDir = './dist/';
var testDir = './test/';
var header = "/*!\n" +
" * Chart.js\n" +
@@ -33,17 +35,11 @@ var header = "/*!\n" +
" */\n";
var preTestFiles = [
'./node_modules/moment/min/moment.min.js',
'./node_modules/moment/min/moment.min.js'
];
var testFiles = [
'./test/mockContext.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'
'./test/*.js'
];
gulp.task('bower', bowerTask);
@@ -133,6 +129,7 @@ function packageTask() {
function lintTask() {
var files = [
srcDir + '**/*.js',
testDir + '**/*.js'
];
// NOTE(SB) codeclimate has 'complexity' and 'max-statements' eslint rules way too strict
@@ -142,7 +139,22 @@ function lintTask() {
rules: {
'complexity': [1, 6],
'max-statements': [1, 30]
}
},
globals: [
'Chart',
'acquireChart',
'afterAll',
'afterEach',
'beforeAll',
'beforeEach',
'describe',
'expect',
'it',
'jasmine',
'moment',
'spyOn',
'xit'
]
};
return gulp.src(files)
@@ -157,10 +169,13 @@ function validHTMLTask() {
}
function startTest() {
var files = ['./src/**/*.js'];
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return files;
return [].concat(preTestFiles).concat([
'./src/**/*.js',
'./test/mockContext.js'
]).concat(
argv.inputs?
argv.inputs.split(';'):
testFiles);
}
function unittestTask() {

View File

@@ -2,7 +2,7 @@
"name": "chart.js",
"homepage": "http://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "2.3.0",
"version": "2.4.0",
"license": "MIT",
"main": "src/chart.js",
"repository": {
@@ -17,7 +17,7 @@
"gulp": "3.9.x",
"gulp-concat": "~2.1.x",
"gulp-connect": "~2.0.5",
"gulp-eslint": "^2.0.0",
"gulp-eslint": "^3.0.0",
"gulp-file": "^0.3.0",
"gulp-html-validator": "^0.0.2",
"gulp-insert": "~0.5.0",
@@ -38,7 +38,9 @@
"karma-jasmine": "^0.3.6",
"karma-jasmine-html-reporter": "^0.1.8",
"merge-stream": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.7.0",
"yargs": "^5.0.0"
},
"spm": {
"main": "Chart.js"

View File

@@ -1,170 +0,0 @@
<!doctype html>
<html>
<head>
<title> Animation Callbacks </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>
<progress id="animationProgress" max="1" value="0" style="width: 100%"></progress>
</div>
<br>
<br>
<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.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var $progress = $('#animationProgress');
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset ",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset ",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
title:{
display:true,
text:"Chart.js Line Chart - Animation Progress Bar"
},
animation: {
duration: 2000,
onProgress: function(animation) {
$progress.attr({
value: animation.animationObject.currentStep / animation.animationObject.numSteps,
});
},
onComplete: function(animation) {
window.setTimeout(function() {
$progress.attr({
value: 0
});
}, 2000);
}
},
tooltips: {
mode: 'label',
},
scales: {
xAxes: [{
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
scaleLabel: {
show: true,
labelString: 'Value'
},
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!doctype html>
<html>
<head>
<title> Animation Callbacks </title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<progress id="animationProgress" max="1" value="0" style="width: 100%"></progress>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var progress = document.getElementById('animationProgress');
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
fill: false,
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset ",
fill: false,
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
},
options: {
title:{
display:true,
text: "Chart.js Line Chart - Animation Progress Bar"
},
animation: {
duration: 2000,
onProgress: function(animation) {
progress.value = animation.animationObject.currentStep / animation.animationObject.numSteps;
},
onComplete: function(animation) {
window.setTimeout(function() {
progress.value = 0;
}, 2000);
}
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,102 +0,0 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Multi Axis</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 style="width: 75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
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 barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
yAxisID: "y-axis-1",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
yAxisID: "y-axis-2",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: [randomColor(), randomColor(), randomColor(), randomColor(), randomColor(), randomColor(), randomColor()],
yAxisID: "y-axis-1",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = Chart.Bar(ctx, {
data: barChartData,
options: {
responsive: true,
hoverMode: 'label',
hoverAnimationDuration: 400,
stacked: false,
title:{
display:true,
text:"Chart.js Bar Chart - Multi Axis"
},
scales: {
yAxes: [{
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "left",
id: "y-axis-1",
}, {
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "right",
id: "y-axis-2",
gridLines: {
drawOnChartArea: false
}
}],
}
}
});
};
$('#randomizeData').click(function() {
$.each(barChartData.datasets, function(i, dataset) {
if (Chart.helpers.isArray(dataset.backgroundColor)) {
dataset.backgroundColor= [randomColor(), randomColor(), randomColor(), randomColor(), randomColor(), randomColor(), randomColor()];
} else {
dataset.backgroundColor= randomColor();
}
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
});
window.myBar.update();
});
</script>
</body>
</html>

View File

@@ -1,84 +0,0 @@
<!doctype html>
<html>
<head>
<title>Stacked 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 style="width: 75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
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 barChartData = {
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()]
}, {
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.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title:{
display:true,
text:"Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
};
$('#randomizeData').click(function() {
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
});
window.myBar.update();
});
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<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>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -25,32 +25,36 @@
<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 color = Chart.helpers.color;
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()]
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
borderWidth: 1,
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()]
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
@@ -62,12 +66,10 @@
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
// In this case, we are setting the border of each horizontal bar to be 2px wide
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'left'
}
},
responsive: true,
@@ -83,10 +85,9 @@
};
$('#randomizeData').click(function() {
document.getElementById('randomizeData').addEventListener('click', function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(horizontalBarChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
horizontalBarChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return zero ? 0.0 : randomScalingFactor();
});
@@ -95,10 +96,15 @@
window.myHorizontalBar.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[horizontalBarChartData.datasets.length % colorNames.length];;
var dsColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + horizontalBarChartData.datasets.length,
backgroundColor: randomColor(),
backgroundColor: color(dsColor).alpha(0.5).rgbString(),
borderColor: dsColor,
data: []
};
@@ -110,7 +116,7 @@
window.myHorizontalBar.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (horizontalBarChartData.datasets.length > 0) {
var month = MONTHS[horizontalBarChartData.labels.length % MONTHS.length];
horizontalBarChartData.labels.push(month);
@@ -123,12 +129,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
horizontalBarChartData.datasets.splice(0, 1);
window.myHorizontalBar.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
horizontalBarChartData.labels.splice(-1, 1); // remove the label first
horizontalBarChartData.datasets.forEach(function (dataset, datasetIndex) {

View File

@@ -0,0 +1,108 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Multi Axis</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: [
window.chartColors.red,
window.chartColors.orange,
window.chartColors.yellow,
window.chartColors.green,
window.chartColors.blue,
window.chartColors.purple,
window.chartColors.red
],
yAxisID: "y-axis-1",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: 'Dataset 2',
backgroundColor: window.chartColors.grey,
yAxisID: "y-axis-2",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Bar Chart - Multi Axis"
},
tooltips: {
mode: 'index',
intersect: true
},
scales: {
yAxes: [{
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "left",
id: "y-axis-1",
}, {
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "right",
id: "y-axis-2",
gridLines: {
drawOnChartArea: false
}
}],
}
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
barChartData.datasets.forEach(function(dataset, i) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myBar.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,102 @@
<!doctype html>
<html>
<head>
<title>Stacked Bar Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: 'Dataset 2',
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: 'Dataset 3',
backgroundColor: window.chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title:{
display:true,
text:"Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'index',
intersect: false
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
barChartData.datasets.forEach(function(dataset, i) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myBar.update();
});
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<head>
<title>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>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -25,32 +25,37 @@
<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 color = Chart.helpers.color;
var barChartData = {
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()]
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
borderWidth: 1,
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()]
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
borderWidth: 1,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
@@ -61,15 +66,6 @@
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
@@ -83,10 +79,9 @@
};
$('#randomizeData').click(function() {
document.getElementById('randomizeData').addEventListener('click', function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
barChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return zero ? 0.0 : randomScalingFactor();
});
@@ -95,10 +90,15 @@
window.myBar.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[barChartData.datasets.length % colorNames.length];;
var dsColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + barChartData.datasets.length,
backgroundColor: randomColor(),
backgroundColor: color(dsColor).alpha(0.5).rgbString(),
borderColor: dsColor,
borderWidth: 1,
data: []
};
@@ -110,7 +110,7 @@
window.myBar.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (barChartData.datasets.length > 0) {
var month = MONTHS[barChartData.labels.length % MONTHS.length];
barChartData.labels.push(month);
@@ -124,12 +124,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
barChartData.datasets.splice(0, 1);
window.myBar.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
barChartData.labels.splice(-1, 1); // remove the label first
barChartData.datasets.forEach(function(dataset, datasetIndex) {

View File

@@ -3,8 +3,8 @@
<head>
<title>Bubble 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>
<script src="utils.js"></script>
<style type="text/css">
canvas{
-moz-user-select: none;
@@ -27,24 +27,16 @@
var DEFAULT_DATASET_SIZE = 7;
var addedCount = 0;
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 color = Chart.helpers.color;
var bubbleChartData = {
animation: {
duration: 10000
},
datasets: [{
label: "My First dataset",
backgroundColor: randomColor(),
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
borderWidth: 1,
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
@@ -76,7 +68,9 @@
}]
}, {
label: "My Second dataset",
backgroundColor: randomColor(),
backgroundColor: color(window.chartColors.orange).alpha(0.5).rgbString(),
borderColor: window.chartColors.orange,
borderWidth: 1,
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
@@ -120,14 +114,15 @@
display:true,
text:'Chart.js Bubble Chart'
},
tooltips: {
mode: 'point'
}
}
});
};
$('#randomizeData').click(function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(bubbleChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
document.getElementById('randomizeData').addEventListener('click', function() {
bubbleChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return {
x: randomScalingFactor(),
@@ -139,11 +134,16 @@
window.myChart.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
++addedCount;
var colorName = colorNames[bubbleChartData.datasets.length % colorNames.length];;
var dsColor = window.chartColors[colorName];
var newDataset = {
label: "My added dataset " + addedCount,
backgroundColor: randomColor(),
backgroundColor: color(dsColor).alpha(0.5).rgbString(),
borderColor: dsColor,
borderWidth: 1,
data: []
};
@@ -159,7 +159,7 @@
window.myChart.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (bubbleChartData.datasets.length > 0) {
for (var index = 0; index < bubbleChartData.datasets.length; ++index) {
bubbleChartData.datasets[index].data.push({
@@ -173,13 +173,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
bubbleChartData.datasets.splice(0, 1);
window.myChart.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
bubbleChartData.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});

View File

@@ -3,8 +3,8 @@
<head>
<title>Combo Bar-Line 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>
<script src="utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -20,35 +20,52 @@
</div>
<button id="randomizeData">Randomize Data</button>
<script>
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 chartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'line',
label: 'Dataset 1',
borderColor: window.chartColors.blue,
borderWidth: 2,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
borderColor: 'white',
borderWidth: 2
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, ]
backgroundColor: window.chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
window.onload = function() {
@@ -61,16 +78,20 @@
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
},
tooltips: {
mode: 'index',
intersect: true
}
}
});
};
$('#randomizeData').click(function() {
$.each(chartData.datasets, function(i, dataset) {
dataset.backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
document.getElementById('randomizeData').addEventListener('click', function() {
chartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myMixedChart.update();
});

View File

@@ -1,95 +0,0 @@
<!doctype html>
<html>
<head>
<title>Combo Bar-Line 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 style="width: 75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
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 barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'line',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, ]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
},
animation: {
onComplete: function () {
var chartInstance = this.chart;
var ctx = chartInstance.ctx;
ctx.textAlign = "center";
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);
}
}
}
});
};
$('#randomizeData').click(function() {
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
});
window.myBar.update();
});
</script>
</body>
</html>

132
samples/data_labelling.html Normal file
View File

@@ -0,0 +1,132 @@
<!doctype html>
<html>
<head>
<title>Labelling Data Points</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var color = Chart.helpers.color;
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
type: 'line',
label: 'Dataset 2',
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: color(window.chartColors.green).alpha(0.2).rgbString(),
borderColor: window.chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
// Define a plugin to provide data labels
Chart.plugins.register({
afterDatasetsDraw: function(chartInstance, easing) {
// To only draw at the end of animation, check for easing === 1
var ctx = chartInstance.chart.ctx;
chartInstance.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach(function(element, index) {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgb(0, 0, 0)';
var fontSize = 16;
var fontStyle = 'normal';
var fontFamily = 'Helvetica Neue';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
// Just naively convert to string for now
var dataString = dataset.data[index].toString();
// Make sure alignment settings are correct
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var padding = 5;
var position = element.tooltipPosition();
ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
});
}
});
}
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
},
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
barChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
})
});
window.myBar.update();
});
</script>
</body>
</html>

View File

@@ -1,154 +0,0 @@
<!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

@@ -4,7 +4,7 @@
<head>
<title>Doughnut 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>
<script src="utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -15,7 +15,7 @@
</head>
<body>
<div id="canvas-holder" style="width:75%">
<div id="canvas-holder" style="width:40%">
<canvas id="chart-area" />
</div>
<button id="randomizeData">Randomize Data</button>
@@ -27,12 +27,6 @@
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'doughnut',
@@ -46,53 +40,20 @@
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
window.chartColors.red,
window.chartColors.orange,
window.chartColors.yellow,
window.chartColors.green,
window.chartColors.blue,
],
label: 'Dataset 1'
}, {
hidden: true,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Dataset 2'
}, {
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Dataset 3'
}],
labels: [
"Red",
"Green",
"Orange",
"Yellow",
"Grey",
"Dark Grey"
"Green",
"Blue"
]
},
options: {
@@ -116,21 +77,18 @@
window.myDoughnut = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
dataset.backgroundColor = dataset.backgroundColor.map(function() {
return randomColor(0.7);
});
});
window.myDoughnut.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var newDataset = {
backgroundColor: [],
data: [],
@@ -139,35 +97,41 @@
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
newDataset.backgroundColor.push(randomColor(0.7));
var colorName = colorNames[index % colorNames.length];;
var newColor = window.chartColors[colorName];
newDataset.backgroundColor.push(newColor);
}
config.data.datasets.push(newDataset);
window.myDoughnut.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('data #' + config.data.labels.length);
$.each(config.data.datasets, function(index, dataset) {
var colorName = colorNames[config.data.datasets[0].data.length % colorNames.length];;
var newColor = window.chartColors[colorName];
config.data.datasets.forEach(function(dataset) {
dataset.data.push(randomScalingFactor());
dataset.backgroundColor.push(randomColor(0.7));
dataset.backgroundColor.push(newColor);
});
window.myDoughnut.update();
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myDoughnut.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
config.data.datasets.forEach(function(dataset) {
dataset.data.pop();
dataset.backgroundColor.pop();
});

View File

@@ -0,0 +1,116 @@
<!doctype html>
<html>
<head>
<title>Legend Point Style</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
<div class="chart-container">
<canvas id="chart-legend-normal"></canvas>
</div>
<div class="chart-container">
<canvas id="chart-legend-pointstyle"></canvas>
</div>
</div>
<script>
var color = Chart.helpers.color;
function createConfig(colorName) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
backgroundColor: color(window.chartColors[colorName]).alpha(0.5).rgbString(),
borderColor: window.chartColors[colorName],
borderWidth: 1,
pointStyle: 'rectRot',
pointRadius: 5,
pointBorderColor: 'rgb(0, 0, 0)'
}]
},
options: {
responsive: true,
legend: {
labels: {
usePointStyle: false
}
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
title: {
display: true,
text: 'Normal Legend'
}
}
};
}
function createPointStyleConfig(colorName) {
var config = createConfig(colorName);
config.options.legend.labels.usePointStyle = true;
config.options.title.text = 'Point Style Legend';
return config;
}
window.onload = function() {
[{
id: 'chart-legend-normal',
config: createConfig('red')
}, {
id: 'chart-legend-pointstyle',
config: createPointStyleConfig('blue')
}].forEach(function(details) {
var ctx = document.getElementById(details.id).getContext('2d');
new Chart(ctx, details.config)
})
};
</script>
</body>
</html>

View File

@@ -0,0 +1,121 @@
<!doctype html>
<html>
<head>
<title>Legend Positions</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
<div class="chart-container">
<canvas id="chart-legend-top"></canvas>
</div>
<div class="chart-container">
<canvas id="chart-legend-right"></canvas>
</div>
<div class="chart-container">
<canvas id="chart-legend-bottom"></canvas>
</div>
<div class="chart-container">
<canvas id="chart-legend-left"></canvas>
</div>
</div>
<script>
var color = Chart.helpers.color;
function createConfig(legendPosition, colorName) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
backgroundColor: color(window.chartColors[colorName]).alpha(0.5).rgbString(),
borderColor: window.chartColors[colorName],
borderWidth: 1
}]
},
options: {
responsive: true,
legend: {
position: legendPosition,
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
title: {
display: true,
text: 'Legend Position: ' + legendPosition
}
}
};
}
window.onload = function() {
[{
id: 'chart-legend-top',
legendPosition: 'top',
color: 'red'
}, {
id: 'chart-legend-right',
legendPosition: 'right',
color: 'blue'
}, {
id: 'chart-legend-bottom',
legendPosition: 'bottom',
color: 'green'
}, {
id: 'chart-legend-left',
legendPosition: 'left',
color: 'yellow'
}].forEach(function(details) {
var ctx = document.getElementById(details.id).getContext('2d');
var config = createConfig(details.legendPosition, details.color);
new Chart(ctx, config)
})
};
</script>
</body>
</html>

View File

@@ -1,141 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line 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{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
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-key {
display: inline-block;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder1" style="width:75%;">
<canvas id="chart1"/>
</div>
<script>
window.count = 0;
Chart.defaults.global.pointHitDetectionRadius = 1;
var customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
if (!tooltipEl[0]) {
$('body').append('<div id="chartjs-tooltip"></div>');
tooltipEl = $('#chartjs-tooltip');
}
// Hide if no tooltip
if (!tooltip.opacity) {
tooltipEl.css({
opacity: 0
});
$('.chartjs-wrap canvas')
.each(function(index, el) {
$(el).css('cursor', 'default');
});
return;
}
$(this._chart.canvas).css('cursor', 'pointer');
// Set caret Position
tooltipEl.removeClass('above below no-transform');
if (tooltip.yAlign) {
tooltipEl.addClass(tooltip.yAlign);
} else {
tooltipEl.addClass('no-transform');
}
// Set Text
if (tooltip.body) {
var innerHtml = [
(tooltip.beforeTitle || []).join('\n'), (tooltip.title || []).join('\n'), (tooltip.afterTitle || []).join('\n'), (tooltip.beforeBody || []).join('\n'), (tooltip.body || []).join('\n'), (tooltip.afterBody || []).join('\n'), (tooltip.beforeFooter || [])
.join('\n'), (tooltip.footer || []).join('\n'), (tooltip.afterFooter || []).join('\n')
];
tooltipEl.html(innerHtml.join('\n'));
}
// Find Y Location on page
var top = 0;
if (tooltip.yAlign) {
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
}
var position = $(this._chart.canvas)[0].getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
width: tooltip.width ? (tooltip.width + 'px') : 'auto',
left: position.left + tooltip.x + 'px',
top: position.top + top + 'px',
fontFamily: tooltip._fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip._fontStyle,
padding: tooltip.yPadding + 'px ' + tooltip.xPadding + 'px',
});
};
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var chartEl = document.getElementById("chart1");
window.myLine = new Chart(chartEl, {
type: 'line',
data: lineChartData,
options: {
title:{
display:true,
text:'Chart.js Line Chart - Custom Tooltips'
},
tooltips: {
enabled: false,
custom: customTooltips
}
}
});
};
</script>
</body>
</html>

View File

@@ -1,172 +0,0 @@
<!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="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.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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Third dataset - No bezier",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
lineTension: 0,
fill: false,
}, {
label: "My Fourth dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}]
},
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 - Legend'
}
}
};
$.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();
});
$('#addDataset').click(function() {
var background = randomColor(0.5);
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: background,
backgroundColor: background,
pointBorderColor: background,
pointBackgroundColor: background,
pointBorderWidth: 1,
fill: false,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,155 +0,0 @@
<!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>
<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.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));
};
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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart - Logarithmic'
},
scales: {
xAxes: [{
display: true,
gridLines: {
color: ['black', 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
},
scaleLabel: {
display: true,
labelString: 'x axis'
}
}],
yAxes: [{
display: true,
type: 'logarithmic',
scaleLabel: {
display: true,
labelString: 'y axis'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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);
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push(randomScalingFactor());
}
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,218 +0,0 @@
<!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:90%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="changeDataObject">Change Data Object</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.round(Math.random() * 100);
//return 0;
};
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: [["June","2015"], "July", "August", "September", "October", "November", "December", ["January","2016"],"February", "March", "April", "May"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
hidden: true,
label: 'hidden dataset',
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'label',
callbacks: {
// beforeTitle: function() {
// return '...beforeTitle';
// },
// afterTitle: function() {
// return '...afterTitle';
// },
// beforeBody: function() {
// return '...beforeBody';
// },
// afterBody: function() {
// return '...afterBody';
// },
// beforeFooter: function() {
// return '...beforeFooter';
// },
// footer: function() {
// return 'Footer';
// },
// afterFooter: function() {
// return '...afterFooter';
// },
}
},
hover: {
mode: 'dataset'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 250,
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#changeDataObject').click(function() {
config.data = {
labels: ["July", "August", "September", "October", "November", "December"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}, {
label: "My Second dataset",
fill: false,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
// Update the chart
window.myLine.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,163 +0,0 @@
<!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="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.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 || '1') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Third dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Third dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - Stacked Area"
},
tooltips: {
mode: 'label',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
var color = randomColor(1);
dataset.borderColor = color;
dataset.backgroundColor = color;
dataset.pointBorderColor = color;
dataset.pointBackgroundColor = color;
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();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,224 +0,0 @@
<!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="changeDataObject">Change Data Object</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 : 1) * Math.round(Math.random() * 100);
//return 0;
};
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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
steppedLine: true,
borderDash: [5, 5],
}, {
hidden: true,
label: 'hidden dataset',
steppedLine: true,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
steppedLine: true,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'label',
callbacks: {
// beforeTitle: function() {
// return '...beforeTitle';
// },
// afterTitle: function() {
// return '...afterTitle';
// },
// beforeBody: function() {
// return '...beforeBody';
// },
// afterBody: function() {
// return '...afterBody';
// },
// beforeFooter: function() {
// return '...beforeFooter';
// },
// footer: function() {
// return 'Footer';
// },
// afterFooter: function() {
// return '...afterFooter';
// },
}
},
hover: {
mode: 'dataset'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 250,
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#changeDataObject').click(function() {
config.data = {
labels: ["July", "August", "September", "October", "November", "December"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
steppedLine: true,
}, {
label: "My Second dataset",
fill: false,
steppedLine: true,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
// Update the chart
window.myLine.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
steppedLine: true,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,151 +0,0 @@
<!doctype html>
<html>
<head>
<title>Chart with xAxis Filtering</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="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.round(Math.random() * 50 * (Math.random() > 0.5 ? 1 : 1)) + 50;
};
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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - X-Axis Filter"
},
scales: {
xAxes: [{
display: true,
ticks: {
userCallback: function(dataLabel, index) {
return index % 2 === 0 ? dataLabel : '';
}
}
}],
yAxes: [{
display: true,
beginAtZero: false
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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);
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push(randomScalingFactor());
}
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -1,218 +0,0 @@
<!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="changeDataObject">Change Data Object</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.round(Math.random() * 100);
//return 0;
};
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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
hidden: true,
label: 'hidden dataset',
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'label',
callbacks: {
// beforeTitle: function() {
// return '...beforeTitle';
// },
// afterTitle: function() {
// return '...afterTitle';
// },
// beforeBody: function() {
// return '...beforeBody';
// },
// afterBody: function() {
// return '...afterBody';
// },
// beforeFooter: function() {
// return '...beforeFooter';
// },
// footer: function() {
// return 'Footer';
// },
// afterFooter: function() {
// return '...afterFooter';
// },
}
},
hover: {
mode: 'dataset'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 250,
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#changeDataObject').click(function() {
config.data = {
labels: ["July", "August", "September", "October", "November", "December"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}, {
label: "My Second dataset",
fill: false,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
// Update the chart
window.myLine.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,130 @@
<!doctype html>
<html>
<head>
<title>Different Point Sizes</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
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()
],
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
fill: false,
borderDash: [5, 5],
pointRadius: 15,
pointHoverRadius: 10,
}, {
label: "dataset - individual point sizes",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
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()
],
backgroundColor: window.chartColors.green,
borderColor: window.chartColors.green,
fill: false,
pointHoverRadius: 30,
}, {
label: "dataset - large pointHitRadius",
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
backgroundColor: window.chartColors.yellow,
borderColor: window.chartColors.yellow,
fill: false,
pointHitRadius: 20,
}]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
hover: {
mode: 'index'
},
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'
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<head>
<title>Line Chart - Cubic interpolation mode</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
@@ -25,13 +25,6 @@
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
//return 0;
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var datapoints = [0, 20, 20, 60, 60, 120, NaN, 180, 120, 125, 105, 110, 170];
@@ -42,20 +35,20 @@
datasets: [{
label: "Cubic interpolation (monotone)",
data: datapoints,
borderColor: 'rgba(255, 0, 0, 0.7)',
borderColor: window.chartColors.red,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
cubicInterpolationMode: 'monotone'
}, {
label: "Cubic interpolation (default)",
data: datapoints,
borderColor: 'rgba(0, 0, 255, 0.3)',
borderColor: window.chartColors.blue,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
}, {
label: "Linear interpolation",
data: datapoints,
borderColor: 'rgba(0, 0, 0, 0.10)',
borderColor: window.chartColors.green,
backgroundColor: 'rgba(0, 0, 0, 0)',
fill: false,
lineTension: 0
@@ -68,10 +61,7 @@
text:'Chart.js Line Chart - Cubic interpolation mode'
},
tooltips: {
mode: 'label'
},
hover: {
mode: 'dataset'
mode: 'index'
},
scales: {
xAxes: [{
@@ -100,7 +90,7 @@
window.myLine = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
document.getElementById('randomizeData').addEventListener('click', function() {
for (var i = 0, len = datapoints.length; i < len; ++i) {
datapoints[i] = Math.random() < 0.05 ? NaN : randomScalingFactor();
}

View File

@@ -3,8 +3,8 @@
<head>
<title>Line Chart Multiple Axes</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -20,53 +20,54 @@
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
yAxisID: "y-axis-1",
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
yAxisID: "y-axis-2"
}]
};
$.each(lineChartData.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = Chart.Line(ctx, {
data: lineChartData,
options: {
responsive: true,
hoverMode: 'label',
hoverMode: 'index',
stacked: false,
title:{
display:true,
display: true,
text:'Chart.js Line Chart - Multi Axis'
},
scales: {
xAxes: [{
display: true,
gridLines: {
offsetGridLines: false
}
}],
yAxes: [{
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
@@ -88,10 +89,12 @@
});
};
$('#randomizeData').click(function() {
lineChartData.datasets[0].data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
lineChartData.datasets[1].data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
document.getElementById('randomizeData').addEventListener('click', function() {
lineChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});

View File

@@ -0,0 +1,95 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
fill: false,
// Skip a point in the middle
data: [
randomScalingFactor(),
randomScalingFactor(),
NaN,
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
fill: false,
// Skip first and last points
data: [
NaN,
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
NaN
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart - Skip Points'
},
tooltips: {
mode: 'index',
},
hover: {
mode: 'index'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,183 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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="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 config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Third dataset",
borderColor: window.chartColors.green,
backgroundColor: window.chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Third dataset",
borderColor: window.chartColors.yellow,
backgroundColor: window.chartColors.yellow,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - Stacked Area"
},
tooltips: {
mode: 'index',
},
hover: {
mode: 'index'
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: newColor,
backgroundColor: newColor,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
config.data.datasets.forEach(function(dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,93 @@
<!doctype html>
<html>
<head>
<title>Stepped Line Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
steppedLine: true,
}, {
label: "My Second dataset",
steppedLine: true,
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,111 @@
<!doctype html>
<html>
<head>
<title>Line Styles</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "Unfilled",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "Dashed",
fill: false,
backgroundColor: window.chartColors.green,
borderColor: window.chartColors.green,
borderDash: [5, 5],
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "Filled",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: true,
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -3,10 +3,10 @@
<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>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
@@ -27,47 +27,53 @@
<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);
//return 0;
};
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: "My First dataset",
// Skip a point in the middle
data: [randomScalingFactor(), randomScalingFactor(), NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: true,
borderDash: [5, 5],
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
}, {
label: "My Second dataset",
// Skip first and last points
data: [NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN],
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart - Skip Points'
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'label',
mode: 'index',
intersect: false,
},
hover: {
mode: 'label'
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
@@ -82,27 +88,19 @@
scaleLabel: {
display: true,
labelString: 'Value'
},
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
@@ -112,15 +110,16 @@
window.myLine.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
backgroundColor: newColor,
borderColor: newColor,
data: [],
fill: false
};
for (var index = 0; index < config.data.labels.length; ++index) {
@@ -131,12 +130,12 @@
window.myLine.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('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) {
config.data.datasets.forEach(function(dataset) {
dataset.data.push(randomScalingFactor());
});
@@ -144,12 +143,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {

View File

@@ -0,0 +1,95 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
</div>
<script>
function createConfig(pointStyle) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [10, 23, 5, 99, 67, 43, 0],
fill: false,
pointRadius: 10,
pointHoverRadius: 15,
showLine: false // no line shown
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Point Style: ' + pointStyle
},
legend: {
display: false
},
elements: {
point: {
pointStyle: pointStyle
}
}
}
};
}
window.onload = function() {
var container = document.querySelector('.container');
[
'circle',
'triangle',
'rect',
'rectRot',
'cross',
'crossRot',
'star',
'line',
'dash'
].forEach(function(pointStyle) {
var div = document.createElement('div');
div.classList.add('chart-container');
var canvas = document.createElement('canvas');
div.appendChild(canvas);
container.appendChild(div);
var ctx = canvas.getContext('2d');
var config = createConfig(pointStyle);
new Chart(ctx, config);
});
};
</script>
</body>
</html>

View File

@@ -1,156 +0,0 @@
<!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;
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-key {
display: inline-block;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder" style="width: 50px;">
<canvas id="chart-area1" width="50" height="50" />
</div>
<div id="canvas-holder" style="width: 300px;">
<canvas id="chart-area2" width="300" height="300" />
</div>
<div id="chartjs-tooltip"></div>
<script>
Chart.defaults.global.tooltips.custom = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
if (!tooltipEl[0]) {
$('body').append('<div id="chartjs-tooltip"></div>');
tooltipEl = $('#chartjs-tooltip');
}
// Hide if no tooltip
if (!tooltip.opacity) {
tooltipEl.css({
opacity: 0
});
$('.chartjs-wrap canvas')
.each(function(index, el) {
$(el).css('cursor', 'default');
});
return;
}
$(this._chart.canvas).css('cursor', 'pointer');
// Set caret Position
tooltipEl.removeClass('above below no-transform');
if (tooltip.yAlign) {
tooltipEl.addClass(tooltip.yAlign);
} else {
tooltipEl.addClass('no-transform');
}
// Set Text
if (tooltip.body) {
var innerHtml = [
(tooltip.beforeTitle || []).join('\n'), (tooltip.title || []).join('\n'), (tooltip.afterTitle || []).join('\n'), (tooltip.beforeBody || []).join('\n'), (tooltip.body || []).join('\n'), (tooltip.afterBody || []).join('\n'), (tooltip.beforeFooter || [])
.join('\n'), (tooltip.footer || []).join('\n'), (tooltip.afterFooter || []).join('\n')
];
tooltipEl.html(innerHtml.join('\n'));
}
// Find Y Location on page
var top = 0;
if (tooltip.yAlign) {
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
}
var position = $(this._chart.canvas)[0].getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
width: tooltip.width ? (tooltip.width + 'px') : 'auto',
left: position.left + tooltip.x + 'px',
top: position.top + top + 'px',
fontFamily: tooltip._fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip._fontStyle,
padding: tooltip.yPadding + 'px ' + tooltip.xPadding + 'px',
});
};
var config = {
type: 'pie',
data: {
datasets: [{
data: [300, 50, 100, 40, 10],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
legend: {
display: false
},
tooltips: {
enabled: false,
}
}
};
window.onload = function() {
var ctx1 = document.getElementById("chart-area1").getContext("2d");
window.myPie = new Chart(ctx1, config);
var ctx2 = document.getElementById("chart-area2").getContext("2d");
window.myPie = new Chart(ctx2, config);
};
</script>
</body>
</html>

View File

@@ -4,12 +4,12 @@
<head>
<title>Pie 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>
<script src="utils.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:50%">
<canvas id="chart-area" width="300" height="300" />
<div id="canvas-holder" style="width:40%">
<canvas id="chart-area" />
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
@@ -18,12 +18,6 @@
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'pie',
@@ -37,49 +31,20 @@
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
}, {
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
}, {
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
window.chartColors.red,
window.chartColors.orange,
window.chartColors.yellow,
window.chartColors.green,
window.chartColors.blue,
],
label: 'Dataset 1'
}],
labels: [
"Red",
"Green",
"Orange",
"Yellow",
"Grey",
"Dark Grey"
"Green",
"Blue"
]
},
options: {
@@ -92,27 +57,37 @@
window.myPie = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, piece) {
$.each(piece.data, function(j, value) {
config.data.datasets[i].data[j] = randomScalingFactor();
config.data.datasets[i].backgroundColor[j] = randomColor(0.7);
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myPie.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var newDataset = {
backgroundColor: [randomColor(0.7), randomColor(0.7), randomColor(0.7), randomColor(0.7), randomColor(0.7)],
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
backgroundColor: [],
data: [],
label: 'New dataset ' + config.data.datasets.length,
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
var colorName = colorNames[index % colorNames.length];;
var newColor = window.chartColors[colorName];
newDataset.backgroundColor.push(newColor);
}
config.data.datasets.push(newDataset);
window.myPie.update();
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myPie.update();
});

View File

@@ -4,7 +4,7 @@
<head>
<title>Polar Area 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>
<script src="utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -15,7 +15,7 @@
</head>
<body>
<div id="canvas-holder" style="width:75%">
<div id="canvas-holder" style="width:50%">
<canvas id="chart-area"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
@@ -25,13 +25,9 @@
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var chartColors = window.chartColors;
var color = Chart.helpers.color;
var config = {
data: {
datasets: [{
@@ -43,26 +39,26 @@
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
color(chartColors.red).alpha(0.5).rgbString(),
color(chartColors.orange).alpha(0.5).rgbString(),
color(chartColors.yellow).alpha(0.5).rgbString(),
color(chartColors.green).alpha(0.5).rgbString(),
color(chartColors.blue).alpha(0.5).rgbString(),
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Orange",
"Yellow",
"Grey",
"Dark Grey"
"Green",
"Blue"
]
},
options: {
responsive: true,
legend: {
position: 'top',
position: 'right',
},
title: {
display: true,
@@ -86,37 +82,33 @@
window.myPolarArea = Chart.PolarArea(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, piece) {
$.each(piece.data, function(j, value) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(piece, i) {
piece.data.forEach(function(value, j) {
config.data.datasets[i].data[j] = randomScalingFactor();
config.data.datasets[i].backgroundColor[j] = randomColor();
});
});
window.myPolarArea.update();
});
$('#addData').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
$.each(config.data.datasets, function(i, dataset) {
dataset.backgroundColor.push(randomColor());
config.data.labels.push('data #' + config.data.labels.length);
config.data.datasets.forEach(function(dataset) {
var colorName = colorNames[config.data.labels.length % colorNames.length];
dataset.backgroundColor.push(window.chartColors[colorName]);
dataset.data.push(randomScalingFactor());
});
window.myPolarArea.update();
}
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
config.data.datasets.forEach(function(dataset) {
dataset.backgroundColor.pop();
dataset.data.pop();
});
window.myPolarArea.update();
});
</script>

View File

@@ -1,143 +0,0 @@
<!doctype html>
<html>
<head>
<title>Radar 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>
<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 randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'radar',
data: {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "Skip first dataset",
borderColor: 'rgb(255, 0, 0)',
backgroundColor: "rgba(255,255,0,0.5)",
pointBackgroundColor: "rgba(220,220,220,1)",
data: [NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "Skip mid dataset",
borderColor: 'rgb(255, 0, 255)',
backgroundColor: "rgba(0, 255, 0, 0.5)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
data: [randomScalingFactor(), randomScalingFactor(), NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
},{
label: "Skip last dataset",
borderColor: 'rgb(0, 255, 255)',
backgroundColor: "rgba(0, 0, 255, 0.5)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN]
}]
},
options: {
title:{
display:true,
text:"Chart.js Radar Chart - Skip Points"
},
elements: {
line: {
tension: 0.0,
}
},
scale: {
beginAtZero: true,
reverse: false
}
}
};
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myRadar.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
$.each(config.data.datasets, function (i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myRadar.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.data.pop();
});
window.myRadar.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,109 @@
<!doctype html>
<html>
<head>
<title>Radar Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:40%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var color = Chart.helpers.color;
var config = {
type: 'radar',
data: {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "Skip first dataset",
borderColor: window.chartColors.red,
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
pointBackgroundColor: window.chartColors.red,
data: [
NaN,
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "Skip mid dataset",
borderColor: window.chartColors.blue,
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
pointBackgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
NaN,
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
},{
label: "Skip last dataset",
borderColor: window.chartColors.green,
backgroundColor: color(window.chartColors.green).alpha(0.2).rgbString(),
pointBackgroundColor: window.chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
NaN
]
}]
},
options: {
title:{
display:true,
text:"Chart.js Radar Chart - Skip Points"
},
elements: {
line: {
tension: 0.0,
}
},
scale: {
beginAtZero: true,
}
}
};
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.update();
});
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<head>
<title>Radar 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>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -15,7 +15,7 @@
</head>
<body>
<div style="width:75%">
<div style="width:40%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
@@ -27,32 +27,40 @@
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var color = Chart.helpers.color;
var config = {
type: 'radar',
data: {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(220,220,220,0.2)",
pointBackgroundColor: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Hidden dataset',
hidden: true,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
borderColor: window.chartColors.red,
pointBackgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset",
backgroundColor: "rgba(151,187,205,0.2)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
borderColor: window.chartColors.blue,
pointBackgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
},]
},
options: {
@@ -64,10 +72,6 @@
text: 'Chart.js Radar Chart'
},
scale: {
reverse: false,
gridLines: {
color: ['black', 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
},
ticks: {
beginAtZero: true
}
@@ -79,25 +83,26 @@
window.myRadar = new Chart(document.getElementById("canvas"), config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];;
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
borderColor: newColor,
backgroundColor: color(newColor).alpha(0.2).rgbString(),
pointBorderColor: newColor,
data: [],
};
@@ -109,11 +114,11 @@
window.myRadar.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
$.each(config.data.datasets, function (i, dataset) {
config.data.datasets.forEach(function (dataset) {
dataset.data.push(randomScalingFactor());
});
@@ -121,15 +126,15 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
config.data.datasets.forEach(function(dataset) {
dataset.data.pop();
});

View File

@@ -0,0 +1,124 @@
<!doctype html>
<html>
<head>
<title>Suggested Min/Max Settings</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container"></div>
<script>
function createConfig(gridlines, title) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [10, 30, 39, 20, 25, 34, 0],
fill: false,
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [18, 33, 22, 19, 11, 39, 30],
}]
},
options: {
responsive: true,
title:{
display: true,
text: title
},
scales: {
xAxes: [{
gridLines: gridlines
}],
yAxes: [{
gridLines: gridlines,
ticks: {
min: 0,
max: 100,
stepSize: 10
}
}]
}
}
};
}
window.onload = function() {
var container = document.querySelector('.container');
[{
title: 'Display: true',
gridLines: {
display: true
}
}, {
title: 'Display: false',
gridLines: {
display: false
}
}, {
title: 'Display: false, no border',
gridLines: {
display: false,
drawBorder: false
}
}, {
title: 'DrawOnChartArea: false',
gridLines: {
display: true,
drawBorder: true,
drawOnChartArea: false,
}
}, {
title: 'DrawTicks: false',
gridLines: {
display: true,
drawBorder: true,
drawOnChartArea: true,
drawTicks: false,
}
}].forEach(function(details) {
var div = document.createElement('div');
div.classList.add('chart-container');
var canvas = document.createElement('canvas');
div.appendChild(canvas);
container.appendChild(div);
var ctx = canvas.getContext('2d');
var config = createConfig(details.gridLines, details.title);
new Chart(ctx, config);
});
};
</script>
</body>
</html>

View File

@@ -0,0 +1,93 @@
<!doctype html>
<html>
<head>
<title>Chart with xAxis Filtering</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 50 * (Math.random() > 0.5 ? 1 : 1)) + 50;
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fill: false,
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset",
fill: false,
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - X-Axis Filter"
},
scales: {
xAxes: [{
display: true,
ticks: {
callback: function(dataLabel, index) {
// Hide the label of every 2nd dataset. return null to hide the grid line too
return index % 2 === 0 ? dataLabel : '';
}
}
}],
yAxes: [{
display: true,
beginAtZero: false
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,69 @@
<!doctype html>
<html>
<head>
<title>Suggested Min/Max Settings</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [10, 30, 39, 20, 25, 34, -10],
fill: false,
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [18, 33, 22, 19, 11, 39, 30],
}]
},
options: {
responsive: true,
title:{
display: true,
text: 'Grid Line Settings'
},
scales: {
yAxes: [{
gridLines: {
drawBorder: false,
color: ['pink', 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple']
},
ticks: {
min: 0,
max: 100,
stepSize: 10
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<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>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
@@ -20,18 +20,6 @@
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
//return 0;
};
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: {
@@ -41,14 +29,15 @@
label: "My First dataset",
data: ['', 'Request Added', 'Request Added', 'Request Added', 'Request Viewed', 'Request Viewed', 'Request Viewed'],
fill: false,
borderDash: [5, 5],
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
text:'Chart with Non Numeric Y Axis'
},
scales: {
xAxes: [{
@@ -74,14 +63,6 @@
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);

View File

@@ -0,0 +1,64 @@
<!doctype html>
<html>
<head>
<title>Min/Max Settings</title>
<script src="../../../dist/Chart.bundle.js"></script>
<script src="../../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [10, 30, 50, 20, 25, 44, -10],
fill: false,
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [100, 33, 22, 19, 11, 49, 30],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Min and Max Settings'
},
scales: {
yAxes: [{
ticks: {
min: 10,
max: 50
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,116 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../../dist/Chart.bundle.js"></script>
<script src="../../utils.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="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.round(Math.random() * 100);
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
ticks: {
min: 0,
max: 100,
// forces step size to be 5 units
stepSize: 5
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,67 @@
<!doctype html>
<html>
<head>
<title>Suggested Min/Max Settings</title>
<script src="../../../dist/Chart.bundle.js"></script>
<script src="../../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [10, 30, 39, 20, 25, 34, -10],
fill: false,
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [18, 33, 22, 19, 11, 39, 30],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Min and Max Settings'
},
scales: {
yAxes: [{
ticks: {
// the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)
suggestedMin: 10,
// the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
suggestedMax: 50
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,97 @@
<!doctype html>
<html>
<head>
<title>Logarithmic Line Chart</title>
<script src="../../../dist/Chart.bundle.js"></script>
<script src="../../utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return Math.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart - Logarithmic'
},
scales: {
xAxes: [{
display: true,
}],
yAxes: [{
display: true,
type: 'logarithmic',
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -3,8 +3,8 @@
<head>
<title>Scatter 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>
<script src="../../../dist/Chart.bundle.js"></script>
<script src="../../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -16,20 +16,14 @@
<body>
<div style="width:75%">
<div>
<canvas id="canvas"></canvas>
</div>
<canvas id="canvas"></canvas>
</div>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};
var color = Chart.helpers.color;
var scatterChartData = {
datasets: [{
borderColor: window.chartColors.red,
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
label: "V(node2)",
data: [{
x: 1,
@@ -128,14 +122,6 @@
}]
};
$.each(scatterChartData.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {

View File

@@ -0,0 +1,86 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:90%;">
<canvas id="canvas"></canvas>
</div>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var config = {
type: 'line',
data: {
labels: [["June","2015"], "July", "August", "September", "October", "November", "December", ["January","2016"],"February", "March", "April", "May"],
datasets: [{
label: "My First dataset",
fill: false,
backgroundColor: window.chartColors.red,
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset",
fill: false,
backgroundColor: window.chartColors.blue,
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart with Multiline Labels'
},
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -4,8 +4,8 @@
<head>
<title>Line Chart - Combo Time Scale</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../../../dist/Chart.js"></script>
<script src="../../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -29,52 +29,70 @@
<script>
var timeFormat = 'MM/DD/YYYY HH:mm';
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
var color = Chart.helpers.color;
var config = {
type: 'bar',
data: {
labels: [newDateString(0), newDateString(1), newDateString(2), newDateString(3), newDateString(4), newDateString(5), newDateString(6)],
labels: [
newDateString(0),
newDateString(1),
newDateString(2),
newDateString(3),
newDateString(4),
newDateString(5),
newDateString(6)
],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
type: 'line',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
backgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),
borderColor: window.chartColors.green,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, ]
},
options: {
showLines: true,
responsive: true,
title:{
display:true,
title: {
text:"Chart.js Combo Time Scale"
},
scales: {
@@ -90,22 +108,14 @@
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
@@ -114,14 +124,14 @@
window.myLine.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName];
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
borderColor: newColor,
backgroundColor: color(newColor).alpha(0.5).rgbString(),
data: [],
};
@@ -133,7 +143,7 @@
window.myLine.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(newDateString(config.data.labels.length));
@@ -145,12 +155,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {

View File

@@ -4,8 +4,8 @@
<head>
<title>Time Scale Point Data</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../../../dist/Chart.js"></script>
<script src="../../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -25,18 +25,6 @@
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDate(days) {
return moment().add(days, 'd').toDate();
}
@@ -45,11 +33,15 @@
return moment().add(days, 'd').format();
}
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
datasets: [{
label: "Dataset with string point data",
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
fill: false,
data: [{
x: newDateString(0),
y: randomScalingFactor()
@@ -63,9 +55,11 @@
x: newDateString(5),
y: randomScalingFactor()
}],
fill: false
}, {
label: "Dataset with date object point data",
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
fill: false,
data: [{
x: newDate(0),
y: randomScalingFactor()
@@ -78,8 +72,7 @@
}, {
x: newDate(5),
y: randomScalingFactor()
}],
fill: false
}]
}]
},
options: {
@@ -108,23 +101,15 @@
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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) {
$.each(dataset.data, function(j, dataObj) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj) {
dataObj.y = randomScalingFactor();
});
});
@@ -132,7 +117,7 @@
window.myLine.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
var lastTime = myLine.scales['x-axis-0'].labelMoments[0].length ? myLine.scales['x-axis-0'].labelMoments[0][myLine.scales['x-axis-0'].labelMoments[0].length - 1] : moment();
var newTime = lastTime
@@ -151,7 +136,7 @@
}
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});

View File

@@ -4,8 +4,8 @@
<head>
<title>Line Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../../../dist/Chart.js"></script>
<script src="../../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
@@ -28,19 +28,7 @@
<button id="removeData">Remove Data</button>
<script>
var timeFormat = 'MM/DD/YYYY HH:mm';
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDate(days) {
return moment().add(days, 'd').toDate();
}
@@ -53,20 +41,52 @@
return moment().add(days, 'd').unix();
}
var color = Chart.helpers.color;
var config = {
type: 'line',
data: {
labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
labels: [ // Date Objects
newDate(0),
newDate(1),
newDate(2),
newDate(3),
newDate(4),
newDate(5),
newDate(6)
],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
backgroundColor: color(window.chartColors.red).alpha(0.5).rgbString(),
borderColor: window.chartColors.red,
fill: false,
borderDash: [5, 5],
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
backgroundColor: color(window.chartColors.blue).alpha(0.5).rgbString(),
borderColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "Dataset with point data",
backgroundColor: color(window.chartColors.green).alpha(0.5).rgbString(),
borderColor: window.chartColors.green,
fill: false,
data: [{
x: newDateString(0),
y: randomScalingFactor()
@@ -80,14 +100,11 @@
x: newDateString(15),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Time Scale"
text: "Chart.js Time Scale"
},
scales: {
xAxes: [{
@@ -112,23 +129,15 @@
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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) {
$.each(dataset.data, function(j, dataObj) {
document.getElementById('randomizeData').addEventListener('click', function() {
config.data.datasets.forEach(function(dataset) {
dataset.data.forEach(function(dataObj, j) {
if (typeof dataObj === 'object') {
dataObj.y = randomScalingFactor();
} else {
@@ -140,14 +149,14 @@
window.myLine.update();
});
$('#addDataset').click(function() {
var colorNames = Object.keys(window.chartColors);
document.getElementById('addDataset').addEventListener('click', function() {
var colorName = colorNames[config.data.datasets.length % colorNames.length];
var newColor = window.chartColors[colorName]
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
borderColor: newColor,
backgroundColor: color(newColor).alpha(0.5).rgbString(),
data: [],
};
@@ -159,7 +168,7 @@
window.myLine.update();
});
$('#addData').click(function() {
document.getElementById('addData').addEventListener('click', function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(newDate(config.data.labels.length));
@@ -178,12 +187,12 @@
}
});
$('#removeDataset').click(function() {
document.getElementById('removeDataset').addEventListener('click', function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
document.getElementById('removeData').addEventListener('click', function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {

View File

@@ -1,186 +0,0 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart Multi Axis</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%">
<div>
<canvas id="canvas"></canvas>
</div>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};
var scatterChartData = {
datasets: [{
label: "My First dataset",
xAxisID: "x-axis-1",
yAxisID: "y-axis-1",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}, {
label: "My Second dataset",
xAxisID: "x-axis-1",
yAxisID: "y-axis-2",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}]
};
$.each(scatterChartData.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
responsive: true,
hoverMode: 'single',
title: {
display: true,
text: 'Chart.js Scatter Chart - Multi Axis'
},
scales: {
xAxes: [{
position: "bottom",
gridLines: {
zeroLineColor: "rgba(0,0,0,1)"
}
}],
yAxes: [{
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "left",
id: "y-axis-1",
}, {
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "right",
reverse: true,
id: "y-axis-2",
// grid line settings
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
}],
}
}
});
};
$('#randomizeData').click(function() {
scatterChartData.datasets[0].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}];
scatterChartData.datasets[1].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}];
window.myScatter.update();
});
</script>
</body>
</html>

View File

@@ -1,177 +0,0 @@
<!doctype html>
<html>
<head>
<title>Scatter 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%">
<div>
<canvas id="canvas"></canvas>
</div>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};
var scatterChartData = {
datasets: [{
label: "My First dataset",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}, {
label: "My Second dataset",
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}]
};
$.each(scatterChartData.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart'
},
scales: {
xAxes: [{
position: 'top',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'x axis'
}
}],
yAxes: [{
position: 'right',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'y axis'
}
}]
}
}
});
};
$('#randomizeData').click(function() {
scatterChartData.datasets[0].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}];
scatterChartData.datasets[1].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
window.myScatter.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,139 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart Multi Axis</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var color = Chart.helpers.color;
var scatterChartData = {
datasets: [{
label: "My First dataset",
xAxisID: "x-axis-1",
yAxisID: "y-axis-1",
borderColor: window.chartColors.red,
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}, {
label: "My Second dataset",
xAxisID: "x-axis-1",
yAxisID: "y-axis-2",
borderColor: window.chartColors.blue,
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
responsive: true,
hoverMode: 'nearest',
intersect: true,
title: {
display: true,
text: 'Chart.js Scatter Chart - Multi Axis'
},
scales: {
xAxes: [{
position: "bottom",
gridLines: {
zeroLineColor: "rgba(0,0,0,1)"
}
}],
yAxes: [{
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "left",
id: "y-axis-1",
}, {
type: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
display: true,
position: "right",
reverse: true,
id: "y-axis-2",
// grid line settings
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
}],
}
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
scatterChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return {
x: randomScalingFactor(),
y: randomScalingFactor()
};
});
});
window.myScatter.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<button id="randomizeData">Randomize Data</button>
<script>
var color = Chart.helpers.color;
var scatterChartData = {
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart'
},
}
});
};
document.getElementById('randomizeData').addEventListener('click', function() {
scatterChartData.datasets.forEach(function(dataset) {
dataset.data = dataset.data.map(function() {
return {
x: randomScalingFactor(),
y: randomScalingFactor()
};
});
});
window.myScatter.update();
});
</script>
</body>
</html>

View File

@@ -1,189 +0,0 @@
<!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="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.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: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - Tooltip Hooks"
},
tooltips: {
mode: 'label',
callbacks: {
beforeTitle: function() {
return '...beforeTitle';
},
afterTitle: function() {
return '...afterTitle';
},
beforeBody: function() {
return '...beforeBody';
},
afterBody: function() {
return '...afterBody';
},
beforeLabel: function() {
return '...beforeLabel';
},
afterLabel: function() {
return '...afterLabel';
},
beforeFooter: function() {
return '...beforeFooter';
},
footer: function() {
return 'Footer';
},
afterFooter: function() {
return '...afterFooter';
},
}
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
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();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
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());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
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();
});
window.myLine.update();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,125 @@
<!doctype html>
<html>
<head>
<title>Custom Tooltips using Data Points</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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;
}
.chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
padding: 4px;
}
.chartjs-tooltip-key {
display: inline-block;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder1" style="width:75%;">
<canvas id="chart1"></canvas>
</div>
<div class="chartjs-tooltip" id="tooltip-0"></div>
<div class="chartjs-tooltip" id="tooltip-1"></div>
<script>
var customTooltips = function (tooltip) {
$(this._chart.canvas).css("cursor", "pointer");
$(".chartjs-tooltip").css({
opacity: 0,
});
if (!tooltip || !tooltip.opacity) {
return;
}
if (tooltip.dataPoints.length > 0) {
tooltip.dataPoints.forEach(function (dataPoint) {
var content = [dataPoint.xLabel, dataPoint.yLabel].join(": ");
var $tooltip = $("#tooltip-" + dataPoint.datasetIndex);
$tooltip.html(content);
$tooltip.css({
opacity: 1,
top: dataPoint.y + "px",
left: dataPoint.x + "px",
});
});
}
};
var color = Chart.helpers.color;
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
backgroundColor: color(window.chartColors.red).alpha(0.2).rgbString(),
borderColor: window.chartColors.red,
pointBackgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset",
backgroundColor: color(window.chartColors.blue).alpha(0.2).rgbString(),
borderColor: window.chartColors.blue,
pointBackgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
window.onload = function() {
var chartEl = document.getElementById("chart1");
var chart = new Chart(chartEl, {
type: "line",
data: lineChartData,
options: {
title:{
display: true,
text: "Chart.js - Custom Tooltips using Data Points"
},
tooltips: {
enabled: false,
mode: 'index',
intersect: false,
custom: customTooltips
}
}
});
};
</script>
</body>
</html>

View File

@@ -0,0 +1,125 @@
<!doctype html>
<html>
<head>
<title>Tooltip Interaction Modes</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
</div>
<script>
function createConfig(mode, intersect) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [10, 30, 46, 2, 8, 50, 0],
fill: false,
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [7, 49, 46, 13, 25, 30, 22],
fill: false,
}]
},
options: {
responsive: true,
title:{
display: true,
text: 'Mode: ' + mode + ', intersect = ' + intersect
},
tooltips: {
mode: mode,
intersect: intersect,
},
hover: {
mode: mode,
intersect: intersect
},
}
};
}
window.onload = function() {
var container = document.querySelector('.container');
[{
mode: 'index',
intersect: true,
}, {
mode: 'index',
intersect: false,
}, {
mode: 'dataset',
intersect: true,
}, {
mode: 'dataset',
intersect: false,
}, {
mode: 'point',
intersect: true,
}, {
mode: 'point',
intersect: false,
}, {
mode: 'nearest',
intersect: true,
}, {
mode: 'nearest',
intersect: false,
}, {
mode: 'x',
intersect: true
}, {
mode: 'x',
intersect: false
}, {
mode: 'y',
intersect: true
}, {
mode: 'y',
intersect: false
}].forEach(function(details) {
var div = document.createElement('div');
div.classList.add('chart-container');
var canvas = document.createElement('canvas');
div.appendChild(canvas);
container.appendChild(div);
var ctx = canvas.getContext('2d');
var config = createConfig(details.mode, details.intersect);
new Chart(ctx, config);
})
};
</script>
</body>
</html>

View File

@@ -0,0 +1,165 @@
<!doctype html>
<html>
<head>
<title>Line Chart with Custom Tooltips</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
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-key {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder1" style="width:75%;">
<canvas id="chart"/>
</div>
<script>
Chart.defaults.global.pointHitDetectionRadius = 1;
var customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = "<table></table>"
document.body.appendChild(tooltipEl);
}
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltip.yAlign) {
tooltipEl.classList.add(tooltip.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltip.body) {
var titleLines = tooltip.title || [];
var bodyLines = tooltip.body.map(getBody);
var innerHtml = '<thead>';
titleLines.forEach(function(title) {
innerHtml += '<tr><th>' + title + '</th></tr>';
});
innerHtml += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
var colors = tooltip.labelColors[i];
var style = 'background:' + colors.backgroundColor;
style += '; border-color:' + colors.borderColor;
style += '; border-width: 2px';
var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = position.left + tooltip.caretX + 'px';
tooltipEl.style.top = position.top + tooltip.caretY + 'px';
tooltipEl.style.fontFamily = tooltip._fontFamily;
tooltipEl.style.fontSize = tooltip.fontSize;
tooltipEl.style.fontStyle = tooltip._fontStyle;
tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
pointBackgroundColor: window.chartColors.red,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
pointBackgroundColor: window.chartColors.blue,
fill: false,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
]
}]
};
window.onload = function() {
var chartEl = document.getElementById("chart");
window.myLine = new Chart(chartEl, {
type: 'line',
data: lineChartData,
options: {
title:{
display:true,
text:'Chart.js Line Chart - Custom Tooltips'
},
tooltips: {
enabled: false,
mode: 'index',
position: 'nearest',
custom: customTooltips
}
}
});
};
</script>
</body>
</html>

View File

@@ -0,0 +1,146 @@
<!doctype html>
<html>
<head>
<title>Pie Chart with Custom Tooltips</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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;
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-key {
display: inline-block;
width: 10px;
height: 10px;
margin-right: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder" style="width: 300px;">
<canvas id="chart-area" width="300" height="300" />
</div>
<div id="chartjs-tooltip">
<table></table>
</div>
<script>
Chart.defaults.global.tooltips.custom = function(tooltip) {
// Tooltip Element
var tooltipEl = document.getElementById('chartjs-tooltip');
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set caret Position
tooltipEl.classList.remove('above', 'below', 'no-transform');
if (tooltip.yAlign) {
tooltipEl.classList.add(tooltip.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// Set Text
if (tooltip.body) {
var titleLines = tooltip.title || [];
var bodyLines = tooltip.body.map(getBody);
var innerHtml = '<thead>';
titleLines.forEach(function(title) {
innerHtml += '<tr><th>' + title + '</th></tr>';
});
innerHtml += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
var colors = tooltip.labelColors[i];
var style = 'background:' + colors.backgroundColor;
style += '; border-color:' + colors.borderColor;
style += '; border-width: 2px';
var span = '<span class="chartjs-tooltip-key" style="' + style + '"></span>';
innerHtml += '<tr><td>' + span + body + '</td></tr>';
});
innerHtml += '</tbody>';
var tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHtml;
}
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = position.left + tooltip.caretX + 'px';
tooltipEl.style.top = position.top + tooltip.caretY + 'px';
tooltipEl.style.fontFamily = tooltip._fontFamily;
tooltipEl.style.fontSize = tooltip.fontSize;
tooltipEl.style.fontStyle = tooltip._fontStyle;
tooltipEl.style.padding = tooltip.yPadding + 'px ' + tooltip.xPadding + 'px';
};
var config = {
type: 'pie',
data: {
datasets: [{
data: [300, 50, 100, 40, 10],
backgroundColor: [
window.chartColors.red,
window.chartColors.orange,
window.chartColors.yellow,
window.chartColors.green,
window.chartColors.blue,
],
}],
labels: [
"Red",
"Orange",
"Yellow",
"Green",
"Blue"
]
},
options: {
responsive: true,
legend: {
display: false
},
tooltips: {
enabled: false,
}
}
};
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPie = new Chart(ctx, config);
};
</script>
</body>
</html>

View File

@@ -0,0 +1,86 @@
<!doctype html>
<html>
<head>
<title>Tooltip Interaction Modes</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
.chart-container {
width: 500px;
margin-left: 40px;
margin-right: 40px;
margin-bottom: 40px;
}
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
</style>
</head>
<body>
<div class="container">
</div>
<script>
function createConfig(position) {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [10, 30, 46, 2, 8, 50, 0],
fill: false,
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [7, 49, 46, 13, 25, 30, 22],
fill: false,
}]
},
options: {
responsive: true,
title:{
display: true,
text: 'Tooltip Position: ' + position
},
tooltips: {
position: position,
mode: 'index',
intersect: false,
},
}
};
}
window.onload = function() {
var container = document.querySelector('.container');
['average', 'nearest'].forEach(function(position) {
var div = document.createElement('div');
div.classList.add('chart-container');
var canvas = document.createElement('canvas');
div.appendChild(canvas);
container.appendChild(div);
var ctx = canvas.getContext('2d');
var config = createConfig(position);
new Chart(ctx, config);
})
};
</script>
</body>
</html>

View File

@@ -0,0 +1,107 @@
<!doctype html>
<html>
<head>
<title>Tooltip Hooks</title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="../utils.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>
<script>
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: window.chartColors.red,
backgroundColor: window.chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
}, {
label: "My Second dataset",
borderColor: window.chartColors.blue,
backgroundColor: window.chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
fill: false,
}]
},
options: {
responsive: true,
title:{
display: true,
text: "Chart.js Line Chart - Custom Information in Tooltip"
},
tooltips: {
mode: 'index',
callbacks: {
// Use the footer callback to display the sum of the items showing in the tooltip
footer: function(tooltipItems, data) {
var sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
});
return 'Sum: ' + sum;
},
},
footerFontStyle: 'normal'
},
hover: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

13
samples/utils.js Normal file
View File

@@ -0,0 +1,13 @@
window.chartColors = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
green: 'rgb(75, 192, 192)',
blue: 'rgb(54, 162, 235)',
purple: 'rgb(153, 102, 255)',
grey: 'rgb(231,233,237)'
};
window.randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
}

View File

@@ -12,9 +12,11 @@ require('./core/core.datasetController')(Chart);
require('./core/core.layoutService')(Chart);
require('./core/core.scaleService')(Chart);
require('./core/core.plugin.js')(Chart);
require('./core/core.ticks.js')(Chart);
require('./core/core.scale')(Chart);
require('./core/core.title')(Chart);
require('./core/core.legend')(Chart);
require('./core/core.interaction')(Chart);
require('./core/core.tooltip')(Chart);
require('./elements/element.arc')(Chart);

View File

@@ -3,7 +3,6 @@
module.exports = function(Chart) {
Chart.Radar = function(context, config) {
config.options = Chart.helpers.configMerge({aspectRatio: 1}, config.options);
config.type = 'radar';
return new Chart(context, config);

View File

@@ -69,31 +69,29 @@ module.exports = function(Chart) {
var custom = rectangle.custom || {};
var dataset = me.getDataset();
helpers.extend(rectangle, {
// Utility
_xScale: xScale,
_yScale: yScale,
_datasetIndex: me.index,
_index: index,
rectangle._xScale = xScale;
rectangle._yScale = yScale;
rectangle._datasetIndex = me.index;
rectangle._index = index;
// Desired view properties
_model: {
x: me.calculateBarX(index, me.index),
y: reset ? scaleBase : me.calculateBarY(index, me.index),
var ruler = me.getRuler(index);
rectangle._model = {
x: me.calculateBarX(index, me.index, ruler),
y: reset ? scaleBase : me.calculateBarY(index, me.index),
// Tooltip
label: me.chart.data.labels[index],
datasetLabel: dataset.label,
// Tooltip
label: me.chart.data.labels[index],
datasetLabel: dataset.label,
// Appearance
base: reset ? scaleBase : me.calculateBarBase(me.index, index),
width: me.calculateBarWidth(ruler),
backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
};
// Appearance
base: reset ? scaleBase : me.calculateBarBase(me.index, index),
width: me.calculateBarWidth(index),
backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
}
});
rectangle.pivot();
},
@@ -160,12 +158,11 @@ module.exports = function(Chart) {
};
},
calculateBarWidth: function(index) {
calculateBarWidth: function(ruler) {
var xScale = this.getScaleForId(this.getMeta().xAxisID);
if (xScale.options.barThickness) {
return xScale.options.barThickness;
}
var ruler = this.getRuler(index);
return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
},
@@ -184,13 +181,11 @@ module.exports = function(Chart) {
return barIndex;
},
calculateBarX: function(index, datasetIndex) {
calculateBarX: function(index, datasetIndex, ruler) {
var me = this;
var meta = me.getMeta();
var xScale = me.getScaleForId(meta.xAxisID);
var barIndex = me.getBarIndex(datasetIndex);
var ruler = me.getRuler(index);
var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;
@@ -242,12 +237,16 @@ module.exports = function(Chart) {
draw: function(ease) {
var me = this;
var easingDecimal = ease || 1;
helpers.each(me.getMeta().data, function(rectangle, index) {
var d = me.getDataset().data[index];
var metaData = me.getMeta().data;
var dataset = me.getDataset();
var i, len;
for (i = 0, len = metaData.length; i < len; ++i) {
var d = dataset.data[i];
if (d !== null && d !== undefined && !isNaN(d)) {
rectangle.transition(easingDecimal).draw();
metaData[i].transition(easingDecimal).draw();
}
}, me);
}
},
setHoverStyle: function(rectangle) {
@@ -342,103 +341,84 @@ module.exports = function(Chart) {
var dataset = me.getDataset();
var rectangleElementOptions = me.chart.options.elements.rectangle;
helpers.extend(rectangle, {
// Utility
_xScale: xScale,
_yScale: yScale,
_datasetIndex: me.index,
_index: index,
rectangle._xScale = xScale;
rectangle._yScale = yScale;
rectangle._datasetIndex = me.index;
rectangle._index = index;
// Desired view properties
_model: {
x: reset ? scaleBase : me.calculateBarX(index, me.index),
y: me.calculateBarY(index, me.index),
var ruler = me.getRuler(index);
rectangle._model = {
x: reset ? scaleBase : me.calculateBarX(index, me.index),
y: me.calculateBarY(index, me.index, ruler),
// Tooltip
label: me.chart.data.labels[index],
datasetLabel: dataset.label,
// Tooltip
label: me.chart.data.labels[index],
datasetLabel: dataset.label,
// Appearance
base: reset ? scaleBase : me.calculateBarBase(me.index, index),
height: me.calculateBarHeight(index),
backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
},
// Appearance
base: reset ? scaleBase : me.calculateBarBase(me.index, index),
height: me.calculateBarHeight(ruler),
backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor),
borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped,
borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor),
borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth)
};
rectangle.draw = function() {
var ctx = this._chart.ctx;
var vm = this._view;
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;
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(cornerIndex) {
return corners[(startCorner + cornerIndex) % 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;
// 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(cornerIndex) {
return corners[(startCorner + cornerIndex) % 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();
}
};
rectangle.pivot();
},
@@ -505,13 +485,12 @@ module.exports = function(Chart) {
};
},
calculateBarHeight: function(index) {
calculateBarHeight: function(ruler) {
var me = this;
var yScale = me.getScaleForId(me.getMeta().yAxisID);
if (yScale.options.barThickness) {
return yScale.options.barThickness;
}
var ruler = me.getRuler(index);
return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
},
@@ -548,13 +527,11 @@ module.exports = function(Chart) {
return xScale.getPixelForValue(value);
},
calculateBarY: function(index, datasetIndex) {
calculateBarY: function(index, datasetIndex, ruler) {
var me = this;
var meta = me.getMeta();
var yScale = me.getScaleForId(meta.yAxisID);
var barIndex = me.getBarIndex(datasetIndex);
var ruler = me.getRuler(index);
var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;

View File

@@ -31,7 +31,7 @@ module.exports = function(Chart) {
label: function(tooltipItem, data) {
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';
return datasetLabel + ': (' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ', ' + dataPoint.r + ')';
}
}
}

View File

@@ -102,7 +102,19 @@ module.exports = function(Chart) {
return '';
},
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
var dataLabel = data.labels[tooltipItem.index];
var value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (helpers.isArray(dataLabel)) {
// show value on first line of multiline label
// need to clone because we are changing the value
dataLabel = dataLabel.slice();
dataLabel[0] += value;
} else {
dataLabel += value;
}
return dataLabel;
}
}
}

View File

@@ -34,19 +34,6 @@ module.exports = function(Chart) {
dataElementType: Chart.elements.Point,
addElementAndReset: function(index) {
var me = this;
var options = me.chart.options;
var meta = me.getMeta();
Chart.DatasetController.prototype.addElementAndReset.call(me, index);
// Make sure bezier control points are updated
if (lineEnabled(me.getDataset(), options) && meta.dataset._model.tension !== 0) {
me.updateBezierControlPoints();
}
},
update: function(reset) {
var me = this;
var meta = me.getMeta();
@@ -78,7 +65,7 @@ module.exports = function(Chart) {
// Appearance
// The default behavior of lines is to break at null values, according
// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
// This option gives linse the ability to span gaps
// This option gives lines the ability to span gaps
spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),

View File

@@ -32,11 +32,11 @@ module.exports = function(Chart) {
if (datasets.length) {
for (var i = 0; i < datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '">');
text.push('<li><span style="background-color:' + datasets[0].backgroundColor[i] + '"></span>');
if (labels[i]) {
text.push(labels[i]);
}
text.push('</span></li>');
text.push('</li>');
}
}

View File

@@ -5,6 +5,7 @@ module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.radar = {
aspectRatio: 1,
scale: {
type: 'radialLinear'
},
@@ -23,13 +24,6 @@ module.exports = function(Chart) {
linkScales: helpers.noop,
addElementAndReset: function(index) {
Chart.DatasetController.prototype.addElementAndReset.call(this, index);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function(reset) {
var me = this;
var meta = me.getMeta();
@@ -78,7 +72,6 @@ module.exports = function(Chart) {
me.updateElement(point, index, reset);
}, me);
// Update bezier control points
me.updateBezierControlPoints();
},

View File

@@ -27,6 +27,14 @@ module.exports = function(Chart) {
animations: [],
dropFrames: 0,
request: null,
/**
* @function Chart.animationService.addAnimation
* @param chartInstance {ChartController} the chart to animate
* @param animationObject {IAnimation} the animation that we will animate
* @param duration {Number} length of animation in ms
* @param lazy {Boolean} if true, the chart is not marked as animating to enable more responsive interactions
*/
addAnimation: function(chartInstance, animationObject, duration, lazy) {
var me = this;

View File

@@ -3,6 +3,7 @@
module.exports = function(Chart) {
var helpers = Chart.helpers;
// Create a dictionary of chart types, to allow for extension of existing types
Chart.types = {};
@@ -14,39 +15,228 @@ module.exports = function(Chart) {
Chart.controllers = {};
/**
* @class Chart.Controller
* The main controller of a chart.
* The "used" size is the final value of a dimension property after all calculations have
* been performed. This method uses the computed style of `element` but returns undefined
* if the computed style is not expressed in pixels. That can happen in some cases where
* `element` has a size relative to its parent and this last one is not yet displayed,
* for example because of `display: none` on a parent node.
* TODO(SB) Move this method in the upcoming core.platform class.
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
* @returns {Number} Size in pixels or undefined if unknown.
*/
Chart.Controller = function(instance) {
function readUsedSize(element, property) {
var value = helpers.getStyle(element, property);
var matches = value && value.match(/(\d+)px/);
return matches? Number(matches[1]) : undefined;
}
this.chart = instance;
this.config = instance.config;
this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});
this.id = helpers.uid();
/**
* Initializes the canvas style and render size without modifying the canvas display size,
* since responsiveness is handled by the controller.resize() method. The config is used
* to determine the aspect ratio to apply in case no explicit height has been specified.
* TODO(SB) Move this method in the upcoming core.platform class.
*/
function initCanvas(canvas, config) {
var style = canvas.style;
Object.defineProperty(this, 'data', {
get: function() {
return this.config.data;
// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it
// returns null or '' if no explicit value has been set to the canvas attribute.
var renderHeight = canvas.getAttribute('height');
var renderWidth = canvas.getAttribute('width');
// Chart.js modifies some canvas values that we want to restore on destroy
canvas._chartjs = {
initial: {
height: renderHeight,
width: renderWidth,
style: {
display: style.display,
height: style.height,
width: style.width
}
}
};
// Force canvas to display as block to avoid extra space caused by inline
// elements, which would interfere with the responsive resize process.
// https://github.com/chartjs/Chart.js/issues/2538
style.display = style.display || 'block';
if (renderWidth === null || renderWidth === '') {
var displayWidth = readUsedSize(canvas, 'width');
if (displayWidth !== undefined) {
canvas.width = displayWidth;
}
}
if (renderHeight === null || renderHeight === '') {
if (canvas.style.height === '') {
// If no explicit render height and style height, let's apply the aspect ratio,
// which one can be specified by the user but also by charts as default option
// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.
canvas.height = canvas.width / (config.options.aspectRatio || 2);
} else {
var displayHeight = readUsedSize(canvas, 'height');
if (displayWidth !== undefined) {
canvas.height = displayHeight;
}
}
}
return canvas;
}
/**
* Restores the canvas initial state, such as render/display sizes and style.
* TODO(SB) Move this method in the upcoming core.platform class.
*/
function releaseCanvas(canvas) {
if (!canvas._chartjs) {
return;
}
var initial = canvas._chartjs.initial;
['height', 'width'].forEach(function(prop) {
var value = initial[prop];
if (value === undefined || value === null) {
canvas.removeAttribute(prop);
} else {
canvas.setAttribute(prop, value);
}
});
// Add the chart instance to the global namespace
Chart.instances[this.id] = this;
helpers.each(initial.style || {}, function(value, key) {
canvas.style[key] = value;
});
if (this.options.responsive) {
// Silent resize before chart draws
this.resize(true);
// The canvas render size might have been changed (and thus the state stack discarded),
// we can't use save() and restore() to restore the initial state. So make sure that at
// least the canvas context is reset to the default state by setting the canvas width.
// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html
canvas.width = canvas.width;
delete canvas._chartjs;
}
/**
* TODO(SB) Move this method in the upcoming core.platform class.
*/
function acquireContext(item, config) {
if (typeof item === 'string') {
item = document.getElementById(item);
} else if (item.length) {
// Support for array based queries (such as jQuery)
item = item[0];
}
this.initialize();
if (item && item.canvas) {
// Support for any object associated to a canvas (including a context2d)
item = item.canvas;
}
return this;
if (item instanceof HTMLCanvasElement) {
// To prevent canvas fingerprinting, some add-ons undefine the getContext
// method, for example: https://github.com/kkapsner/CanvasBlocker
// https://github.com/chartjs/Chart.js/issues/2807
var context = item.getContext && item.getContext('2d');
if (context instanceof CanvasRenderingContext2D) {
initCanvas(item, config);
return context;
}
}
return null;
}
/**
* Initializes the given config with global and chart default values.
*/
function initConfig(config) {
config = config || {};
// Do NOT use configMerge() for the data object because this method merges arrays
// and so would change references to labels and datasets, preventing data updates.
var data = config.data = config.data || {};
data.datasets = data.datasets || [];
data.labels = data.labels || [];
config.options = helpers.configMerge(
Chart.defaults.global,
Chart.defaults[config.type],
config.options || {});
return config;
}
/**
* @class Chart.Controller
* The main controller of a chart.
*/
Chart.Controller = function(item, config, instance) {
var me = this;
config = initConfig(config);
var context = acquireContext(item, config);
var canvas = context && context.canvas;
var height = canvas && canvas.height;
var width = canvas && canvas.width;
instance.ctx = context;
instance.canvas = canvas;
instance.config = config;
instance.width = width;
instance.height = height;
instance.aspectRatio = height? width / height : null;
me.id = helpers.uid();
me.chart = instance;
me.config = config;
me.options = config.options;
me._bufferedRender = false;
// Add the chart instance to the global namespace
Chart.instances[me.id] = me;
Object.defineProperty(me, 'data', {
get: function() {
return me.config.data;
}
});
if (!context || !canvas) {
// The given item is not a compatible context2d element, let's return before finalizing
// the chart initialization but after setting basic chart / controller properties that
// can help to figure out that the chart is not valid (e.g chart.canvas !== null);
// https://github.com/chartjs/Chart.js/issues/2807
console.error("Failed to create chart: can't acquire context from the given item");
return me;
}
helpers.retinaScale(instance);
// Responsiveness is currently based on the use of an iframe, however this method causes
// performance issues and could be troublesome when used with ad blockers. So make sure
// that the user is still able to create a chart without iframe when responsive is false.
// See https://github.com/chartjs/Chart.js/issues/2210
if (me.options.responsive) {
helpers.addResizeListener(canvas.parentNode, function() {
me.resize();
});
// Initial resize before chart draws (must be silent to preserve initial animations).
me.resize(true);
}
me.initialize();
return me;
};
helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {
initialize: function() {
var me = this;
// Before init plugin notification
Chart.plugins.notify('beforeInit', [me]);
@@ -74,7 +264,7 @@ module.exports = function(Chart) {
},
stop: function() {
// Stops any current animation loop occuring
// Stops any current animation loop occurring
Chart.animationService.cancelAnimation(this);
return this;
},
@@ -82,19 +272,23 @@ module.exports = function(Chart) {
resize: function(silent) {
var me = this;
var chart = me.chart;
var options = me.options;
var canvas = chart.canvas;
var newWidth = helpers.getMaximumWidth(canvas);
var aspectRatio = chart.aspectRatio;
var newHeight = (me.options.maintainAspectRatio && isNaN(aspectRatio) === false && isFinite(aspectRatio) && aspectRatio !== 0) ? newWidth / aspectRatio : helpers.getMaximumHeight(canvas);
var aspectRatio = (options.maintainAspectRatio && chart.aspectRatio) || null;
var sizeChanged = chart.width !== newWidth || chart.height !== newHeight;
// the canvas render width and height will be casted to integers so make sure that
// the canvas display style uses the same integer values to avoid blurring effect.
var newWidth = Math.floor(helpers.getMaximumWidth(canvas));
var newHeight = Math.floor(aspectRatio? newWidth / aspectRatio : helpers.getMaximumHeight(canvas));
if (!sizeChanged) {
return me;
if (chart.width === newWidth && chart.height === newHeight) {
return;
}
canvas.width = chart.width = newWidth;
canvas.height = chart.height = newHeight;
canvas.style.width = newWidth + 'px';
canvas.style.height = newHeight + 'px';
helpers.retinaScale(chart);
@@ -111,8 +305,6 @@ module.exports = function(Chart) {
me.stop();
me.update(me.options.responsiveAnimationDuration);
}
return me;
},
ensureScalesHaveIDs: function() {
@@ -222,6 +414,11 @@ module.exports = function(Chart) {
return newControllers;
},
/**
* Reset the elements of all datasets
* @method resetElements
* @private
*/
resetElements: function() {
var me = this;
helpers.each(me.data.datasets, function(dataset, datasetIndex) {
@@ -229,6 +426,15 @@ module.exports = function(Chart) {
}, me);
},
/**
* Resets the chart back to it's state before the initial animation
* @method reset
*/
reset: function() {
this.resetElements();
this.tooltip.initialize();
},
update: function(animationDuration, lazy) {
var me = this;
Chart.plugins.notify('beforeUpdate', [me]);
@@ -246,7 +452,7 @@ module.exports = function(Chart) {
Chart.layoutService.update(me, me.chart.width, me.chart.height);
// Apply changes to the dataets that require the scales to have been calculated i.e BorderColor chages
// Apply changes to the datasets that require the scales to have been calculated i.e BorderColor changes
Chart.plugins.notify('afterScaleUpdate', [me]);
// Can only reset the new controllers after the scales have been updated
@@ -259,7 +465,14 @@ module.exports = function(Chart) {
// Do this before render so that any plugins that need final scale updates can use it
Chart.plugins.notify('afterUpdate', [me]);
me.render(animationDuration, lazy);
if (me._bufferedRender) {
me._bufferedRequest = {
lazy: lazy,
duration: animationDuration
};
} else {
me.render(animationDuration, lazy);
}
},
/**
@@ -371,125 +584,28 @@ module.exports = function(Chart) {
// 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 me = this;
var eventPosition = helpers.getRelativePosition(e, me.chart);
var elementsArray = [];
helpers.each(me.data.datasets, function(dataset, datasetIndex) {
if (me.isDatasetVisible(datasetIndex)) {
var meta = me.getDatasetMeta(datasetIndex);
helpers.each(meta.data, function(element) {
if (element.inRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
return elementsArray;
}
});
}
});
return elementsArray.slice(0, 1);
return Chart.Interaction.modes.single(this, e);
},
getElementsAtEvent: function(e) {
var me = this;
var eventPosition = helpers.getRelativePosition(e, me.chart);
var elementsArray = [];
var found = function() {
if (me.data.datasets) {
for (var i = 0; i < me.data.datasets.length; i++) {
var meta = me.getDatasetMeta(i);
if (me.isDatasetVisible(i)) {
for (var j = 0; j < meta.data.length; j++) {
if (meta.data[j].inRange(eventPosition.x, eventPosition.y)) {
return meta.data[j];
}
}
}
}
}
}.call(me);
if (!found) {
return elementsArray;
}
helpers.each(me.data.datasets, function(dataset, datasetIndex) {
if (me.isDatasetVisible(datasetIndex)) {
var meta = me.getDatasetMeta(datasetIndex),
element = meta.data[found._index];
if (element && !element._view.skip) {
elementsArray.push(element);
}
}
}, me);
return elementsArray;
return Chart.Interaction.modes.label(this, e, {intersect: true});
},
getElementsAtXAxis: function(e) {
var me = this;
var eventPosition = helpers.getRelativePosition(e, me.chart);
var elementsArray = [];
var found = function() {
if (me.data.datasets) {
for (var i = 0; i < me.data.datasets.length; i++) {
var meta = me.getDatasetMeta(i);
if (me.isDatasetVisible(i)) {
for (var j = 0; j < meta.data.length; j++) {
if (meta.data[j].inLabelRange(eventPosition.x, eventPosition.y)) {
return meta.data[j];
}
}
}
}
}
}.call(me);
if (!found) {
return elementsArray;
}
helpers.each(me.data.datasets, function(dataset, datasetIndex) {
if (me.isDatasetVisible(datasetIndex)) {
var meta = me.getDatasetMeta(datasetIndex);
var index = helpers.findIndex(meta.data, function(it) {
return found._model.x === it._model.x;
});
if (index !== -1 && !meta.data[index]._view.skip) {
elementsArray.push(meta.data[index]);
}
}
}, me);
return elementsArray;
return Chart.Interaction.modes['x-axis'](this, e, {intersect: true});
},
getElementsAtEventForMode: function(e, mode) {
var me = this;
switch (mode) {
case 'single':
return me.getElementAtEvent(e);
case 'label':
return me.getElementsAtEvent(e);
case 'dataset':
return me.getDatasetAtEvent(e);
case 'x-axis':
return me.getElementsAtXAxis(e);
default:
return e;
getElementsAtEventForMode: function(e, mode, options) {
var method = Chart.Interaction.modes[mode];
if (typeof method === 'function') {
return method(this, e, options);
}
return [];
},
getDatasetAtEvent: function(e) {
var elementsArray = this.getElementAtEvent(e);
if (elementsArray.length > 0) {
elementsArray = this.getDatasetMeta(elementsArray[0]._datasetIndex).data;
}
return elementsArray;
return Chart.Interaction.modes.dataset(this, e);
},
getDatasetMeta: function(datasetIndex) {
@@ -539,24 +655,28 @@ module.exports = function(Chart) {
destroy: function() {
var me = this;
me.stop();
me.clear();
helpers.unbindEvents(me, me.events);
helpers.removeResizeListener(me.chart.canvas.parentNode);
// Reset canvas height/width attributes
var canvas = me.chart.canvas;
canvas.width = me.chart.width;
canvas.height = me.chart.height;
var meta, i, ilen;
// if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here
if (me.chart.originalDevicePixelRatio !== undefined) {
me.chart.ctx.scale(1 / me.chart.originalDevicePixelRatio, 1 / me.chart.originalDevicePixelRatio);
me.stop();
// dataset controllers need to cleanup associated data
for (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {
meta = me.getDatasetMeta(i);
if (meta.controller) {
meta.controller.destroy();
meta.controller = null;
}
}
// Reset to the old style since it may have been changed by the device pixel ratio changes
canvas.style.width = me.chart.originalCanvasStyleWidth;
canvas.style.height = me.chart.originalCanvasStyleHeight;
if (canvas) {
helpers.unbindEvents(me, me.events);
helpers.removeResizeListener(canvas.parentNode);
helpers.clear(me.chart);
releaseCanvas(canvas);
me.chart.canvas = null;
me.chart.ctx = null;
}
Chart.plugins.notify('destroy', [me]);
@@ -575,6 +695,7 @@ module.exports = function(Chart) {
_data: me.data,
_options: me.options.tooltips
}, me);
me.tooltip.initialize();
},
bindEvents: function() {
@@ -588,20 +709,6 @@ module.exports = function(Chart) {
var method = enabled? 'setHoverStyle' : 'removeHoverStyle';
var element, i, ilen;
switch (mode) {
case 'single':
elements = [elements[0]];
break;
case 'label':
case 'dataset':
case 'x-axis':
// elements = elements;
break;
default:
// unsupported mode
return;
}
for (i=0, ilen=elements.length; i<ilen; ++i) {
element = elements[i];
if (element) {
@@ -612,21 +719,56 @@ module.exports = function(Chart) {
eventHandler: function(e) {
var me = this;
var legend = me.legend;
var tooltip = me.tooltip;
var hoverOptions = me.options.hover;
// Buffer any update calls so that renders do not occur
me._bufferedRender = true;
me._bufferedRequest = null;
var changed = me.handleEvent(e);
changed |= legend && legend.handleEvent(e);
changed |= tooltip && tooltip.handleEvent(e);
var bufferedRequest = me._bufferedRequest;
if (bufferedRequest) {
// If we have an update that was triggered, we need to do a normal render
me.render(bufferedRequest.duration, bufferedRequest.lazy);
} else if (changed && !me.animating) {
// If entering, leaving, or changing elements, animate the change via pivot
me.stop();
// We only need to render at this point. Updating will cause scales to be
// recomputed generating flicker & using more memory than necessary.
me.render(hoverOptions.animationDuration, true);
}
me._bufferedRender = false;
me._bufferedRequest = null;
return me;
},
/**
* Handle an event
* @private
* param e {Event} the event to handle
* @return {Boolean} true if the chart needs to re-render
*/
handleEvent: function(e) {
var me = this;
var options = me.options || {};
var hoverOptions = options.hover;
var tooltipsOptions = options.tooltips;
var changed = false;
me.lastActive = me.lastActive || [];
me.lastTooltipActive = me.lastTooltipActive || [];
// Find Active Elements for hover and tooltips
if (e.type === 'mouseout') {
me.active = [];
me.tooltipActive = [];
} else {
me.active = me.getElementsAtEventForMode(e, hoverOptions.mode);
me.tooltipActive = me.getElementsAtEventForMode(e, tooltipsOptions.mode);
me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);
}
// On Hover hook
@@ -634,10 +776,6 @@ module.exports = function(Chart) {
hoverOptions.onHover.call(me, me.active);
}
if (me.legend && me.legend.handleEvent) {
me.legend.handleEvent(e);
}
if (e.type === 'mouseup' || e.type === 'click') {
if (options.onClick) {
options.onClick.call(me, e, me.active);
@@ -654,37 +792,12 @@ module.exports = function(Chart) {
me.updateHoverStyle(me.active, hoverOptions.mode, true);
}
// Built in Tooltips
if (tooltipsOptions.enabled || tooltipsOptions.custom) {
tooltip.initialize();
tooltip._active = me.tooltipActive;
tooltip.update(true);
}
// Hover animations
tooltip.pivot();
if (!me.animating) {
// If entering, leaving, or changing elements, animate the change via pivot
if (!helpers.arrayEquals(me.active, me.lastActive) ||
!helpers.arrayEquals(me.tooltipActive, me.lastTooltipActive)) {
me.stop();
if (tooltipsOptions.enabled || tooltipsOptions.custom) {
tooltip.update(true);
}
// We only need to render at this point. Updating will cause scales to be
// recomputed generating flicker & using more memory than necessary.
me.render(hoverOptions.animationDuration, true);
}
}
changed = !helpers.arrayEquals(me.active, me.lastActive);
// Remember Last Actives
me.lastActive = me.active;
me.lastTooltipActive = me.tooltipActive;
return me;
return changed;
}
});
};

View File

@@ -3,7 +3,77 @@
module.exports = function(Chart) {
var helpers = Chart.helpers;
var noop = helpers.noop;
var arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];
/**
* Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',
* 'unshift') and notify the listener AFTER the array has been altered. Listeners are
* called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.
*/
function listenArrayEvents(array, listener) {
if (array._chartjs) {
array._chartjs.listeners.push(listener);
return;
}
Object.defineProperty(array, '_chartjs', {
configurable: true,
enumerable: false,
value: {
listeners: [listener]
}
});
arrayEvents.forEach(function(key) {
var method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);
var base = array[key];
Object.defineProperty(array, key, {
configurable: true,
enumerable: false,
value: function() {
var args = Array.prototype.slice.call(arguments);
var res = base.apply(this, args);
helpers.each(array._chartjs.listeners, function(object) {
if (typeof object[method] === 'function') {
object[method].apply(object, args);
}
});
return res;
}
});
});
}
/**
* Removes the given array event listener and cleanup extra attached properties (such as
* the _chartjs stub and overridden methods) if array doesn't have any more listeners.
*/
function unlistenArrayEvents(array, listener) {
var stub = array._chartjs;
if (!stub) {
return;
}
var listeners = stub.listeners;
var index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
if (listeners.length > 0) {
return;
}
arrayEvents.forEach(function(key) {
delete array[key];
});
delete array._chartjs;
}
// Base class for all dataset controllers (line, bar, etc)
Chart.DatasetController = function(chart, datasetIndex) {
@@ -65,6 +135,15 @@ module.exports = function(Chart) {
this.update(true);
},
/**
* @private
*/
destroy: function() {
if (this._data) {
unlistenArrayEvents(this._data, this);
}
},
createMetaDataset: function() {
var me = this;
var type = me.datasetElementType;
@@ -92,45 +171,50 @@ module.exports = function(Chart) {
var i, ilen;
for (i=0, ilen=data.length; i<ilen; ++i) {
metaData[i] = metaData[i] || me.createMetaData(meta, i);
metaData[i] = metaData[i] || me.createMetaData(i);
}
meta.dataset = meta.dataset || me.createMetaDataset();
},
addElementAndReset: function(index) {
var me = this;
var element = me.createMetaData(index);
me.getMeta().data.splice(index, 0, element);
me.updateElement(element, index, true);
var element = this.createMetaData(index);
this.getMeta().data.splice(index, 0, element);
this.updateElement(element, index, true);
},
buildOrUpdateElements: function() {
// Handle the number of data points changing
var meta = this.getMeta(),
md = meta.data,
numData = this.getDataset().data.length,
numMetaData = md.length;
var me = this;
var dataset = me.getDataset();
var data = dataset.data || (dataset.data = []);
// Make sure that we handle number of datapoints changing
if (numData < numMetaData) {
// Remove excess bars for data points that have been removed
md.splice(numData, numMetaData - numData);
} else if (numData > numMetaData) {
// Add new elements
for (var index = numMetaData; index < numData; ++index) {
this.addElementAndReset(index);
// In order to correctly handle data addition/deletion animation (an thus simulate
// real-time charts), we need to monitor these data modifications and synchronize
// the internal meta data accordingly.
if (me._data !== data) {
if (me._data) {
// This case happens when the user replaced the data array instance.
unlistenArrayEvents(me._data, me);
}
listenArrayEvents(data, me);
me._data = data;
}
// Re-sync meta data in case the user replaced the data array or if we missed
// any updates and so make sure that we handle number of datapoints changing.
me.resyncElements();
},
update: noop,
update: helpers.noop,
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getMeta().data, function(element) {
element.transition(easingDecimal).draw();
});
var i, len;
var metaData = this.getMeta().data;
for (i = 0, len = metaData.length; i < len; ++i) {
metaData[i].transition(easingDecimal).draw();
}
},
removeHoverStyle: function(element, elementOpts) {
@@ -156,8 +240,69 @@ module.exports = function(Chart) {
model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor));
model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
}
},
/**
* @private
*/
resyncElements: function() {
var me = this;
var meta = me.getMeta();
var data = me.getDataset().data;
var numMeta = meta.data.length;
var numData = data.length;
if (numData < numMeta) {
meta.data.splice(numData, numMeta - numData);
} else if (numData > numMeta) {
me.insertElements(numMeta, numData - numMeta);
}
},
/**
* @private
*/
insertElements: function(start, count) {
for (var i=0; i<count; ++i) {
this.addElementAndReset(start + i);
}
},
/**
* @private
*/
onDataPush: function() {
this.insertElements(this.getDataset().data.length-1, arguments.length);
},
/**
* @private
*/
onDataPop: function() {
this.getMeta().data.pop();
},
/**
* @private
*/
onDataShift: function() {
this.getMeta().data.shift();
},
/**
* @private
*/
onDataSplice: function(start, count) {
this.getMeta().data.splice(start, count);
this.insertElements(start, arguments.length - 2);
},
/**
* @private
*/
onDataUnshift: function() {
this.insertElements(0, arguments.length);
}
});
Chart.DatasetController.extend = helpers.inherits;

View File

@@ -58,37 +58,23 @@ module.exports = function(Chart) {
var base = helpers.clone(_base);
helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
helpers.each(extension, function(value, key) {
if (key === 'scales') {
// Scale config merging is complex. Add out own function here for that
base[key] = helpers.scaleMerge(base.hasOwnProperty(key) ? base[key] : {}, value);
var baseHasProperty = base.hasOwnProperty(key);
var baseVal = baseHasProperty ? base[key] : {};
if (key === 'scales') {
// Scale config merging is complex. Add our own function here for that
base[key] = helpers.scaleMerge(baseVal, value);
} else if (key === 'scale') {
// Used in polar area & radar charts since there is only one scale
base[key] = helpers.configMerge(base.hasOwnProperty(key) ? base[key] : {}, Chart.scaleService.getScaleDefaults(value.type), value);
} else if (base.hasOwnProperty(key) && helpers.isArray(base[key]) && helpers.isArray(value)) {
// In this case we have an array of objects replacing another array. Rather than doing a strict replace,
// merge. This allows easy scale option merging
var baseArray = base[key];
helpers.each(value, function(valueObj, index) {
if (index < baseArray.length) {
if (typeof baseArray[index] === 'object' && baseArray[index] !== null && typeof valueObj === 'object' && valueObj !== null) {
// Two objects are coming together. Do a merge of them.
baseArray[index] = helpers.configMerge(baseArray[index], valueObj);
} else {
// Just overwrite in this case since there is nothing to merge
baseArray[index] = valueObj;
}
} else {
baseArray.push(valueObj); // nothing to merge
}
});
} else if (base.hasOwnProperty(key) && typeof base[key] === 'object' && base[key] !== null && typeof value === 'object') {
base[key] = helpers.configMerge(baseVal, Chart.scaleService.getScaleDefaults(value.type), value);
} else if (baseHasProperty
&& typeof baseVal === 'object'
&& !helpers.isArray(baseVal)
&& baseVal !== null
&& typeof value === 'object'
&& !helpers.isArray(value)) {
// If we are overwriting an object with an object, do a merge of the properties.
base[key] = helpers.configMerge(base[key], value);
base[key] = helpers.configMerge(baseVal, value);
} else {
// can just overwrite the value in this case
base[key] = value;
@@ -308,6 +294,9 @@ module.exports = function(Chart) {
distance: radialDistanceFromCenter
};
};
helpers.distanceBetweenPoints = function(pt1, pt2) {
return Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));
};
helpers.aliasPixel = function(pixelWidth) {
return (pixelWidth % 2 === 0) ? 0 : 0.5;
};
@@ -843,25 +832,24 @@ module.exports = function(Chart) {
document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
};
helpers.retinaScale = function(chart) {
var ctx = chart.ctx;
var canvas = chart.canvas;
var width = canvas.width;
var height = canvas.height;
var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
if (pixelRatio !== 1) {
canvas.height = height * pixelRatio;
canvas.width = width * pixelRatio;
ctx.scale(pixelRatio, pixelRatio);
// Store the device pixel ratio so that we can go backwards in `destroy`.
// The devicePixelRatio changes with zoom, so there are no guarantees that it is the same
// when destroy is called
chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;
if (pixelRatio === 1) {
return;
}
canvas.style.width = width + 'px';
var canvas = chart.canvas;
var height = chart.height;
var width = chart.width;
canvas.height = height * pixelRatio;
canvas.width = width * pixelRatio;
chart.ctx.scale(pixelRatio, pixelRatio);
// If no style has been set on the canvas, the render size is used as display size,
// making the chart visually bigger, so let's enforce it to the "correct" values.
// See https://github.com/chartjs/Chart.js/issues/3575
canvas.style.height = height + 'px';
canvas.style.width = width + 'px';
};
// -- Canvas methods
helpers.clear = function(chart) {
@@ -957,47 +945,71 @@ module.exports = function(Chart) {
return color(c);
};
helpers.addResizeListener = function(node, callback) {
// Hide an iframe before the node
var hiddenIframe = document.createElement('iframe');
var hiddenIframeClass = 'chartjs-hidden-iframe';
var iframe = document.createElement('iframe');
iframe.className = 'chartjs-hidden-iframe';
iframe.style.cssText =
'display:block;'+
'overflow:hidden;'+
'border:0;'+
'margin:0;'+
'top:0;'+
'left:0;'+
'bottom:0;'+
'right:0;'+
'height:100%;'+
'width:100%;'+
'position:absolute;'+
'pointer-events:none;'+
'z-index:-1;';
if (hiddenIframe.classlist) {
// can use classlist
hiddenIframe.classlist.add(hiddenIframeClass);
} else {
hiddenIframe.setAttribute('class', hiddenIframeClass);
}
// Prevent the iframe to gain focus on tab.
// https://github.com/chartjs/Chart.js/issues/3090
iframe.tabIndex = -1;
// Set the style
hiddenIframe.tabIndex = -1;
var style = hiddenIframe.style;
style.width = '100%';
style.display = 'block';
style.border = 0;
style.height = 0;
style.margin = 0;
style.position = 'absolute';
style.left = 0;
style.right = 0;
style.top = 0;
style.bottom = 0;
// Let's keep track of this added iframe and thus avoid DOM query when removing it.
var stub = node._chartjs = {
resizer: iframe,
ticking: false
};
// Insert the iframe so that contentWindow is available
node.insertBefore(hiddenIframe, node.firstChild);
(hiddenIframe.contentWindow || hiddenIframe).onresize = function() {
if (callback) {
return callback();
// Throttle the callback notification until the next animation frame.
var notify = function() {
if (!stub.ticking) {
stub.ticking = true;
helpers.requestAnimFrame.call(window, function() {
if (stub.resizer) {
stub.ticking = false;
return callback();
}
});
}
};
// If the iframe is re-attached to the DOM, the resize listener is removed because the
// content is reloaded, so make sure to install the handler after the iframe is loaded.
// https://github.com/chartjs/Chart.js/issues/3521
helpers.addEvent(iframe, 'load', function() {
helpers.addEvent(iframe.contentWindow || iframe, 'resize', notify);
// The iframe size might have changed while loading, which can also
// happen if the size has been changed while detached from the DOM.
notify();
});
node.insertBefore(iframe, node.firstChild);
};
helpers.removeResizeListener = function(node) {
var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
// Remove the resize detect iframe
if (hiddenIframe) {
hiddenIframe.parentNode.removeChild(hiddenIframe);
if (!node || !node._chartjs) {
return;
}
var iframe = node._chartjs.resizer;
if (iframe) {
iframe.parentNode.removeChild(iframe);
node._chartjs.resizer = null;
}
delete node._chartjs;
};
helpers.isArray = Array.isArray?
function(obj) {

View File

@@ -0,0 +1,295 @@
'use strict';
module.exports = function(Chart) {
var helpers = Chart.helpers;
/**
* Helper function to traverse all of the visible elements in the chart
* @param chart {chart} the chart
* @param handler {Function} the callback to execute for each visible item
*/
function parseVisibleItems(chart, handler) {
var datasets = chart.data.datasets;
var meta, i, j, ilen, jlen;
for (i = 0, ilen = datasets.length; i < ilen; ++i) {
if (!chart.isDatasetVisible(i)) {
continue;
}
meta = chart.getDatasetMeta(i);
for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
var element = meta.data[j];
if (!element._view.skip) {
handler(element);
}
}
}
}
/**
* Helper function to get the items that intersect the event position
* @param items {ChartElement[]} elements to filter
* @param position {Point} the point to be nearest to
* @return {ChartElement[]} the nearest items
*/
function getIntersectItems(chart, position) {
var elements = [];
parseVisibleItems(chart, function(element) {
if (element.inRange(position.x, position.y)) {
elements.push(element);
}
});
return elements;
}
/**
* Helper function to get the items nearest to the event position considering all visible items in teh chart
* @param chart {Chart} the chart to look at elements from
* @param position {Point} the point to be nearest to
* @param intersect {Boolean} if true, only consider items that intersect the position
* @param distanceMetric {Function} Optional function to provide the distance between
* @return {ChartElement[]} the nearest items
*/
function getNearestItems(chart, position, intersect, distanceMetric) {
var minDistance = Number.POSITIVE_INFINITY;
var nearestItems = [];
if (!distanceMetric) {
distanceMetric = helpers.distanceBetweenPoints;
}
parseVisibleItems(chart, function(element) {
if (intersect && !element.inRange(position.x, position.y)) {
return;
}
var center = element.getCenterPoint();
var distance = distanceMetric(position, center);
if (distance < minDistance) {
nearestItems = [element];
minDistance = distance;
} else if (distance === minDistance) {
// Can have multiple items at the same distance in which case we sort by size
nearestItems.push(element);
}
});
return nearestItems;
}
function indexMode(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var distanceMetric = function(pt1, pt2) {
return Math.abs(pt1.x - pt2.x);
};
var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
var elements = [];
if (!items.length) {
return [];
}
chart.data.datasets.forEach(function(dataset, datasetIndex) {
if (chart.isDatasetVisible(datasetIndex)) {
var meta = chart.getDatasetMeta(datasetIndex),
element = meta.data[items[0]._index];
// don't count items that are skipped (null data)
if (element && !element._view.skip) {
elements.push(element);
}
}
});
return elements;
}
/**
* @interface IInteractionOptions
*/
/**
* If true, only consider items that intersect the point
* @name IInterfaceOptions#boolean
* @type Boolean
*/
/**
* @namespace Chart.Interaction
* Contains interaction related functions
*/
Chart.Interaction = {
// Helper function for different modes
modes: {
single: function(chart, e) {
var position = helpers.getRelativePosition(e, chart.chart);
var elements = [];
parseVisibleItems(chart, function(element) {
if (element.inRange(position.x, position.y)) {
elements.push(element);
return elements;
}
});
return elements.slice(0, 1);
},
/**
* @function Chart.Interaction.modes.label
* @deprecated since version 2.4.0
*/
label: indexMode,
/**
* Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something
* If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item
* @function Chart.Interaction.modes.index
* @since v2.4.0
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @param options {IInteractionOptions} options to use during interaction
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
index: indexMode,
/**
* Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something
* If the options.intersect is false, we find the nearest item and return the items in that dataset
* @function Chart.Interaction.modes.dataset
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @param options {IInteractionOptions} options to use during interaction
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
dataset: function(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);
if (items.length > 0) {
items = chart.getDatasetMeta(items[0]._datasetIndex).data;
}
return items;
},
/**
* @function Chart.Interaction.modes.x-axis
* @deprecated since version 2.4.0. Use index mode and intersect == true
*/
'x-axis': function(chart, e) {
return indexMode(chart, e, true);
},
/**
* Point mode returns all elements that hit test based on the event position
* of the event
* @function Chart.Interaction.modes.intersect
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
point: function(chart, e) {
var position = helpers.getRelativePosition(e, chart.chart);
return getIntersectItems(chart, position);
},
/**
* nearest mode returns the element closest to the point
* @function Chart.Interaction.modes.intersect
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @param options {IInteractionOptions} options to use
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
nearest: function(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var nearestItems = getNearestItems(chart, position, options.intersect);
// We have multiple items at the same distance from the event. Now sort by smallest
if (nearestItems.length > 1) {
nearestItems.sort(function(a, b) {
var sizeA = a.getArea();
var sizeB = b.getArea();
var ret = sizeA - sizeB;
if (ret === 0) {
// if equal sort by dataset index
ret = a._datasetIndex - b._datasetIndex;
}
return ret;
});
}
// Return only 1 item
return nearestItems.slice(0, 1);
},
/**
* x mode returns the elements that hit-test at the current x coordinate
* @function Chart.Interaction.modes.x
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @param options {IInteractionOptions} options to use
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
x: function(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var items = [];
var intersectsItem = false;
parseVisibleItems(chart, function(element) {
if (element.inXRange(position.x)) {
items.push(element);
}
if (element.inRange(position.x, position.y)) {
intersectsItem = true;
}
});
// If we want to trigger on an intersect and we don't have any items
// that intersect the position, return nothing
if (options.intersect && !intersectsItem) {
items = [];
}
return items;
},
/**
* y mode returns the elements that hit-test at the current y coordinate
* @function Chart.Interaction.modes.y
* @param chart {chart} the chart we are returning items from
* @param e {Event} the event we are find things at
* @param options {IInteractionOptions} options to use
* @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned
*/
y: function(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var items = [];
var intersectsItem = false;
parseVisibleItems(chart, function(element) {
if (element.inYRange(position.y)) {
items.push(element);
}
if (element.inRange(position.x, position.y)) {
intersectsItem = true;
}
});
// If we want to trigger on an intersect and we don't have any items
// that intersect the position, return nothing
if (options.intersect && !intersectsItem) {
items = [];
}
return items;
}
}
};
};

View File

@@ -3,63 +3,9 @@
module.exports = function() {
// Occupy the global variable of Chart, and create a simple base class
var Chart = function(context, config) {
var me = this;
var helpers = Chart.helpers;
me.config = config || {
data: {
datasets: []
}
};
// Support a jQuery'd canvas element
if (context.length && context[0].getContext) {
context = context[0];
}
// Support a canvas domnode
if (context.getContext) {
context = context.getContext('2d');
}
me.ctx = context;
me.canvas = context.canvas;
context.canvas.style.display = context.canvas.style.display || 'block';
// Figure out what the size of the chart will be.
// If the canvas has a specified width and height, we use those else
// we look to see if the canvas node has a CSS width and height.
// If there is still no height, fill the parent container
me.width = context.canvas.width || parseInt(helpers.getStyle(context.canvas, 'width'), 10) || helpers.getMaximumWidth(context.canvas);
me.height = context.canvas.height || parseInt(helpers.getStyle(context.canvas, 'height'), 10) || helpers.getMaximumHeight(context.canvas);
me.aspectRatio = me.width / me.height;
if (isNaN(me.aspectRatio) || isFinite(me.aspectRatio) === false) {
// If the canvas has no size, try and figure out what the aspect ratio will be.
// Some charts prefer square canvases (pie, radar, etc). If that is specified, use that
// else use the canvas default ratio of 2
me.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
}
// Store the original style of the element so we can set it back
me.originalCanvasStyleWidth = context.canvas.style.width;
me.originalCanvasStyleHeight = context.canvas.style.height;
// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
helpers.retinaScale(me);
me.controller = new Chart.Controller(me);
// Always bind this so that if the responsive state changes we still work
helpers.addResizeListener(context.canvas.parentNode, function() {
if (me.controller && me.controller.config.options.responsive) {
me.controller.resize();
}
});
return me.controller ? me.controller : me;
var Chart = function(item, config) {
this.controller = new Chart.Controller(item, config, this);
return this.controller;
};
// Globally expose the defaults to allow for user updating/changing
@@ -71,7 +17,8 @@ module.exports = function() {
events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
hover: {
onHover: null,
mode: 'single',
mode: 'nearest',
intersect: true,
animationDuration: 400
},
onClick: null,
@@ -106,5 +53,4 @@ module.exports = function() {
Chart.Chart = Chart;
return Chart;
};

View File

@@ -32,8 +32,26 @@ module.exports = function(Chart) {
return;
}
var xPadding = 0;
var yPadding = 0;
var layoutOptions = chartInstance.options.layout;
var padding = layoutOptions ? layoutOptions.padding : null;
var leftPadding = 0;
var rightPadding = 0;
var topPadding = 0;
var bottomPadding = 0;
if (!isNaN(padding)) {
// options.layout.padding is a number. assign to all
leftPadding = padding;
rightPadding = padding;
topPadding = padding;
bottomPadding = padding;
} else {
leftPadding = padding.left || 0;
rightPadding = padding.right || 0;
topPadding = padding.top || 0;
bottomPadding = padding.bottom || 0;
}
var leftBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === 'left';
@@ -99,8 +117,8 @@ module.exports = function(Chart) {
// 9. Tell any axes that overlay the chart area the positions of the chart area
// Step 1
var chartWidth = width - (2 * xPadding);
var chartHeight = height - (2 * yPadding);
var chartWidth = width - leftPadding - rightPadding;
var chartHeight = height - topPadding - bottomPadding;
var chartAreaWidth = chartWidth / 2; // min 50%
var chartAreaHeight = chartHeight / 2; // min 50%
@@ -140,10 +158,10 @@ module.exports = function(Chart) {
// be if the axes are drawn at their minimum sizes.
// Steps 5 & 6
var totalLeftBoxesWidth = xPadding;
var totalRightBoxesWidth = xPadding;
var totalTopBoxesHeight = yPadding;
var totalBottomBoxesHeight = yPadding;
var totalLeftBoxesWidth = leftPadding;
var totalRightBoxesWidth = rightPadding;
var totalTopBoxesHeight = topPadding;
var totalBottomBoxesHeight = bottomPadding;
// Function to fit a box
function fitBox(box) {
@@ -213,10 +231,10 @@ module.exports = function(Chart) {
helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
totalLeftBoxesWidth = xPadding;
totalRightBoxesWidth = xPadding;
totalTopBoxesHeight = yPadding;
totalBottomBoxesHeight = yPadding;
totalLeftBoxesWidth = leftPadding;
totalRightBoxesWidth = rightPadding;
totalTopBoxesHeight = topPadding;
totalBottomBoxesHeight = bottomPadding;
helpers.each(leftBoxes, function(box) {
totalLeftBoxesWidth += box.width;
@@ -265,13 +283,13 @@ module.exports = function(Chart) {
}
// Step 7 - Position the boxes
var left = xPadding;
var top = yPadding;
var left = leftPadding;
var top = topPadding;
function placeBox(box) {
if (box.isHorizontal()) {
box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;
box.left = box.options.fullWidth ? leftPadding : totalLeftBoxesWidth;
box.right = box.options.fullWidth ? width - rightPadding : totalLeftBoxesWidth + maxChartAreaWidth;
box.top = top;
box.bottom = top + box.height;

View File

@@ -64,6 +64,18 @@ module.exports = function(Chart) {
}
};
/**
* Helper function to get the box width based on the usePointStyle option
* @param labelopts {Object} the label options on the legend
* @param fontSize {Number} the label font size
* @return {Number} width of the color box area
*/
function getBoxWidth(labelOpts, fontSize) {
return labelOpts.usePointStyle ?
fontSize * Math.SQRT2 :
labelOpts.boxWidth;
}
Chart.Legend = Chart.Element.extend({
initialize: function(config) {
@@ -76,7 +88,7 @@ module.exports = function(Chart) {
this.doughnutMode = false;
},
// These methods are ordered by lifecyle. Utilities then follow.
// These methods are ordered by lifecycle. Utilities then follow.
// Any function defined here is inherited by all legend types.
// Any function can be extended by the legend type
@@ -204,11 +216,9 @@ module.exports = function(Chart) {
ctx.textBaseline = 'top';
helpers.each(me.legendItems, function(legendItem, i) {
var boxWidth = labelOpts.usePointStyle ?
fontSize * Math.sqrt(2) :
labelOpts.boxWidth;
var boxWidth = getBoxWidth(labelOpts, fontSize);
var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
totalHeight += fontSize + (labelOpts.padding);
lineWidths[lineWidths.length] = me.left;
@@ -236,10 +246,7 @@ module.exports = function(Chart) {
var itemHeight = fontSize + vPadding;
helpers.each(me.legendItems, function(legendItem, i) {
// If usePointStyle is set, multiple boxWidth by 2 since it represents
// the radius and not truly the width
var boxWidth = labelOpts.usePointStyle ? 2 * labelOpts.boxWidth : labelOpts.boxWidth;
var boxWidth = getBoxWidth(labelOpts, fontSize);
var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
// If too tall, go to new column
@@ -280,7 +287,7 @@ module.exports = function(Chart) {
return this.options.position === 'top' || this.options.position === 'bottom';
},
// Actualy draw the legend on the canvas
// Actually draw the legend on the canvas
draw: function() {
var me = this;
var opts = me.options;
@@ -308,7 +315,7 @@ module.exports = function(Chart) {
ctx.fillStyle = fontColor; // render in correct colour
ctx.font = labelFont;
var boxWidth = labelOpts.boxWidth,
var boxWidth = getBoxWidth(labelOpts, fontSize),
hitboxes = me.legendHitBoxes;
// current position
@@ -334,7 +341,7 @@ module.exports = function(Chart) {
}
if (opts.labels && opts.labels.usePointStyle) {
// Recalulate x and y for drawPoint() because its expecting
// Recalculate x and y for drawPoint() because its expecting
// x and y to be center of figure (instead of top left)
var radius = fontSize * Math.SQRT2 / 2;
var offSet = radius / Math.SQRT2;
@@ -385,9 +392,7 @@ module.exports = function(Chart) {
var itemHeight = fontSize + labelOpts.padding;
helpers.each(me.legendItems, function(legendItem, i) {
var textWidth = ctx.measureText(legendItem.text).width,
width = labelOpts.usePointStyle ?
fontSize + (fontSize / 2) + textWidth :
boxWidth + (fontSize / 2) + textWidth,
width = boxWidth + (fontSize / 2) + textWidth,
x = cursor.x,
y = cursor.y;
@@ -421,11 +426,17 @@ module.exports = function(Chart) {
}
},
// Handle an event
/**
* Handle an event
* @private
* @param e {Event} the event to handle
* @return {Boolean} true if a change occured
*/
handleEvent: function(e) {
var me = this;
var opts = me.options;
var type = e.type === 'mouseup' ? 'click' : e.type;
var changed = false;
if (type === 'mousemove') {
if (!opts.onHover) {
@@ -453,14 +464,18 @@ module.exports = function(Chart) {
// Touching an element
if (type === 'click') {
opts.onClick.call(me, e, me.legendItems[i]);
changed = true;
break;
} else if (type === 'mousemove') {
opts.onHover.call(me, e, me.legendItems[i]);
changed = true;
break;
}
}
}
}
return changed;
}
});

View File

@@ -40,7 +40,7 @@ module.exports = function(Chart) {
},
/**
* Remove all registered p^lugins.
* Remove all registered plugins.
* @since 2.1.5
*/
clear: function() {
@@ -57,7 +57,7 @@ module.exports = function(Chart) {
},
/**
* Returns all registered plugin intances.
* Returns all registered plugin instances.
* @returns {Array} array of plugin objects.
* @since 2.1.5
*/

View File

@@ -46,15 +46,13 @@ module.exports = function(Chart) {
autoSkipPadding: 0,
labelOffset: 0,
// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
callback: function(value) {
return helpers.isArray(value) ? value : '' + value;
}
callback: Chart.Ticks.formatters.values
}
};
Chart.Scale = Chart.Element.extend({
// These methods are ordered by lifecyle. Utilities then follow.
// These methods are ordered by lifecycle. Utilities then follow.
// Any function defined here is inherited by all scale types.
// Any function can be extended by the scale type
@@ -169,13 +167,8 @@ module.exports = function(Chart) {
convertTicksToLabels: function() {
var me = this;
// Convert ticks to strings
me.ticks = me.ticks.map(function(numericalTick, index, ticks) {
if (me.options.ticks.userCallback) {
return me.options.ticks.userCallback(numericalTick, index, ticks);
}
return me.options.ticks.callback(numericalTick, index, ticks);
},
me);
var tickOpts = me.options.ticks;
me.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback);
},
afterTickToLabelConversion: function() {
helpers.callCallback(this.options.afterTickToLabelConversion, [this]);
@@ -398,8 +391,8 @@ module.exports = function(Chart) {
if (rawValue === null || typeof(rawValue) === 'undefined') {
return NaN;
}
// isNaN(object) returns true, so make sure NaN is checking for a number
if (typeof(rawValue) === 'number' && isNaN(rawValue)) {
// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values
if (typeof(rawValue) === 'number' && !isFinite(rawValue)) {
return NaN;
}
// If it is in fact an object, dive in one more level
@@ -470,7 +463,7 @@ module.exports = function(Chart) {
0);
},
// Actualy draw the scale on the canvas
// Actually draw the scale on the canvas
// @param {rectangle} chartArea : the area of the chart to draw full grid lines on
draw: function(chartArea) {
var me = this;

202
src/core/core.ticks.js Normal file
View File

@@ -0,0 +1,202 @@
'use strict';
module.exports = function(Chart) {
var helpers = Chart.helpers;
/**
* Namespace to hold static tick generation functions
* @namespace Chart.Ticks
*/
Chart.Ticks = {
/**
* Namespace to hold generators for different types of ticks
* @namespace Chart.Ticks.generators
*/
generators: {
/**
* Interface for the options provided to the numeric tick generator
* @interface INumericTickGenerationOptions
*/
/**
* The maximum number of ticks to display
* @name INumericTickGenerationOptions#maxTicks
* @type Number
*/
/**
* The distance between each tick.
* @name INumericTickGenerationOptions#stepSize
* @type Number
* @optional
*/
/**
* Forced minimum for the ticks. If not specified, the minimum of the data range is used to calculate the tick minimum
* @name INumericTickGenerationOptions#min
* @type Number
* @optional
*/
/**
* The maximum value of the ticks. If not specified, the maximum of the data range is used to calculate the tick maximum
* @name INumericTickGenerationOptions#max
* @type Number
* @optional
*/
/**
* Generate a set of linear ticks
* @method Chart.Ticks.generators.linear
* @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
* @param dataRange {IRange} the range of the data
* @returns {Array<Number>} array of tick values
*/
linear: function(generationOptions, dataRange) {
var ticks = [];
// To get a "nice" value for the tick spacing, we will use the appropriately named
// "nice number" algorithm. See http://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks
// for details.
var spacing;
if (generationOptions.stepSize && generationOptions.stepSize > 0) {
spacing = generationOptions.stepSize;
} else {
var niceRange = helpers.niceNum(dataRange.max - dataRange.min, false);
spacing = helpers.niceNum(niceRange / (generationOptions.maxTicks - 1), true);
}
var niceMin = Math.floor(dataRange.min / spacing) * spacing;
var niceMax = Math.ceil(dataRange.max / spacing) * spacing;
// If min, max and stepSize is set and they make an evenly spaced scale use it.
if (generationOptions.min && generationOptions.max && generationOptions.stepSize) {
var minMaxDeltaDivisibleByStepSize = ((generationOptions.max - generationOptions.min) % generationOptions.stepSize) === 0;
if (minMaxDeltaDivisibleByStepSize) {
niceMin = generationOptions.min;
niceMax = generationOptions.max;
}
}
var numSpaces = (niceMax - niceMin) / spacing;
// If very close to our rounded value, use it.
if (helpers.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {
numSpaces = Math.round(numSpaces);
} else {
numSpaces = Math.ceil(numSpaces);
}
// Put the values into the ticks array
ticks.push(generationOptions.min !== undefined ? generationOptions.min : niceMin);
for (var j = 1; j < numSpaces; ++j) {
ticks.push(niceMin + (j * spacing));
}
ticks.push(generationOptions.max !== undefined ? generationOptions.max : niceMax);
return ticks;
},
/**
* Generate a set of logarithmic ticks
* @method Chart.Ticks.generators.logarithmic
* @param generationOptions {INumericTickGenerationOptions} the options used to generate the ticks
* @param dataRange {IRange} the range of the data
* @returns {Array<Number>} array of tick values
*/
logarithmic: function(generationOptions, dataRange) {
var ticks = [];
var getValueOrDefault = helpers.getValueOrDefault;
// Figure out what the max number of ticks we can support it is based on the size of
// the axis area. For now, we say that the minimum tick spacing in pixels must be 50
// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on
// the graph
var tickVal = getValueOrDefault(generationOptions.min, Math.pow(10, Math.floor(helpers.log10(dataRange.min))));
while (tickVal < dataRange.max) {
ticks.push(tickVal);
var exp;
var significand;
if (tickVal === 0) {
exp = Math.floor(helpers.log10(dataRange.minNotZero));
significand = Math.round(dataRange.minNotZero / Math.pow(10, exp));
} else {
exp = Math.floor(helpers.log10(tickVal));
significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
}
if (significand === 10) {
significand = 1;
++exp;
}
tickVal = significand * Math.pow(10, exp);
}
var lastTick = getValueOrDefault(generationOptions.max, tickVal);
ticks.push(lastTick);
return ticks;
}
},
/**
* Namespace to hold formatters for different types of ticks
* @namespace Chart.Ticks.formatters
*/
formatters: {
/**
* Formatter for value labels
* @method Chart.Ticks.formatters.values
* @param value the value to display
* @return {String|Array} the label to display
*/
values: function(value) {
return helpers.isArray(value) ? value : '' + value;
},
/**
* Formatter for linear numeric ticks
* @method Chart.Ticks.formatters.linear
* @param tickValue {Number} the value to be formatted
* @param index {Number} the position of the tickValue parameter in the ticks array
* @param ticks {Array<Number>} the list of ticks being converted
* @return {String} string representation of the tickValue parameter
*/
linear: function(tickValue, index, ticks) {
// 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) {
if (tickValue !== Math.floor(tickValue)) {
// not an integer
delta = tickValue - Math.floor(tickValue);
}
}
var logDelta = helpers.log10(Math.abs(delta));
var tickString = '';
if (tickValue !== 0) {
var numDecimal = -1 * Math.floor(logDelta);
numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
tickString = tickValue.toFixed(numDecimal);
} else {
tickString = '0'; // never show decimal places for 0
}
return tickString;
},
logarithmic: function(tickValue, index, ticks) {
var remain = tickValue / (Math.pow(10, Math.floor(helpers.log10(tickValue))));
if (tickValue === 0) {
return '0';
} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {
return tickValue.toExponential();
}
return '';
}
}
};
};

View File

@@ -28,7 +28,7 @@ module.exports = function(Chart) {
me.legendHitBoxes = [];
},
// These methods are ordered by lifecyle. Utilities then follow.
// These methods are ordered by lifecycle. Utilities then follow.
beforeUpdate: function() {
var chartOpts = this.chart.options;
@@ -139,7 +139,7 @@ module.exports = function(Chart) {
return pos === 'top' || pos === 'bottom';
},
// Actualy draw the title block on the canvas
// Actually draw the title block on the canvas
draw: function() {
var me = this,
ctx = me.ctx,
@@ -158,7 +158,8 @@ module.exports = function(Chart) {
top = me.top,
left = me.left,
bottom = me.bottom,
right = me.right;
right = me.right,
maxWidth;
ctx.fillStyle = valueOrDefault(opts.fontColor, globalDefaults.defaultFontColor); // render in correct colour
ctx.font = titleFont;
@@ -167,9 +168,11 @@ module.exports = function(Chart) {
if (me.isHorizontal()) {
titleX = left + ((right - left) / 2); // midpoint of the width
titleY = top + ((bottom - top) / 2); // midpoint of the height
maxWidth = right - left;
} else {
titleX = opts.position === 'left' ? left + (fontSize / 2) : right - (fontSize / 2);
titleY = top + ((bottom - top) / 2);
maxWidth = bottom - top;
rotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);
}
@@ -178,7 +181,7 @@ module.exports = function(Chart) {
ctx.rotate(rotation);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(opts.text, 0, 0);
ctx.fillText(opts.text, 0, 0, maxWidth);
ctx.restore();
}
}

View File

@@ -4,10 +4,20 @@ module.exports = function(Chart) {
var helpers = Chart.helpers;
/**
* Helper method to merge the opacity into a color
*/
function mergeOpacity(colorString, opacity) {
var color = helpers.color(colorString);
return color.alpha(opacity * color.alpha()).rgbaString();
}
Chart.defaults.global.tooltips = {
enabled: true,
custom: null,
mode: 'single',
mode: 'nearest',
position: 'average',
intersect: true,
backgroundColor: 'rgba(0,0,0,0.8)',
titleFontStyle: 'bold',
titleSpacing: 2,
@@ -24,11 +34,10 @@ module.exports = function(Chart) {
footerAlign: 'left',
yPadding: 6,
xPadding: 6,
yAlign: 'center',
xAlign: 'center',
caretSize: 5,
cornerRadius: 6,
multiKeyBackground: '#fff',
displayColors: true,
callbacks: {
// Args are: (tooltipItems, data)
beforeTitle: helpers.noop,
@@ -96,40 +105,7 @@ module.exports = function(Chart) {
return base;
}
function getAveragePosition(elements) {
if (!elements.length) {
return false;
}
var i, len;
var xPositions = [];
var yPositions = [];
for (i = 0, len = elements.length; i < len; ++i) {
var el = elements[i];
if (el && el.hasValue()) {
var pos = el.tooltipPosition();
xPositions.push(pos.x);
yPositions.push(pos.y);
}
}
var x = 0,
y = 0;
for (i = 0; i < xPositions.length; ++i) {
if (xPositions[i]) {
x += xPositions[i];
y += yPositions[i];
}
}
return {
x: Math.round(x / xPositions.length),
y: Math.round(y / xPositions.length)
};
}
// Private helper to create a tooltip iteam model
// Private helper to create a tooltip item model
// @param element : the chart element (point, arc, bar) to create the tooltip item for
// @return : new tooltip item
function createTooltipItem(element) {
@@ -142,59 +118,255 @@ module.exports = function(Chart) {
xLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',
yLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',
index: index,
datasetIndex: datasetIndex
datasetIndex: datasetIndex,
x: element._model.x,
y: element._model.y
};
}
/**
* Helper to get the reset model for the tooltip
* @param tooltipOpts {Object} the tooltip options
*/
function getBaseModel(tooltipOpts) {
var globalDefaults = Chart.defaults.global;
var getValueOrDefault = helpers.getValueOrDefault;
return {
// Positioning
xPadding: tooltipOpts.xPadding,
yPadding: tooltipOpts.yPadding,
xAlign: tooltipOpts.xAlign,
yAlign: tooltipOpts.yAlign,
// Body
bodyFontColor: tooltipOpts.bodyFontColor,
_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
_bodyAlign: tooltipOpts.bodyAlign,
bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
bodySpacing: tooltipOpts.bodySpacing,
// Title
titleFontColor: tooltipOpts.titleFontColor,
_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
_titleAlign: tooltipOpts.titleAlign,
titleSpacing: tooltipOpts.titleSpacing,
titleMarginBottom: tooltipOpts.titleMarginBottom,
// Footer
footerFontColor: tooltipOpts.footerFontColor,
_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
_footerAlign: tooltipOpts.footerAlign,
footerSpacing: tooltipOpts.footerSpacing,
footerMarginTop: tooltipOpts.footerMarginTop,
// Appearance
caretSize: tooltipOpts.caretSize,
cornerRadius: tooltipOpts.cornerRadius,
backgroundColor: tooltipOpts.backgroundColor,
opacity: 0,
legendColorBackground: tooltipOpts.multiKeyBackground,
displayColors: tooltipOpts.displayColors
};
}
/**
* Get the size of the tooltip
*/
function getTooltipSize(tooltip, model) {
var ctx = tooltip._chart.ctx;
var height = model.yPadding * 2; // Tooltip Padding
var width = 0;
// Count of all lines in the body
var body = model.body;
var combinedBodyLength = body.reduce(function(count, bodyItem) {
return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
}, 0);
combinedBodyLength += model.beforeBody.length + model.afterBody.length;
var titleLineCount = model.title.length;
var footerLineCount = model.footer.length;
var titleFontSize = model.titleFontSize,
bodyFontSize = model.bodyFontSize,
footerFontSize = model.footerFontSize;
height += titleLineCount * titleFontSize; // Title Lines
height += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing
height += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin
height += combinedBodyLength * bodyFontSize; // Body Lines
height += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing
height += footerLineCount ? model.footerMarginTop : 0; // Footer Margin
height += footerLineCount * (footerFontSize); // Footer Lines
height += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing
// Title width
var widthPadding = 0;
var maxLineWidth = function(line) {
width = Math.max(width, ctx.measureText(line).width + widthPadding);
};
ctx.font = helpers.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);
helpers.each(model.title, maxLineWidth);
// Body width
ctx.font = helpers.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);
helpers.each(model.beforeBody.concat(model.afterBody), maxLineWidth);
// Body lines may include some extra width due to the color box
widthPadding = model.displayColors ? (bodyFontSize + 2) : 0;
helpers.each(body, function(bodyItem) {
helpers.each(bodyItem.before, maxLineWidth);
helpers.each(bodyItem.lines, maxLineWidth);
helpers.each(bodyItem.after, maxLineWidth);
});
// Reset back to 0
widthPadding = 0;
// Footer width
ctx.font = helpers.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);
helpers.each(model.footer, maxLineWidth);
// Add padding
width += 2 * model.xPadding;
return {
width: width,
height: height
};
}
/**
* Helper to get the alignment of a tooltip given the size
*/
function determineAlignment(tooltip, size) {
var model = tooltip._model;
var chart = tooltip._chart;
var chartArea = tooltip._chartInstance.chartArea;
var xAlign = 'center';
var yAlign = 'center';
if (model.y < size.height) {
yAlign = 'top';
} else if (model.y > (chart.height - size.height)) {
yAlign = 'bottom';
}
var lf, rf; // functions to determine left, right alignment
var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (yAlign === 'center') {
lf = function(x) {
return x <= midX;
};
rf = function(x) {
return x > midX;
};
} else {
lf = function(x) {
return x <= (size.width / 2);
};
rf = function(x) {
return x >= (chart.width - (size.width / 2));
};
}
olf = function(x) {
return x + size.width > chart.width;
};
orf = function(x) {
return x - size.width < 0;
};
yf = function(y) {
return y <= midY ? 'top' : 'bottom';
};
if (lf(model.x)) {
xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (olf(model.x)) {
xAlign = 'center';
yAlign = yf(model.y);
}
} else if (rf(model.x)) {
xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (orf(model.x)) {
xAlign = 'center';
yAlign = yf(model.y);
}
}
var opts = tooltip._options;
return {
xAlign: opts.xAlign ? opts.xAlign : xAlign,
yAlign: opts.yAlign ? opts.yAlign : yAlign
};
}
/**
* @Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment
*/
function getBackgroundPoint(vm, size, alignment) {
// Background Position
var x = vm.x;
var y = vm.y;
var caretSize = vm.caretSize,
caretPadding = vm.caretPadding,
cornerRadius = vm.cornerRadius,
xAlign = alignment.xAlign,
yAlign = alignment.yAlign,
paddingAndSize = caretSize + caretPadding,
radiusAndPadding = cornerRadius + caretPadding;
if (xAlign === 'right') {
x -= size.width;
} else if (xAlign === 'center') {
x -= (size.width / 2);
}
if (yAlign === 'top') {
y += paddingAndSize;
} else if (yAlign === 'bottom') {
y -= size.height + paddingAndSize;
} else {
y -= (size.height / 2);
}
if (yAlign === 'center') {
if (xAlign === 'left') {
x += paddingAndSize;
} else if (xAlign === 'right') {
x -= paddingAndSize;
}
} else if (xAlign === 'left') {
x -= radiusAndPadding;
} else if (xAlign === 'right') {
x += radiusAndPadding;
}
return {
x: x,
y: y
};
}
Chart.Tooltip = Chart.Element.extend({
initialize: function() {
var me = this;
var globalDefaults = Chart.defaults.global;
var tooltipOpts = me._options;
var getValueOrDefault = helpers.getValueOrDefault;
helpers.extend(me, {
_model: {
// Positioning
xPadding: tooltipOpts.xPadding,
yPadding: tooltipOpts.yPadding,
xAlign: tooltipOpts.xAlign,
yAlign: tooltipOpts.yAlign,
// Body
bodyFontColor: tooltipOpts.bodyFontColor,
_bodyFontFamily: getValueOrDefault(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),
_bodyFontStyle: getValueOrDefault(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),
_bodyAlign: tooltipOpts.bodyAlign,
bodyFontSize: getValueOrDefault(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),
bodySpacing: tooltipOpts.bodySpacing,
// Title
titleFontColor: tooltipOpts.titleFontColor,
_titleFontFamily: getValueOrDefault(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),
_titleFontStyle: getValueOrDefault(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),
titleFontSize: getValueOrDefault(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),
_titleAlign: tooltipOpts.titleAlign,
titleSpacing: tooltipOpts.titleSpacing,
titleMarginBottom: tooltipOpts.titleMarginBottom,
// Footer
footerFontColor: tooltipOpts.footerFontColor,
_footerFontFamily: getValueOrDefault(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),
_footerFontStyle: getValueOrDefault(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),
footerFontSize: getValueOrDefault(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),
_footerAlign: tooltipOpts.footerAlign,
footerSpacing: tooltipOpts.footerSpacing,
footerMarginTop: tooltipOpts.footerMarginTop,
// Appearance
caretSize: tooltipOpts.caretSize,
cornerRadius: tooltipOpts.cornerRadius,
backgroundColor: tooltipOpts.backgroundColor,
opacity: 0,
legendColorBackground: tooltipOpts.multiKeyBackground
}
});
this._model = getBaseModel(this._options);
},
// Get the title
@@ -271,25 +443,55 @@ module.exports = function(Chart) {
update: function(changed) {
var me = this;
var opts = me._options;
var model = me._model;
// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition
// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time
// which breaks any animations.
var existingModel = me._model;
var model = me._model = getBaseModel(opts);
var active = me._active;
var data = me._data;
var chartInstance = me._chartInstance;
// In the case where active.length === 0 we need to keep these at existing values for good animations
var alignment = {
xAlign: existingModel.xAlign,
yAlign: existingModel.yAlign
};
var backgroundPoint = {
x: existingModel.x,
y: existingModel.y
};
var tooltipSize = {
width: existingModel.width,
height: existingModel.height
};
var tooltipPosition = {
x: existingModel.caretX,
y: existingModel.caretY
};
var i, len;
if (active.length) {
model.opacity = 1;
var labelColors = [],
tooltipPosition = getAveragePosition(active);
var labelColors = [];
tooltipPosition = Chart.Tooltip.positioners[opts.position](active, me._eventPosition);
var tooltipItems = [];
for (i = 0, len = active.length; i < len; ++i) {
tooltipItems.push(createTooltipItem(active[i]));
}
// If the user provided a filter function, use it to modify the tooltip items
if (opts.filter) {
tooltipItems = tooltipItems.filter(function(a) {
return opts.filter(a, data);
});
}
// If the user provided a sorting function, use it to modify the tooltip items
if (opts.itemSort) {
tooltipItems = tooltipItems.sort(function(a, b) {
@@ -297,209 +499,55 @@ module.exports = function(Chart) {
});
}
// If there is more than one item, show color items
if (active.length > 1) {
helpers.each(tooltipItems, function(tooltipItem) {
labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));
});
}
// Build the Text Lines
helpers.extend(model, {
title: me.getTitle(tooltipItems, data),
beforeBody: me.getBeforeBody(tooltipItems, data),
body: me.getBody(tooltipItems, data),
afterBody: me.getAfterBody(tooltipItems, data),
footer: me.getFooter(tooltipItems, data),
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
labelColors: labelColors
// Determine colors for boxes
helpers.each(tooltipItems, function(tooltipItem) {
labelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, chartInstance));
});
// We need to determine alignment of
var tooltipSize = me.getTooltipSize(model);
me.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
// Build the Text Lines
model.title = me.getTitle(tooltipItems, data);
model.beforeBody = me.getBeforeBody(tooltipItems, data);
model.body = me.getBody(tooltipItems, data);
model.afterBody = me.getAfterBody(tooltipItems, data);
model.footer = me.getFooter(tooltipItems, data);
helpers.extend(model, me.getBackgroundPoint(model, tooltipSize));
// Initial positioning and colors
model.x = Math.round(tooltipPosition.x);
model.y = Math.round(tooltipPosition.y);
model.caretPadding = helpers.getValueOrDefault(tooltipPosition.padding, 2);
model.labelColors = labelColors;
// data points
model.dataPoints = tooltipItems;
// We need to determine alignment of the tooltip
tooltipSize = getTooltipSize(this, model);
alignment = determineAlignment(this, tooltipSize);
// Final Size and Position
backgroundPoint = getBackgroundPoint(model, tooltipSize, alignment);
} else {
me._model.opacity = 0;
model.opacity = 0;
}
model.xAlign = alignment.xAlign;
model.yAlign = alignment.yAlign;
model.x = backgroundPoint.x;
model.y = backgroundPoint.y;
model.width = tooltipSize.width;
model.height = tooltipSize.height;
// Point where the caret on the tooltip points to
model.caretX = tooltipPosition.x;
model.caretY = tooltipPosition.y;
me._model = model;
if (changed && opts.custom) {
opts.custom.call(me, model);
}
return me;
},
getTooltipSize: function(vm) {
var ctx = this._chart.ctx;
var size = {
height: vm.yPadding * 2, // Tooltip Padding
width: 0
};
// Count of all lines in the body
var body = vm.body;
var combinedBodyLength = body.reduce(function(count, bodyItem) {
return count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;
}, 0);
combinedBodyLength += vm.beforeBody.length + vm.afterBody.length;
var titleLineCount = vm.title.length;
var footerLineCount = vm.footer.length;
var titleFontSize = vm.titleFontSize,
bodyFontSize = vm.bodyFontSize,
footerFontSize = vm.footerFontSize;
size.height += titleLineCount * titleFontSize; // Title Lines
size.height += (titleLineCount - 1) * vm.titleSpacing; // Title Line Spacing
size.height += titleLineCount ? vm.titleMarginBottom : 0; // Title's bottom Margin
size.height += combinedBodyLength * bodyFontSize; // Body Lines
size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
size.height += footerLineCount ? vm.footerMarginTop : 0; // Footer Margin
size.height += footerLineCount * (footerFontSize); // Footer Lines
size.height += footerLineCount ? (footerLineCount - 1) * vm.footerSpacing : 0; // Footer Line Spacing
// Title width
var widthPadding = 0;
var maxLineWidth = function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width + widthPadding);
};
ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
helpers.each(vm.title, maxLineWidth);
// Body width
ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
helpers.each(vm.beforeBody.concat(vm.afterBody), maxLineWidth);
// Body lines may include some extra width due to the color box
widthPadding = body.length > 1 ? (bodyFontSize + 2) : 0;
helpers.each(body, function(bodyItem) {
helpers.each(bodyItem.before, maxLineWidth);
helpers.each(bodyItem.lines, maxLineWidth);
helpers.each(bodyItem.after, maxLineWidth);
});
// Reset back to 0
widthPadding = 0;
// Footer width
ctx.font = helpers.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(vm.footer, maxLineWidth);
// Add padding
size.width += 2 * vm.xPadding;
return size;
},
determineAlignment: function(size) {
var me = this;
var model = me._model;
var chart = me._chart;
var chartArea = me._chartInstance.chartArea;
if (model.y < size.height) {
model.yAlign = 'top';
} else if (model.y > (chart.height - size.height)) {
model.yAlign = 'bottom';
}
var lf, rf; // functions to determine left, right alignment
var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
var midX = (chartArea.left + chartArea.right) / 2;
var midY = (chartArea.top + chartArea.bottom) / 2;
if (model.yAlign === 'center') {
lf = function(x) {
return x <= midX;
};
rf = function(x) {
return x > midX;
};
} else {
lf = function(x) {
return x <= (size.width / 2);
};
rf = function(x) {
return x >= (chart.width - (size.width / 2));
};
}
olf = function(x) {
return x + size.width > chart.width;
};
orf = function(x) {
return x - size.width < 0;
};
yf = function(y) {
return y <= midY ? 'top' : 'bottom';
};
if (lf(model.x)) {
model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (olf(model.x)) {
model.xAlign = 'center';
model.yAlign = yf(model.y);
}
} else if (rf(model.x)) {
model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (orf(model.x)) {
model.xAlign = 'center';
model.yAlign = yf(model.y);
}
}
},
getBackgroundPoint: function(vm, size) {
// Background Position
var pt = {
x: vm.x,
y: vm.y
};
var caretSize = vm.caretSize,
caretPadding = vm.caretPadding,
cornerRadius = vm.cornerRadius,
xAlign = vm.xAlign,
yAlign = vm.yAlign,
paddingAndSize = caretSize + caretPadding,
radiusAndPadding = cornerRadius + caretPadding;
if (xAlign === 'right') {
pt.x -= size.width;
} else if (xAlign === 'center') {
pt.x -= (size.width / 2);
}
if (yAlign === 'top') {
pt.y += paddingAndSize;
} else if (yAlign === 'bottom') {
pt.y -= size.height + paddingAndSize;
} else {
pt.y -= (size.height / 2);
}
if (yAlign === 'center') {
if (xAlign === 'left') {
pt.x += paddingAndSize;
} else if (xAlign === 'right') {
pt.x -= paddingAndSize;
}
} else if (xAlign === 'left') {
pt.x -= radiusAndPadding;
} else if (xAlign === 'right') {
pt.x += radiusAndPadding;
}
return pt;
},
drawCaret: function(tooltipPoint, size, opacity) {
var vm = this._view;
var ctx = this._chart.ctx;
@@ -555,8 +603,7 @@ module.exports = function(Chart) {
}
}
var bgColor = helpers.color(vm.backgroundColor);
ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
@@ -574,8 +621,7 @@ module.exports = function(Chart) {
var titleFontSize = vm.titleFontSize,
titleSpacing = vm.titleSpacing;
var titleFontColor = helpers.color(vm.titleFontColor);
ctx.fillStyle = titleFontColor.alpha(opacity * titleFontColor.alpha()).rgbString();
ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
var i, len;
@@ -597,8 +643,7 @@ module.exports = function(Chart) {
ctx.textAlign = vm._bodyAlign;
ctx.textBaseline = 'top';
var bodyFontColor = helpers.color(vm.bodyFontColor);
var textColor = bodyFontColor.alpha(opacity * bodyFontColor.alpha()).rgbString();
var textColor = mergeOpacity(vm.bodyFontColor, opacity);
ctx.fillStyle = textColor;
ctx.font = helpers.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
@@ -612,7 +657,7 @@ module.exports = function(Chart) {
// Before body lines
helpers.each(vm.beforeBody, fillLineOfText);
var drawColorBoxes = body.length > 1;
var drawColorBoxes = vm.displayColors;
xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
// Draw body lines now
@@ -623,15 +668,15 @@ module.exports = function(Chart) {
// Draw Legend-like boxes if needed
if (drawColorBoxes) {
// Fill a white rect so that colours merge nicely if the opacity is < 1
ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
// Border
ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
// Inner square
ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
ctx.fillStyle = textColor;
@@ -659,8 +704,7 @@ module.exports = function(Chart) {
ctx.textAlign = vm._footerAlign;
ctx.textBaseline = 'top';
var footerFontColor = helpers.color(vm.footerFontColor);
ctx.fillStyle = footerFontColor.alpha(opacity * footerFontColor.alpha()).rgbString();
ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(footer, function(line) {
@@ -669,6 +713,11 @@ module.exports = function(Chart) {
});
}
},
drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
ctx.fill();
},
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
@@ -677,7 +726,10 @@ module.exports = function(Chart) {
return;
}
var tooltipSize = this.getTooltipSize(vm);
var tooltipSize = {
width: vm.width,
height: vm.height
};
var pt = {
x: vm.x,
y: vm.y
@@ -688,10 +740,7 @@ module.exports = function(Chart) {
if (this._options.enabled) {
// Draw Background
var bgColor = helpers.color(vm.backgroundColor);
ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
ctx.fill();
this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
// Draw Caret
this.drawCaret(pt, tooltipSize, opacity);
@@ -709,6 +758,120 @@ module.exports = function(Chart) {
// Footer
this.drawFooter(pt, vm, ctx, opacity);
}
},
/**
* Handle an event
* @private
* @param e {Event} the event to handle
* @returns {Boolean} true if the tooltip changed
*/
handleEvent: function(e) {
var me = this;
var options = me._options;
var changed = false;
me._lastActive = me._lastActive || [];
// Find Active Elements for tooltips
if (e.type === 'mouseout') {
me._active = [];
} else {
me._active = me._chartInstance.getElementsAtEventForMode(e, options.mode, options);
}
// Remember Last Actives
changed = !helpers.arrayEquals(me._active, me._lastActive);
me._lastActive = me._active;
if (options.enabled || options.custom) {
me._eventPosition = helpers.getRelativePosition(e, me._chart);
var model = me._model;
me.update(true);
me.pivot();
// See if our tooltip position changed
changed |= (model.x !== me._model.x) || (model.y !== me._model.y);
}
return changed;
}
});
/**
* @namespace Chart.Tooltip.positioners
*/
Chart.Tooltip.positioners = {
/**
* Average mode places the tooltip at the average position of the elements shown
* @function Chart.Tooltip.positioners.average
* @param elements {ChartElement[]} the elements being displayed in the tooltip
* @returns {Point} tooltip position
*/
average: function(elements) {
if (!elements.length) {
return false;
}
var i, len;
var x = 0;
var y = 0;
var count = 0;
for (i = 0, len = elements.length; i < len; ++i) {
var el = elements[i];
if (el && el.hasValue()) {
var pos = el.tooltipPosition();
x += pos.x;
y += pos.y;
++count;
}
}
return {
x: Math.round(x / count),
y: Math.round(y / count)
};
},
/**
* Gets the tooltip position nearest of the item nearest to the event position
* @function Chart.Tooltip.positioners.nearest
* @param elements {Chart.Element[]} the tooltip elements
* @param eventPosition {Point} the position of the event in canvas coordinates
* @returns {Point} the tooltip position
*/
nearest: function(elements, eventPosition) {
var x = eventPosition.x;
var y = eventPosition.y;
var nearestElement;
var minDistance = Number.POSITIVE_INFINITY;
var i, len;
for (i = 0, len = elements.length; i < len; ++i) {
var el = elements[i];
if (el && el.hasValue()) {
var center = el.getCenterPoint();
var d = helpers.distanceBetweenPoints(eventPosition, center);
if (d < minDistance) {
minDistance = d;
nearestElement = el;
}
}
}
if (nearestElement) {
var tp = nearestElement.tooltipPosition();
x = tp.x;
y = tp.y;
}
return {
x: x,
y: y
};
}
};
};

View File

@@ -52,6 +52,19 @@ module.exports = function(Chart) {
}
return false;
},
getCenterPoint: function() {
var vm = this._view;
var halfAngle = (vm.startAngle + vm.endAngle) / 2;
var halfRadius = (vm.innerRadius + vm.outerRadius) / 2;
return {
x: vm.x + Math.cos(halfAngle) * halfRadius,
y: vm.y + Math.sin(halfAngle) * halfRadius
};
},
getArea: function() {
var vm = this._view;
return Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));
},
tooltipPosition: function() {
var vm = this._view;

View File

@@ -15,7 +15,7 @@ module.exports = function(Chart) {
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
capBezierPoints: true,
fill: true // do we fill in the area between the line and its base axis
fill: true, // do we fill in the area between the line and its base axis
};
Chart.elements.Line = Chart.Element.extend({
@@ -23,9 +23,18 @@ module.exports = function(Chart) {
var me = this;
var vm = me._view;
var spanGaps = vm.spanGaps;
var scaleZero = vm.scaleZero;
var fillPoint = vm.scaleZero;
var loop = me._loop;
// Handle different fill modes for cartesian lines
if (!loop) {
if (vm.fill === 'top') {
fillPoint = vm.scaleTop;
} else if (vm.fill === 'bottom') {
fillPoint = vm.scaleBottom;
}
}
var ctx = me._chart.ctx;
ctx.save();
@@ -71,9 +80,9 @@ module.exports = function(Chart) {
// First point moves to it's starting position no matter what
if (index === 0) {
if (loop) {
ctx.moveTo(scaleZero.x, scaleZero.y);
ctx.moveTo(fillPoint.x, fillPoint.y);
} else {
ctx.moveTo(currentVM.x, scaleZero);
ctx.moveTo(currentVM.x, fillPoint);
}
if (!currentVM.skip) {
@@ -87,9 +96,9 @@ module.exports = function(Chart) {
// Only do this if this is the first point that is skipped
if (!spanGaps && lastDrawnIndex === (index - 1)) {
if (loop) {
ctx.lineTo(scaleZero.x, scaleZero.y);
ctx.lineTo(fillPoint.x, fillPoint.y);
} else {
ctx.lineTo(previous._view.x, scaleZero);
ctx.lineTo(previous._view.x, fillPoint);
}
}
} else {
@@ -102,7 +111,7 @@ module.exports = function(Chart) {
} else if (loop) {
ctx.lineTo(currentVM.x, currentVM.y);
} else {
ctx.lineTo(currentVM.x, scaleZero);
ctx.lineTo(currentVM.x, fillPoint);
ctx.lineTo(currentVM.x, currentVM.y);
}
} else {
@@ -115,7 +124,7 @@ module.exports = function(Chart) {
}
if (!loop && lastDrawnIndex !== -1) {
ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
ctx.lineTo(points[lastDrawnIndex]._view.x, fillPoint);
}
ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;

View File

@@ -18,14 +18,35 @@ module.exports = function(Chart) {
hoverBorderWidth: 1
};
function xRange(mouseX) {
var vm = this._view;
return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
}
function yRange(mouseY) {
var vm = this._view;
return vm ? (Math.pow(mouseY - vm.y, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
}
Chart.elements.Point = Chart.Element.extend({
inRange: function(mouseX, mouseY) {
var vm = this._view;
return vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;
},
inLabelRange: function(mouseX) {
inLabelRange: xRange,
inXRange: xRange,
inYRange: yRange,
getCenterPoint: function() {
var vm = this._view;
return vm ? (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2)) : false;
return {
x: vm.x,
y: vm.y
};
},
getArea: function() {
return Math.PI * Math.pow(this._view.radius, 2);
},
tooltipPosition: function() {
var vm = this._view;

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