Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

09-Advanced.md 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. ---
  2. title: Advanced usage
  3. anchor: advanced-usage
  4. ---
  5. ### Prototype Methods
  6. For each chart, there are a set of global prototype methods on the shared `ChartType` which you may find useful. These are available on all charts created with Chart.js, but for the examples, let's use a line chart we've made.
  7. ```javascript
  8. // For example:
  9. var myLineChart = new Chart(ctx, config);
  10. ```
  11. #### .destroy()
  12. 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.
  13. This must be called before the canvas is reused for a new chart.
  14. ```javascript
  15. // Destroys a specific chart instance
  16. myLineChart.destroy();
  17. ```
  18. #### .update(duration, lazy)
  19. 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.
  20. ```javascript
  21. // duration is the time for the animation of the redraw in miliseconds
  22. // lazy is a boolean. if true, the animation can be interupted by other animations
  23. myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
  24. myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
  25. ```
  26. #### .render(duration, lazy)
  27. Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use `.update()` in that case.
  28. ```javascript
  29. // duration is the time for the animation of the redraw in miliseconds
  30. // lazy is a boolean. if true, the animation can be interupted by other animations
  31. myLineChart.render(duration, lazy);
  32. ```
  33. #### .stop()
  34. Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.
  35. ```javascript
  36. // Stops the charts animation loop at its current frame
  37. myLineChart.stop();
  38. // => returns 'this' for chainability
  39. ```
  40. #### .resize()
  41. 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.
  42. ```javascript
  43. // Resizes & redraws to fill its container element
  44. myLineChart.resize();
  45. // => returns 'this' for chainability
  46. ```
  47. #### .clear()
  48. Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
  49. ```javascript
  50. // Will clear the canvas that myLineChart is drawn on
  51. myLineChart.clear();
  52. // => returns 'this' for chainability
  53. ```
  54. #### .toBase64Image()
  55. This returns a base 64 encoded string of the chart in it's current state.
  56. ```javascript
  57. myLineChart.toBase64Image();
  58. // => returns png data url of the image on the canvas
  59. ```
  60. #### .generateLegend()
  61. Returns an HTML string of a legend for that chart. The legend is generated from the `legendCallback` in the options.
  62. ```javascript
  63. myLineChart.generateLegend();
  64. // => returns HTML string of a legend for this chart
  65. ```
  66. #### .getElementAtEvent(e)
  67. 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
  68. ```javascript
  69. myLineChart.getElementAtEvent(e);
  70. // => returns the first element at the event point.
  71. ```
  72. #### .getElementsAtEvent(e)
  73. 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.
  74. 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.
  75. ```javascript
  76. canvas.onclick = function(evt){
  77. var activePoints = myLineChart.getElementsAtEvent(evt);
  78. // => activePoints is an array of points on the canvas that are at the same position as the click event.
  79. };
  80. ```
  81. This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
  82. #### .getDatasetAtEvent(e)
  83. Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting
  84. ```javascript
  85. myLineChart.getDatasetAtEvent(e);
  86. // => returns an array of elements
  87. ```
  88. ### External Tooltips
  89. You can enable custom tooltips in the global or chart configuration like so:
  90. ```javascript
  91. var myPieChart = new Chart(ctx, {
  92. type: 'pie',
  93. data: data,
  94. options: {
  95. tooltips: {
  96. custom: function(tooltip) {
  97. // tooltip will be false if tooltip is not visible or should be hidden
  98. if (!tooltip) {
  99. return;
  100. }
  101. // Otherwise, tooltip will be an object with all tooltip properties like:
  102. // tooltip.caretSize
  103. // tooltip.caretPadding
  104. // tooltip.chart
  105. // tooltip.cornerRadius
  106. // tooltip.fillColor
  107. // tooltip.font...
  108. // tooltip.text
  109. // tooltip.x
  110. // tooltip.y
  111. // etc...
  112. }
  113. }
  114. }
  115. });
  116. ```
  117. See `sample/line-customTooltips.html` for examples on how to get started.
  118. ### Writing New Scale Types
  119. Starting with Chart.js 2.0 scales can be individually extended. Scales should always derive from Chart.Scale.
  120. ```javascript
  121. var MyScale = Chart.Scale.extend({
  122. /* extensions ... */
  123. });
  124. // MyScale is now derived from Chart.Scale
  125. ```
  126. 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.
  127. ```javascript
  128. Chart.scaleService.registerScaleType('myScale', MyScale, defaultConfigObject);
  129. ```
  130. To use the new scale, simply pass in the string key to the config when creating a chart.
  131. ```javascript
  132. var lineChart = new Chart(ctx, {
  133. data: data,
  134. type: 'line',
  135. options: {
  136. scales: {
  137. yAxes: [{
  138. type: 'myScale' // this is the same key that was passed to the registerScaleType function
  139. }]
  140. }
  141. }
  142. })
  143. ```
  144. #### Scale Properties
  145. Scale instances are given the following properties during the fitting process.
  146. ```javascript
  147. {
  148. left: Number, // left edge of the scale bounding box
  149. right: Number, // right edge of the bounding box'
  150. top: Number,
  151. bottom: Number,
  152. width: Number, // the same as right - left
  153. height: Number, // the same as bottom - top
  154. // Margin on each side. Like css, this is outside the bounding box.
  155. margins: {
  156. left: Number,
  157. right: Number,
  158. top: Number,
  159. bottom: Number,
  160. },
  161. // Amount of padding on the inside of the bounding box (like CSS)
  162. paddingLeft: Number,
  163. paddingRight: Number,
  164. paddingTop: Number,
  165. paddingBottom: Number,
  166. }
  167. ```
  168. #### Scale Interface
  169. To work with Chart.js, custom scale types must implement the following interface.
  170. ```javascript
  171. {
  172. // Determines the data limits. Should set this.min and this.max to be the data max/min
  173. determineDataLimits: function() {},
  174. // Generate tick marks. this.chart is the chart instance. The data object can be accessed as this.chart.data
  175. // buildTicks() should create a ticks array on the axis instance, if you intend to use any of the implementations from the base class
  176. buildTicks: function() {},
  177. // 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]
  178. getLabelForIndex: function(index, datasetIndex) {},
  179. // Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value
  180. // @param index: index into the ticks array
  181. // @param includeOffset: if true, get the pixel halway between the given tick and the next
  182. getPixelForTick: function(index, includeOffset) {},
  183. // Get the pixel (x coordinate for horizontal axis, y coordinate for vertical axis) for a given value
  184. // @param value : the value to get the pixel for
  185. // @param index : index into the data array of the value
  186. // @param datasetIndex : index of the dataset the value comes from
  187. // @param includeOffset : if true, get the pixel halway between the given tick and the next
  188. getPixelForValue: function(value, index, datasetIndex, includeOffset) {}
  189. // Get the value for a given pixel (x coordinate for horizontal axis, y coordinate for vertical axis)
  190. // @param pixel : pixel value
  191. getValueForPixel: function(pixel) {}
  192. }
  193. ```
  194. Optionally, the following methods may also be overwritten, but an implementation is already provided by the `Chart.Scale` base class.
  195. ```javascript
  196. // Transform the ticks array of the scale instance into strings. The default implementation simply calls this.options.ticks.callback(numericalTick, index, ticks);
  197. convertTicksToLabels: function() {},
  198. // Determine how much the labels will rotate by. The default implementation will only rotate labels if the scale is horizontal.
  199. calculateTickRotation: function() {},
  200. // Fits the scale into the canvas.
  201. // 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.
  202. // 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
  203. // You must set this.minSize to be the size of your scale. It must be an object containing 2 properties: width and height.
  204. // You must set this.width to be the width and this.height to be the height of the scale
  205. fit: function() {},
  206. // 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
  207. // @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.
  208. draw: function(chartArea) {},
  209. ```
  210. The Core.Scale base class also has some utility functions that you may find useful.
  211. ```javascript
  212. {
  213. // Returns true if the scale instance is horizontal
  214. isHorizontal: function() {},
  215. // Get the correct value from the value from this.chart.data.datasets[x].data[]
  216. // If dataValue is an object, returns .x or .y depending on the return of isHorizontal()
  217. // If the value is undefined, returns NaN
  218. // Otherwise returns the value.
  219. // Note that in all cases, the returned value is not guaranteed to be a Number
  220. getRightValue: function(dataValue) {},
  221. }
  222. ```
  223. ### Writing New Chart Types
  224. Chart.js 2.0 introduces the concept of controllers for each dataset. Like scales, new controllers can be written as needed.
  225. ```javascript
  226. Chart.controllers.MyType = Chart.DatasetController.extend({
  227. });
  228. // Now we can create a new instance of our chart, using the Chart.js API
  229. new Chart(ctx, {
  230. // this is the string the constructor was registered at, ie Chart.controllers.MyType
  231. type: 'MyType',
  232. data: data,
  233. options: options
  234. });
  235. ```
  236. #### Dataset Controller Interface
  237. Dataset controllers must implement the following interface.
  238. ```javascript
  239. {
  240. // Create elements for each piece of data in the dataset. Store elements in an array on the dataset as dataset.metaData
  241. addElements: function() {},
  242. // Create a single element for the data at the given index and reset its state
  243. addElementAndReset: function(index) {},
  244. // Draw the representation of the dataset
  245. // @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
  246. draw: function(ease) {},
  247. // Remove hover styling from the given element
  248. removeHoverStyle: function(element) {},
  249. // Add hover styling to the given element
  250. setHoverStyle: function(element) {},
  251. // Update the elements in response to new data
  252. // @param reset : if true, put the elements into a reset state so they can animate to their final values
  253. update: function(reset) {},
  254. }
  255. ```
  256. The following methods may optionally be overridden by derived dataset controllers
  257. ```javascript
  258. {
  259. // Initializes the controller
  260. initialize: function(chart, datasetIndex) {},
  261. // 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
  262. // chart types using a single scale
  263. linkScales: function() {},
  264. // 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.
  265. buildOrUpdateElements: function() {}
  266. }
  267. ```
  268. ### Extending Existing Chart Types
  269. Extending or replacing an existing controller type is easy. Simply replace the constructor for one of the built in types with your own.
  270. The built in controller types are:
  271. * `Chart.controllers.line`
  272. * `Chart.controllers.bar`
  273. * `Chart.controllers.radar`
  274. * `Chart.controllers.doughnut`
  275. * `Chart.controllers.polarArea`
  276. * `Chart.controllers.bubble`
  277. #### Bar Controller
  278. 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.
  279. ### Creating Plugins
  280. Starting with v2.1.0, you can create plugins for chart.js. To register your plugin, simply call `Chart.pluginService.register` and pass your plugin in.
  281. Plugins will be called at the following times
  282. * Start of initialization
  283. * End of initialization
  284. * Start of update
  285. * After the chart scales have calculated
  286. * Start of datasets update
  287. * End of datasets update
  288. * End of update (before render occurs)
  289. * Start of draw
  290. * End of draw
  291. * Before datasets draw
  292. * After datasets draw
  293. * Resize
  294. * Before an animation is started
  295. Plugins should derive from Chart.PluginBase and implement the following interface
  296. ```javascript
  297. {
  298. beforeInit: function(chartInstance) { },
  299. afterInit: function(chartInstance) { },
  300. resize: function(chartInstance, newChartSize) { },
  301. beforeUpdate: function(chartInstance) { },
  302. afterScaleUpdate: function(chartInstance) { }
  303. beforeDatasetsUpdate: function(chartInstance) { }
  304. afterDatasetsUpdate: function(chartInstance) { }
  305. afterUpdate: function(chartInstance) { },
  306. // This is called at the start of a render. It is only called once, even if the animation will run for a number of frames. Use beforeDraw or afterDraw
  307. // to do something on each animation frame
  308. beforeRender: function(chartInstance) { },
  309. // Easing is for animation
  310. beforeDraw: function(chartInstance, easing) { },
  311. afterDraw: function(chartInstance, easing) { },
  312. // Before the datasets are drawn but after scales are drawn
  313. beforeDatasetsDraw: function(chartInstance, easing) { },
  314. afterDatasetsDraw: function(chartInstance, easing) { },
  315. destroy: function(chartInstance) { }
  316. }
  317. ```
  318. ### Building Chart.js
  319. Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.
  320. 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:
  321. ```bash
  322. npm install
  323. npm install -g gulp
  324. ```
  325. 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>.
  326. Now, we can run the `gulp build` task.
  327. ```bash
  328. gulp build
  329. ```