diff --git a/js/ui/chart/docs/developers/charts.md b/js/ui/chart/docs/developers/charts.md new file mode 100644 index 0000000..bf63b5f --- /dev/null +++ b/js/ui/chart/docs/developers/charts.md @@ -0,0 +1,116 @@ +# New Charts + +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, { + // this is the string the constructor was registered at, ie Chart.controllers.MyType + type: 'MyType', + data: data, + options: options +}); +``` + +## Dataset Controller Interface + +Dataset controllers must implement the following interface. + +```javascript +{ + // 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) {}, + + // 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) {} +} +``` + +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() {}, + + // 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() {} +} +``` + +## Extending Existing Chart Types + +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` + +For example, to derive a new chart type that extends from a bubble chart, you would do the following. + +```javascript +// Sets the default config for 'derivedBubble' to be the same as the bubble defaults. +// We look for the defaults by doing Chart.defaults[chartType] +// It looks like a bug exists when the defaults don't exist +Chart.defaults.derivedBubble = Chart.defaults.bubble; + +// I think the recommend using Chart.controllers.bubble.extend({ extensions here }); +var custom = Chart.controllers.bubble.extend({ + draw: function(ease) { + // Call super method first + Chart.controllers.bubble.prototype.draw.call(this, ease); + + // Now we can do some custom drawing for this dataset. Here we'll draw a red box around the first point in each dataset + var meta = this.getMeta(); + var pt0 = meta.data[0]; + var radius = pt0._view.radius; + + var ctx = this.chart.chart.ctx; + ctx.save(); + ctx.strokeStyle = 'red'; + ctx.lineWidth = 1; + ctx.strokeRect(pt0._view.x - radius, pt0._view.y - radius, 2 * radius, 2 * radius); + ctx.restore(); + } +}); + +// Stores the controller so that the chart initialization routine can look it up with +// Chart.controllers[type] +Chart.controllers.derivedBubble = custom; + +// Now we can create and use our new chart type +new Chart(ctx, { + type: 'derivedBubble', + data: data, + options: options +}); +``` + +### Bar Controller +The bar controller has a special property that you should be aware of. To correctly calculate the width of a bar, the controller must determine the number of datasets that map to bars. To do this, the bar controller attaches a property `bar` to the dataset during initialization. If you are creating a replacement or updated bar controller, you should do the same. This will ensure that charts with regular bars and your new derived bars will work seamlessly.