### Example usage
```javascript
-new Chart(ctx).PolarArea(data, options);
+new Chart(ctx, {
+ data:data,
+ type: 'polarArea',
+ options: options
+});
```
### Data structure
```javascript
-var data = [
- {
- value: 300,
- color:"#F7464A",
- highlight: "#FF5A5E",
- label: "Red"
- },
- {
- value: 50,
- color: "#46BFBD",
- highlight: "#5AD3D1",
- label: "Green"
- },
- {
- value: 100,
- color: "#FDB45C",
- highlight: "#FFC870",
- label: "Yellow"
- },
- {
- value: 40,
- color: "#949FB1",
- highlight: "#A8B3C5",
- label: "Grey"
- },
- {
- value: 120,
- color: "#4D5360",
- highlight: "#616774",
- label: "Dark Grey"
- }
-
-];
+var data = {
+ datasets: [{
+ data: [
+ 10,
+ 32,
+ 53,
+ 14,
+ 22,
+ ],
+ backgroundColor: [
+ "#F7464A",
+ "#46BFBD",
+ "#FDB45C",
+ "#949FB1",
+ "#4D5360",
+ ],
+ label: 'My dataset' // for legend
+ }],
+ labels: [
+ "Red",
+ "Green",
+ "Yellow",
+ "Grey",
+ "Dark Grey"
+ ]
+};
```
As you can see, for the chart data you pass in an array of objects, with a value and a colour. The value attribute should be a number, while the color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#getting-started-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*scale*.lineArc | Boolean | true | When true, lines are circular.
-*animation*.animateRotate | Boolean |true | If true, will animate the rotation of the chart.
-*animation*.animateScale | Boolean | true | If true, will animate scaling the chart.
+animateRotate | Boolean |true | If true, will animate the rotation of the chart.
+animateScale | Boolean | true | If true, will animate scaling the chart.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
*legend*.onClick | Function | function(event, legendItem) {} ` | Handles clicking an individual legend item
+legendCallback | Function | `function(chart) ` | Generates the HTML legend via calls to `generateLegend`
You can override these for your `Chart` instance by passing a second argument into the `PolarArea` method as an object with the keys you want to override.
For example, we could have a polar area chart with a black stroke on each segment like so:
```javascript
-new Chart(ctx).PolarArea(data, {
- segmentStrokeColor: "#000000"
+new Chart(ctx, {
+ data: data,
+ type: 'polarArea',
+ options: {
+ elements: {
+ arc: {
+ borderColor: "#000000"
+ }
+ }
+ }
});
// This will create a chart with all of the default options, merged from the global config,
-// and the PolarArea chart defaults but this particular instance will have `segmentStrokeColor` set to `"#000000"`.
+// and the PolarArea chart defaults but this particular instance will have `elements.arc.borderColor` set to `"#000000"`.
```
-We can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.PolarArea`.
-
-### Prototype methods
-
-#### .getSegmentsAtEvent( event )
-
-Calling `getSegmentsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the segment elements that are at that the same position of that event.
-
-```javascript
-canvas.onclick = function(evt){
- var activePoints = myPolarAreaChart.getSegmentsAtEvent(evt);
- // => activePoints is an array of segments on the canvas that are at the same position as the click event.
-};
-```
-
-This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
-
-#### .update( )
-
-Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
-
-```javascript
-myPolarAreaChart.segments[1].value = 10;
-// Would update the first dataset's value of 'Green' to be 10
-myPolarAreaChart.update();
-// Calling update now animates the position of Green from 50 to 10.
-```
-
-#### .addData( segmentData, index )
-
-Calling `addData(segmentData, index)` on your Chart instance passing an object in the same format as in the constructor. There is an option second argument of 'index', this determines at what index the new segment should be inserted into the chart.
-
-```javascript
-// An object in the same format as the original data source
-myPolarAreaChart.addData({
- value: 130,
- color: "#B48EAD",
- highlight: "#C69CBE",
- label: "Purple"
-});
-// The new segment will now animate in.
-```
-
-#### .removeData( index )
-
-Calling `removeData(index)` on your Chart instance will remove segment at that particular index. If none is provided, it will default to the last segment.
-
-```javascript
-myPolarAreaChart.removeData();
-// Other segments will update to fill the empty space left.
-```
+We can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.polarArea`.
```javascript
// For example:
-var myLineChart = new Chart(ctx).Line(data);
+var myLineChart = new Chart(ctx, config);
```
-#### .clear()
+#### .destroy()
-Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
+Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js.
+This must be called before the canvas is reused for a new chart.
```javascript
-// Will clear the canvas that myLineChart is drawn on
-myLineChart.clear();
-// => returns 'this' for chainability
+// Destroys a specific chart instance
+myLineChart.destroy();
+```
+
+#### .update(duration, lazy)
+
+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
+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.
+```
+
+#### .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
+myLineChart.render(duration, lazy);
```
#### .stop()
#### .resize()
-Use this to manually resize the canvas element. This is run each time the browser is resized, but you can call this method manually if you change the size of the canvas nodes container element.
+Use this to manually resize the canvas element. This is run each time the canvas container is resized, but you can call this method manually if you change the size of the canvas nodes container element.
```javascript
// Resizes & redraws to fill its container element
// => returns 'this' for chainability
```
-#### .destroy()
+#### .clear()
-Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js.
+Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
```javascript
-// Destroys a specific chart instance
-myLineChart.destroy();
+// Will clear the canvas that myLineChart is drawn on
+myLineChart.clear();
+// => returns 'this' for chainability
```
#### .toBase64Image()
#### .generateLegend()
-Returns an HTML string of a legend for that chart. The template for this legend is at `legendTemplate` in the chart options.
+Returns an HTML string of a legend for that chart. The legend is generated from the `legendCallback` in the options.
```javascript
myLineChart.generateLegend();
// => returns HTML string of a legend for this chart
```
+#### .getElementAtEvent(e)
+
+Calling `getElementAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the single element at the event position. If there are multiple items within range, only the first is returned
+
+```javscript
+myLineChart.getElementAtEvent(e);
+// => returns the first element at the event point.
+```
+
+#### .getElementsAtEvent(e)
+
+Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting.
+
+Calling `getElementsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
+
+```javascript
+canvas.onclick = function(evt){
+ var activePoints = myLineChart.getElementsAtEvent(evt);
+ // => activePoints is an array of points on the canvas that are at the same position as the click event.
+};
+```
+
+This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
+
+#### .getDatasetAtEvent(e)
+
+Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting
+
+```javascript
+myLineChart.getDatasetAtEvent(e);
+// => returns an array of elements
+```
+
### External Tooltips
You can enable custom tooltips in the global or chart configuration like so:
```javascript
-var myPieChart = new Chart(ctx).Pie(data, {
- customTooltips: function(tooltip) {
+var myPieChart = new Chart(ctx, {
+ type: 'pie',
+ data: data,
+ options: {
+ tooltips: {
+ custom: function(tooltip) {
+ // tooltip will be false if tooltip is not visible or should be hidden
+ if (!tooltip) {
+ return;
+ }
+
+ // Otherwise, tooltip will be an object with all tooltip properties like:
+
+ // tooltip.caretHeight
+ // tooltip.caretPadding
+ // tooltip.chart
+ // tooltip.cornerRadius
+ // tooltip.fillColor
+ // tooltip.font...
+ // tooltip.text
+ // tooltip.x
+ // tooltip.y
+ // etc...
+ }
+ }
+ }
+});
+```
- // tooltip will be false if tooltip is not visible or should be hidden
- if (!tooltip) {
- return;
- }
+See `sample/line-customTooltips.html` for examples on how to get started.
- // Otherwise, tooltip will be an object with all tooltip properties like:
+### Writing new scale types
- // tooltip.caretHeight
- // tooltip.caretPadding
- // tooltip.chart
- // tooltip.cornerRadius
- // tooltip.fillColor
- // tooltip.font...
- // tooltip.text
- // tooltip.x
- // tooltip.y
- // etc...
+Starting with Chart.js 2.0 scales can be individually extended. Scales should always derive from Chart.Scale.
- };
+```javascript
+var MyScale = Chart.Scale.extend({
+ /* extensions ... */
});
+
+// MyScale is now derived from Chart.Scale
```
-See files `sample/pie-customTooltips.html` and `sample/line-customTooltips.html` for examples on how to get started.
+Once you have created your scale class, you need to register it with the global chart object so that it can be used. A default config for the scale may be provided when registering the constructor. The first parameter to the register function is a string key that is used later to identify which scale type to use for a chart.
+```javascript
+Chart.scaleService.registerScaleType('myScale', MyScale, defaultConfigObject);
+```
-### Writing new chart types
+To use the new scale, simply pass in the string key to the config when creating a chart.
-Chart.js 1.0 has been rewritten to provide a platform for developers to create their own custom chart types, and be able to share and utilise them through the Chart.js API.
+```javascript
+var lineChart = new Chart(ctx, {
+ data: data,
+ type: 'line',
+ options: {
+ scales: {
+ yAxes: [{
+ type: 'myScale' // this is the same key that was passed to the registerScaleType function
+ }]
+ }
+ }
+})
+```
-The format is relatively simple, there are a set of utility helper methods under `Chart.helpers`, including things such as looping over collections, requesting animation frames, and easing equations.
+#### Scale Properties
-On top of this, there are also some simple base classes of Chart elements, these all extend from `Chart.Element`, and include things such as points, bars and scales.
+Scale instances are given the following properties during the fitting process.
```javascript
-Chart.Type.extend({
- // Passing in a name registers this chart in the Chart namespace
- name: "Scatter",
- // Providing a defaults will also register the deafults in the chart namespace
- defaults : {
- options: "Here",
- available: "at this.options"
- },
- // Initialize is fired when the chart is initialized - Data is passed in as a parameter
- // Config is automatically merged by the core of Chart.js, and is available at this.options
- initialize: function(data){
- this.chart.ctx // The drawing context for this chart
- this.chart.canvas // the canvas node for this chart
+{
+ left: Number, // left edge of the scale bounding box
+ right: Number, // right edge of the bounding box'
+ 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.
+ margins: {
+ left: Number,
+ right: Number,
+ top: Number,
+ bottom: Number,
},
- // Used to draw something on the canvas
- draw: function() {
- }
+
+ // Amount of padding on the inside of the bounding box (like CSS)
+ paddingLeft: Number,
+ paddingRight: Number,
+ paddingTop: Number,
+ paddingBottom: Number,
+}
+```
+
+#### Scale Interface
+To work with Chart.js, custom scale types must implement the following interface.
+
+```javascript
+{
+ // Generate tick marks. this.chart is the chart instance. The data object can be accessed as this.chart.data
+ // buildTicks() should create a ticks array on the scale instance, if you intend to use any of the implementations from the base class
+ buildTicks: function() {},
+
+ // Get the value to show for the data at the given index of the the given dataset, ie this.chart.data.datasets[datasetIndex].data[index]
+ getLabelForIndex: function(index, datasetIndex) {},
+
+ // Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
+ // @param index: index into the ticks array
+ // @param includeOffset: if true, get the pixel halway between the given tick and the next
+ getPixelForTick: function(index, includeOffset) {},
+
+ // Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
+ // @param value : the value to get the pixel for
+ // @param index : index into the data array of the value
+ // @param datasetIndex : index of the dataset the value comes from
+ // @param includeOffset : if true, get the pixel halway between the given tick and the next
+ getPixelForValue: function(value, index, datasetIndex, includeOffset) {}
+}
+```
+
+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);
+ convertTicksToLabels: function() {},
+
+ // 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.
+ // this.maxWidth and this.maxHeight will tell you the maximum dimensions the scale instance can be. Scales should endeavour to be as efficient as possible with canvas space.
+ // this.margins is the amount of space you have on either side of your scale that you may expand in to. This is used already for calculating the best label rotation
+ // You must set this.minSize to be the size of your scale. It must be an object containing 2 properties: width and height.
+ // You must set this.width to be the width and this.height to be the height of the scale
+ fit: function() {},
+
+ // Draws the scale onto the canvas. this.(left|right|top|bottom) will have been populated to tell you the area on the canvas to draw in
+ // @param chartArea : an object containing four properties: left, right, top, bottom. This is the rectangle that lines, bars, etc will be drawn in. It may be used, for example, to draw grid lines.
+ draw: function(chartArea) {},
+```
+
+The Core.Scale base class also has some utility functions that you may find useful.
+```javscript
+{
+ // Returns true if the scale instance is horizontal
+ isHorizontal: function(){},
+
+ // Get the correct value from the value from this.chart.data.datasets[x].data[]
+ // If dataValue is an object, returns .x or .y depending on the return of isHorizontal()
+ // If the value is undefined, returns NaN
+ // Otherwise returns the value.
+ // Note that in all cases, the returned value is not guaranteed to be a Number
+ getRightValue: function(dataValue){},
+}
+```
+
+### Writing new chart types
+
+Chart.js 2.0 introduces the concept of controllers for each dataset. Like scales, new controllers can be written as needed.
+
+```javascript
+Chart.controllers.MyType = Chart.DatasetController.extend({
+
});
+
// Now we can create a new instance of our chart, using the Chart.js API
-new Chart(ctx).Scatter(data);
-// initialize is now run
+new Chart(ctx, {
+ // this is the string the constructor was registered at, ie Chart.controllers.MyType
+ type: 'MyType',
+ data: data,
+ options: options
+});
```
-### Extending existing chart types
+#### Dataset Controller Interface
-We can also extend existing chart types, and expose them to the API in the same way. Let's say for example, we might want to run some more code when we initialize every Line chart.
+Dataset controllers must implement the following interface.
```javascript
-// Notice now we're extending the particular Line chart type, rather than the base class.
-Chart.types.Line.extend({
- // Passing in a name registers this chart in the Chart namespace in the same way
- name: "LineAlt",
- initialize: function(data){
- console.log('My Line chart extension');
- Chart.types.Line.prototype.initialize.apply(this, arguments);
- }
-});
+{
+ // Create elements for each piece of data in the dataset. Store elements in an array on the dataset as dataset.metaData
+ addElements: function() {},
+
+ // Create a single element for the data at the given index and reset its state
+ addElementAndReset: function(index) {},
+
+ // Draw the representation of the dataset
+ // @param ease : if specified, this number represents how far to transition elements. See the implementation of draw() in any of the provided controllers to see how this should be used
+ draw: function(ease) {},
-// Creates a line chart in the same way
-new Chart(ctx).LineAlt(data);
-// but this logs 'My Line chart extension' in the console.
+ // Remove hover styling from the given element
+ removeHoverStyle: function(element) {},
+
+ // Add hover styling to the given element
+ setHoverStyle: function(element) {},
+
+ // Update the elements in response to new data
+ // @param reset : if true, put the elements into a reset state so they can animate to their final values
+ update: function(reset) {},
+}
```
-### Community extensions
+The following methods may optionally be overridden by derived dataset controllers
+```javascript
+{
+ // Initializes the controller
+ initialize: function(chart, datasetIndex) {},
+
+ // Ensures that the dataset represented by this controller is linked to a scale. Overridden to helpers.noop in the polar area and doughnut controllers as these
+ // chart types using a single scale
+ linkScales: function() {},
-- <a href="https://github.com/Regaddi/Chart.StackedBar.js" target="_blank">Stacked Bar Chart</a> by <a href="https://twitter.com/Regaddi" target="_blank">@Regaddi</a>
-- <a href="https://github.com/tannerlinsley/Chart.StackedArea.js" target="_blank">Stacked Bar Chart</a> by <a href="https://twitter.com/tannerlinsley" target="_blank">@tannerlinsley</a>
-- <a href="https://github.com/CAYdenberg/Chart.js" target="_blank">Error bars (bar and line charts)</a> by <a href="https://twitter.com/CAYdenberg" target="_blank">@CAYdenberg</a>
-- <a href="http://dima117.github.io/Chart.Scatter/" target="_blank">Scatter chart (number & date scales are supported)</a> by <a href="https://github.com/dima117" target="_blank">@dima117</a>
+ // 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() {}
+}
+```
-### Creating custom builds
+### Extending existing chart types
-Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file. We can use this same build script with custom parameters in order to build a custom version.
+Extending or replacing an existing controller type is easy. Simply replace the constructor for one of the built in types with your own.
+
+The built in controller types are:
+* `Chart.controllers.line`
+* `Chart.controllers.bar`
+* `Chart.controllers.radar`
+* `Chart.controllers.doughnut`
+* `Chart.controllers.polarArea`
+* `Chart.controllers.bubble`
+
+### Building Chart.js
+
+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:
This will install the local development dependencies for Chart.js, along with a CLI for the JavaScript task runner <a href="http://gulpjs.com/" target="_blank">gulp</a>.
-Now, we can run the `gulp build` task, and pass in a comma seperated list of types as an argument to build a custom version of Chart.js with only specified chart types.
-
-Here we will create a version of Chart.js with only Line, Radar and Bar charts included:
+Now, we can run the `gulp build` task.
```bash
-gulp build --types=Line,Radar,Bar
+gulp build
```
-
-This will output to the `/custom` directory, and write two files, Chart.js, and Chart.min.js with only those chart types included.