New Charts

Chart.js 2.0 introduces the concept of controllers for each dataset. Like scales, new controllers can be written as needed.

  1. Chart.controllers.MyType = Chart.DatasetController.extend({
  2. });
  3. // Now we can create a new instance of our chart, using the Chart.js API
  4. new Chart(ctx, {
  5. // this is the string the constructor was registered at, ie Chart.controllers.MyType
  6. type: 'MyType',
  7. data: data,
  8. options: options
  9. });

Dataset Controller Interface

Dataset controllers must implement the following interface.

  1. {
  2. // Create elements for each piece of data in the dataset. Store elements in an array on the dataset as dataset.metaData
  3. addElements: function() {},
  4. // Create a single element for the data at the given index and reset its state
  5. addElementAndReset: function(index) {},
  6. // Draw the representation of the dataset
  7. // @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
  8. draw: function(ease) {},
  9. // Remove hover styling from the given element
  10. removeHoverStyle: function(element) {},
  11. // Add hover styling to the given element
  12. setHoverStyle: function(element) {},
  13. // Update the elements in response to new data
  14. // @param reset : if true, put the elements into a reset state so they can animate to their final values
  15. update: function(reset) {}
  16. }

The following methods may optionally be overridden by derived dataset controllers.

  1. {
  2. // Initializes the controller
  3. initialize: function(chart, datasetIndex) {},
  4. // 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
  5. // chart types using a single scale
  6. linkScales: function() {},
  7. // 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.
  8. buildOrUpdateElements: function() {}
  9. }

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.
  1. // Sets the default config for 'derivedBubble' to be the same as the bubble defaults.
  2. // We look for the defaults by doing Chart.defaults[chartType]
  3. // It looks like a bug exists when the defaults don't exist
  4. Chart.defaults.derivedBubble = Chart.defaults.bubble;
  5. // I think the recommend using Chart.controllers.bubble.extend({ extensions here });
  6. var custom = Chart.controllers.bubble.extend({
  7. draw: function(ease) {
  8. // Call super method first
  9. Chart.controllers.bubble.prototype.draw.call(this, ease);
  10. // Now we can do some custom drawing for this dataset. Here we'll draw a red box around the first point in each dataset
  11. var meta = this.getMeta();
  12. var pt0 = meta.data[0];
  13. var radius = pt0._view.radius;
  14. var ctx = this.chart.chart.ctx;
  15. ctx.save();
  16. ctx.strokeStyle = 'red';
  17. ctx.lineWidth = 1;
  18. ctx.strokeRect(pt0._view.x - radius, pt0._view.y - radius, 2 * radius, 2 * radius);
  19. ctx.restore();
  20. }
  21. });
  22. // Stores the controller so that the chart initialization routine can look it up with
  23. // Chart.controllers[type]
  24. Chart.controllers.derivedBubble = custom;
  25. // Now we can create and use our new chart type
  26. new Chart(ctx, {
  27. type: 'derivedBubble',
  28. data: data,
  29. options: options
  30. });

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.