Comparar commits

..

127 Commits

Autor SHA1 Mensagem Data
etimberg a62537a800 bump and build for 1.1.1 release 2016-04-05 18:27:27 -04:00
Evert Timberg 4495b63d0a Merge pull request #2220 from TAGraves/master
Fixed a bug with calculating the canvas width and height
2016-04-05 09:47:25 -04:00
Tommy Graves 75ce567d05 Fixed a bug with calculating the canvas width and height
A previous commit removing a workaround for an old Firefox bug left part
of that workaround in, and it was preventing the expected behavior of
the canvas size being equal to the offsetWidth and offsetHeight of the
canvas prior to instantiation of Chart.JS
2016-04-05 08:28:46 -04:00
Evert Timberg ae103c3d0f Merge pull request #2218 from eemikula/master
Change legendTemplates to use separate spans for text and icon.
2016-04-04 19:49:03 -04:00
Eric Mikula 1ccb100739 Change legendTemplates to use separate spans for text and icon.
This addresses the issue in #2192 without entirely reverting #886. Note that it still may cause confusing behavior for some legends: Specifically, the example on chartjs.org styles ".doughnut-legend li span" with a fixed width, and therefore both of the new spans will be impacted by this styling. However, now two spans are generated instead. %name%-legend-icon is used for the color icon, and %name%-legend-text can be used for styling the text. This should be described in release notes.
2016-04-04 18:22:25 -04:00
Evert Timberg 09efe9e6e2 Merge pull request #2214 from eemikula/master
Changing object type check to prevent errors when undefined. Fixes #2213
2016-04-03 15:33:12 -04:00
Eric Mikula 31b883f815 Changing object type check to prevent errors when undefined. Fixes #2213 2016-04-03 15:19:21 -04:00
Nick Downie ef923dfe28 Update package + built files to 1.1.0 version 2016-04-01 17:03:30 +01:00
etimberg 3f73433831 Fixes #2185
Undoes the merge of #1334
2016-03-29 19:41:13 -04:00
Evert Timberg d7117bc792 Add title of license to license file. Fixes #2097 2016-03-13 10:20:24 -04:00
Evert Timberg cf767f71a2 Merge pull request #2093 from aaron-em/angleLineInterval
Add angleLineInterval option
2016-03-13 10:09:43 -04:00
Aaron Miller 668b532fbe Add angleLineInterval option to radar chart 2016-03-13 09:59:19 -04:00
Evert Timberg 6507f5c087 Merge pull request #2118 from davidcochrum/master
Fix multi-dataset bar highlighting and bar highlight color logic
2016-03-11 13:29:30 -05:00
David Cochrum 131b18059a Update Chart.js 2016-03-11 12:21:45 -05:00
David Cochrum 48c082b04a Fix multi-dataset bar highlighting and bar highlight color logic 2016-03-11 12:19:12 -05:00
David Cochrum cf47543243 Fix multi-dataset bar highlighting and bar highlight color logic 2016-03-11 12:16:43 -05:00
Evert Timberg 3f2119526d Fix #2102 2016-03-06 19:03:03 -05:00
Evert Timberg d17c76ea1a Merge pull request #2090 from aaron-em/patch-1
Mention that 1.x is feature-complete
2016-03-02 16:24:35 -05:00
Aaron Miller af3bcd5cfe Mention that 1.x is feature-complete
It'll help would-be contributors (such as myself, see #2058) avoid creating PRs that won't be accepted.
2016-03-02 16:20:23 -05:00
Evert Timberg ea0d93c970 Merge pull request #1070 from mackuba/stop_animations
Stop animations when destroying a chart
2016-02-27 15:46:05 -05:00
Evert Timberg 43606d1faa Merge pull request #1334 from thePanz/patch-2
Fix error in generateLegend() function
2016-02-20 13:29:32 -05:00
William Entriken 6009b00f74 Merge pull request #1886 from coolbombom/patch-4
having differnt colors in one dataset
2016-02-20 13:11:16 -05:00
Derek Perkins 8d6209271b Add link to slack invite 2016-02-19 21:21:26 -07:00
Evert Timberg 57753b8280 update to new gulp and new uglify version. 2016-02-15 19:22:55 -05:00
Evert Timberg 111ada730c Fix typo in docs. Fixes #1042 2016-02-15 16:42:23 -05:00
Evert Timberg 4aa274d5b2 Default multiTooltipTemplate now shows the dataset label + updated built files. Fixes #612 2016-02-15 14:43:34 -05:00
Evert Timberg 4f4f804a71 Use a named define to fix #768 2016-02-15 14:38:11 -05:00
Evert Timberg d4917afba9 Update git ignore to make it easier to switch between branches. Add code climate config here as well. 2016-02-14 15:15:17 -05:00
etimberg 37883689ad Fixes #1144 with an update to the docs to indicate that labels are required for each point 2016-02-07 19:58:15 -05:00
etimberg cf0b550a80 Check to ensure dom node exists when calculating size. Fixes #919 2016-02-07 19:23:54 -05:00
coolbombom 3f658555ba I will try again!
had a bad effect on color that was not array .... fully tested now, is working in my solution!
2016-01-11 12:48:09 +01:00
coolbombom 1f1e6b4e44 minor update, missed a small detail sorry!!!
missed a small detail, resolved in an error, sorry!
2016-01-11 12:17:08 +01:00
coolbombom 3ac54b8790 having differnt colors in one dataset
Hi updated the bar chart so the bars can have different colors in one dataset!

cheers
c_bb
2016-01-11 12:02:32 +01:00
Evert Timberg 126e318fef Update built files 2016-01-09 10:59:52 -05:00
Evert Timberg 1d3cb8ec41 Merge pull request #1875 from michaelarnauts/master
Ignore null values when calculating scale
2016-01-09 09:40:07 -05:00
Michaël Arnauts 57bd8c7715 Ignore null values when calculating scale 2016-01-09 12:04:29 +01:00
Evert Timberg 104143672b Merge pull request #1874 from Parent5446/patch-1
Added documentation about tooltip templates
2016-01-08 23:49:32 -05:00
Tyler Romeo c5f141306f Added documentation about tooltip templates
It can be a little unclear what the actual format for tooltip templates are. Added information concerning how the tooltip templates are evaluated, and what context, i.e., variables, is available inside of them.
2016-01-08 20:02:45 -08:00
Evert Timberg 299c4b3ae1 Update readme for latest v2 beta release 2016-01-01 12:56:08 -05:00
Evert Timberg cea557849a Merge pull request #1844 from zachpanz88/patch-2
Bump copyright year in license
2015-12-31 16:41:26 -05:00
Zach Panzarino 12a35b5d7b Bump copyright year in license 2015-12-31 15:41:36 -05:00
etimberg cfa6eb1289 Update built files 2015-12-27 12:10:07 -05:00
Evert Timberg 92d4d989f5 Merge pull request #1834 from damiansilbergleithcunniff/issue-1764-default-pie-chart-colors
Issue 1764: Add default colors for Pie Charts
2015-12-27 12:08:33 -05:00
Damian Silbergleith Cunniff cebbca67d1 Choose a "better" set of 12 default colors/highlight colors for pie charts 2015-12-27 09:14:15 -07:00
Damian Silbergleith Cunniff c47e4c1da1 Change reference to index to prevent running off the end of the array 2015-12-26 15:36:15 -07:00
Damian Silbergleith Cunniff b06344563d spaces -> tabs 2015-12-26 10:04:29 -07:00
Damian Silbergleith Cunniff 77185993df fix spaces -> tabs 2015-12-26 10:01:06 -07:00
Damian Silbergleith Cunniff fd2344dd5f Update the docs to reflect the new feature 2015-12-26 09:47:59 -07:00
Damian Silbergleith Cunniff e949edacf5 Update the pie chart to use the default color/highlight if none is specified 2015-12-26 09:41:31 -07:00
Damian Silbergleith Cunniff a868a2f61e Add default global values for Color and Highlight color 2015-12-26 09:34:43 -07:00
Evert Timberg ee6aabaffc Merge pull request #1302 from jantimon/master
More robust in-between arc calculation see #1301
2015-12-25 17:44:26 -05:00
Evert Timberg 69695235ac Merge pull request #1771 from ryoon/recent-firefox
Remove Firefox workaround
2015-12-25 13:39:21 -05:00
Evert Timberg 5cdd7a0893 Merge pull request #1141 from kirkstrobeck/gulp-watch
Add livereload to Gulp  task
2015-12-24 23:17:29 -05:00
Evert Timberg f63debe2c7 Merge pull request #1040 from dima117/master
fix multiTooltip appearance with empty title
2015-12-24 21:50:18 -05:00
William Entriken 3c6a736413 Merge pull request #1192 from kkirsche/patch-1
Remove moot `version` property from bower.json
2015-12-21 16:05:38 -05:00
Ryo ONODERA e94bd460a7 Remove Firefox workaround
The workaround for older Firefox should be removed, because latest
supported Firefox 38.4.0/42.0 do not require it.
And it has side effect like #1198 or my problem on Kintone on cybozu.com.
2015-12-12 09:00:12 +09:00
Evert Timberg 4297672424 Merge pull request #1092 from tannerlinsley/negative-arcs-fix
Only draw positive radius arcs Fixes #592
2015-11-16 21:17:46 -05:00
William Entriken 07aa9473f1 Typo: consistent capitalization 2015-11-16 18:11:22 -05:00
Jake 2e9c3d3109 Merge pull request #1621 from jakesyl/add-composer
Add Composer file
2015-11-08 14:37:41 -05:00
Jake a5e382ab8a add composer file
add composer file
2015-11-05 13:36:04 -05:00
Jake 4476c698c5 Merge pull request #1589 from zachpanz88/patch-1
Change license link
2015-11-04 13:07:25 -05:00
Evert Timberg 257da76b4c Merge pull request #1190 from Nek-/patch-1
Added ignore section
2015-11-01 17:16:22 -05:00
Evert Timberg a169e5ad41 Merge pull request #1262 from mattclegg/master
Call onAnimationComplete when reached last frame
2015-11-01 17:11:24 -05:00
Zach Panzarino 682545e1e3 Change license link
The link to the license now points to the direct license that applies for chart.js, rather than a generic MIT license
2015-10-28 21:22:41 -04:00
Tanner Linsley 69e886ad5b Update README.md 2015-10-26 12:44:48 -06:00
Tanner Linsley 249ca0cef7 Update README.md 2015-10-26 12:43:50 -06:00
Tanner Linsley f1a3fb2361 Merge pull request #1577 from yanarchy/patch-1
Add npm info to getting started doc.
2015-10-26 12:42:54 -06:00
Yan Fan b87106c181 Add npm info to getting started doc. 2015-10-26 11:41:01 -07:00
Tanner Linsley b4856d2e24 Update README.md 2015-10-24 18:07:26 -06:00
Tanner Linsley a68c53cf1e Update README.md 2015-10-24 18:06:59 -06:00
Tanner Linsley 891bd63ac7 Update README.md 2015-10-24 18:06:36 -06:00
Tanner Linsley 70b437b41a Update README.md 2015-10-24 18:05:24 -06:00
Tanner Linsley 07b1758c2e Update README.md 2015-10-24 17:56:28 -06:00
Tanner Linsley 55235ef03c Update README.md 2015-10-24 17:55:34 -06:00
Tanner Linsley dfdd865508 Update README.md 2015-10-24 17:43:51 -06:00
Tanner Linsley c11145bb2d Update README.md 2015-10-24 17:37:18 -06:00
Tanner Linsley 9c39d47bc7 Update README.md 2015-10-24 17:26:10 -06:00
Tanner Linsley 0510ba4139 Update README.md 2015-09-30 12:06:26 -06:00
Tanner Linsley 85e6d1ae71 Added Current 2.0 release to Readme 2015-09-30 11:59:09 -06:00
Tanner Linsley 322abd4361 Merge pull request #1476 from nnnick/v1.0-readme-update
Update v1.x readme to reflect release status
2015-09-24 22:34:00 -06:00
Tanner Linsley f992ddd0d7 Update README.md 2015-09-24 22:33:05 -06:00
Tanner Linsley 407eb846d0 Update v1.x readme to reflect release status 2015-09-21 14:28:10 -06:00
Evert Timberg dd4a67e85c Merge pull request #1067 from rvaidya/master
Added a scaleBackgroundColors configuration option for radar charts, to...
2015-09-17 17:28:00 -04:00
Evert Timberg 7fcd4dcae8 Merge pull request #1450 from nlzet/fix-legend-template-doc
Fix span closed before appending the label
2015-09-14 18:44:04 -04:00
NLZ13 8481811110 Fix span closed before appending the label 2015-09-13 00:33:51 +02:00
Evert Timberg c38e852b61 Merge pull request #1449 from bgvianyc/master
adding template language reference to docs
2015-09-12 11:10:40 -04:00
Barry Gitarts b601e2c2a1 adding template language reference to docs 2015-09-12 09:02:26 -04:00
Evert Timberg b41ba24fff Merge pull request #1439 from bengesoff/patch-2
fixed very small typo
2015-09-04 13:49:49 -04:00
Ben Gesoff 8983929f18 fixed very small typo
wrong it's
2015-09-04 17:08:58 +01:00
Tanner Linsley 2fff73f9e3 Merge pull request #1397 from coolbombom/patch-3
Fix scale error before animation complete
2015-08-28 16:29:30 -06:00
Tanner Linsley 1ae2884a04 Merge pull request #1402 from hrniels/tooltip
Added tooltipTitleTemplate option.
2015-08-28 16:28:11 -06:00
Evert Timberg 2b9a575d4d Merge pull request #1389 from ericjperry/fix/datasetStroke
The datasetStroke option has been fixed for line graphs
2015-08-22 09:39:20 -04:00
Evert Timberg 41fb914952 Merge pull request #1390 from internalfx/patch-1
Closes #1309
2015-08-22 09:38:03 -04:00
Nils Asmussen a14309d95f Added tooltipTitleTemplate option. 2015-08-22 13:47:01 +02:00
coolbombom 80ba5aa1c5 error thrown
error thrown (TypeError: this.scale is undefined) if destroy is called before animation is complete, this update fix this error!
2015-08-21 10:53:52 +02:00
Internalfx ac5bf729c5 Closes #1309
Doughnut.addData() broken for index of 0 #1309
2015-08-18 18:39:11 -07:00
Eric Perry 3f77eb83b2 The datasetStroke option has been fixed for line graphs 2015-08-18 17:56:19 -04:00
Evert Timberg ac360b8dd1 Merge pull request #1382 from bengesoff/patch-1
fixed two typos
2015-08-18 10:42:11 -04:00
Ben Gesoff c276c3a974 fixed two typos
wrong it's
2015-08-17 16:37:01 +01:00
Ema Panz d7ee18372a Fix error in generateLegend() function 2015-07-25 17:32:58 +02:00
Tanner Linsley 43f19359a9 Merge pull request #1308 from eunicekokor/patch-1
Update 00-Getting-Started.md
2015-07-22 11:32:08 -06:00
Evert Timberg f56a7db8fc Merge pull request #1181 from paulmasson/master
Update CDN link
2015-07-18 08:01:29 -04:00
eunice 804fcea46a Update 00-Getting-Started.md
Closes a small issue I found while going through the documentation https://github.com/nnnick/Chart.js/issues/1307
2015-07-13 17:45:27 -07:00
Jan Nicklas 0bb3a9b024 Fix typo 2015-07-10 11:53:35 +02:00
Jan Nicklas 961fd11098 More robust in-between arc calculation see #1301 2015-07-10 11:47:48 +02:00
Evert Timberg 66cf8ab787 Merge pull request #1268 from klaemo/patch-1
add license to package.json
2015-07-01 09:04:44 -04:00
Clemens Stolle 79b02bcf26 add license to package.json
just to be a good npm citizen :)
2015-07-01 11:03:00 +02:00
mattclegg d5f1738a3f Merge branch 'master' of github.com:nnnick/Chart.js
# By Amir E. Aharoni
# Via Amir E. Aharoni (1) and Evert Timberg (1)
* 'master' of github.com:nnnick/Chart.js:
  Fix the spelling of "separate"
2015-06-30 11:13:37 +01:00
mattclegg f7e3962087 Call onAnimationComplete when reached last frame 2015-06-30 11:13:30 +01:00
Evert Timberg 1367a234ee Merge pull request #1241 from amire80/spelling
Fix the spelling of "separate"
2015-06-22 18:12:38 -04:00
Amir E. Aharoni 02616b9f17 Fix the spelling of "separate" 2015-06-23 01:01:59 +03:00
Kevin Kirsche 3d389d7c09 Remove moot version property from bower.json
Per bower/bower.json-spec@a325da3
2015-06-10 18:25:22 -04:00
Maxime Veber 28d30b4f5b Added ignore section 2015-06-10 22:32:23 +02:00
paulmasson d1cccd3546 Update CDN link 2015-06-08 16:45:47 -07:00
kirkstrobeck 8db79ae365 nnnick/Chart.js#1140: Watch sample folder 2015-05-27 18:28:45 -07:00
kirkstrobeck 8ef3aaa87d Add livereload to Gulp task 2015-05-27 18:07:01 -07:00
Evert Timberg e093fdf572 Merge pull request #1127 from leighquince/fix/radar-datasetfill-option
fix for radar chart ignoring datasetFill option
2015-05-20 17:54:17 -04:00
Leigh Quince 73b0d587ba fix for radar chart ignoring datasetFill option 2015-05-20 21:53:30 +02:00
Evert Timberg 2ce4291e98 Merge pull request #1122 from ismeta/fix-span-tag
Fixes #886 - Close span tags properly in legend generation template.
2015-05-16 08:37:38 -04:00
Vanessa Ung 598a6f3485 Fixes #886 - Close span tags properly in legend generation template. 2015-05-16 15:31:56 +10:00
Tanner Linsley b8691c9581 Revert "Merge pull request #856 from tannerlinsley/editable-chart-config"
This reverts commit a8063de6b8, reversing
changes made to 7f513b87ee.
2015-05-11 18:57:14 -06:00
Tanner Linsley 1df2b37bc5 Only draw positive radius arcs Fixes #592 2015-04-30 15:49:52 -06:00
Kuba Suder 66f7f96d4b stop animations when destroying a chart
otherwise the animation keeps updating the chart for some time after it
was supposed to be destroyed, and when the canvas might have been
already reused for a new chart
2015-04-16 22:41:53 +02:00
Rahul Vaidya d91c4a14e9 Decouple radar chart background colors from angle line drawing so they can be passed separately. 2015-04-16 11:36:49 -07:00
Rahul Vaidya 9eedf9adb6 For radar chart background colors, don't recalculate center offset multiple times. Verify that background color count is same as axes count. 2015-04-16 11:26:21 -07:00
Rahul Vaidya 7045fdbb5a Added a scaleBackgroundColors configuration option for Radial charts, to add a background color for each axis in the chart. 2015-04-16 09:22:31 -07:00
dima117 ca7a39232a fix multiTooltip appearance with empty title
https://github.com/nnnick/Chart.js/issues/1039
2015-04-03 22:19:34 +03:00
116 arquivos alterados com 8898 adições e 27740 exclusões
+19
Ver Arquivo
@@ -0,0 +1,19 @@
---
engines:
duplication:
enabled: true
config:
languages:
- javascript
eslint:
enabled: true
fixme:
enabled: true
ratings:
paths:
- "**.js"
exclude_paths:
- dist/
- node_modules/
- test/
- coverage/
+1
Ver Arquivo
@@ -0,0 +1 @@
**/*{.,-}min.js
+213
Ver Arquivo
@@ -0,0 +1,213 @@
ecmaFeatures:
modules: true
jsx: true
env:
amd: true
browser: true
es6: true
jquery: true
node: true
# http://eslint.org/docs/rules/
rules:
# Possible Errors
comma-dangle: [2, never]
no-cond-assign: 2
no-console: 0
no-constant-condition: 2
no-control-regex: 2
no-debugger: 2
no-dupe-args: 2
no-dupe-keys: 2
no-duplicate-case: 2
no-empty: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 2
no-extra-parens: 0
no-extra-semi: 2
no-func-assign: 2
no-inner-declarations: [2, functions]
no-invalid-regexp: 2
no-irregular-whitespace: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-regex-spaces: 2
no-sparse-arrays: 2
no-unexpected-multiline: 2
no-unreachable: 2
use-isnan: 2
valid-jsdoc: 0
valid-typeof: 2
# Best Practices
accessor-pairs: 2
block-scoped-var: 0
complexity: [2, 6]
consistent-return: 0
curly: 0
default-case: 0
dot-location: 0
dot-notation: 0
eqeqeq: 2
guard-for-in: 2
no-alert: 2
no-caller: 2
no-case-declarations: 2
no-div-regex: 2
no-else-return: 0
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
no-extend-native: 2
no-extra-bind: 2
no-fallthrough: 2
no-floating-decimal: 0
no-implicit-coercion: 0
no-implied-eval: 2
no-invalid-this: 0
no-iterator: 2
no-labels: 0
no-lone-blocks: 2
no-loop-func: 2
no-magic-number: 0
no-multi-spaces: 0
no-multi-str: 0
no-native-reassign: 2
no-new-func: 2
no-new-wrappers: 2
no-new: 2
no-octal-escape: 2
no-octal: 2
no-proto: 2
no-redeclare: 2
no-return-assign: 2
no-script-url: 2
no-self-compare: 2
no-sequences: 0
no-throw-literal: 0
no-unused-expressions: 2
no-useless-call: 2
no-useless-concat: 2
no-void: 2
no-warning-comments: 0
no-with: 2
radix: 2
vars-on-top: 0
wrap-iife: 2
yoda: 0
# Strict
strict: 0
# Variables
init-declarations: 0
no-catch-shadow: 2
no-delete-var: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-shadow: 0
no-undef-init: 2
no-undef: 0
no-undefined: 0
no-unused-vars: 0
no-use-before-define: 0
# Node.js and CommonJS
callback-return: 2
global-require: 2
handle-callback-err: 2
no-mixed-requires: 0
no-new-require: 0
no-path-concat: 2
no-process-exit: 2
no-restricted-modules: 0
no-sync: 0
# Stylistic Issues
array-bracket-spacing: 0
block-spacing: 0
brace-style: 0
camelcase: 0
comma-spacing: 0
comma-style: 0
computed-property-spacing: 0
consistent-this: 0
eol-last: 0
func-names: 0
func-style: 0
id-length: 0
id-match: 0
indent: 0
jsx-quotes: 0
key-spacing: 0
linebreak-style: 0
lines-around-comment: 0
max-depth: 0
max-len: 0
max-nested-callbacks: 0
max-params: 0
max-statements: [2, 30]
new-cap: 0
new-parens: 0
newline-after-var: 0
no-array-constructor: 0
no-bitwise: 0
no-continue: 0
no-inline-comments: 0
no-lonely-if: 0
no-mixed-spaces-and-tabs: 0
no-multiple-empty-lines: 0
no-negated-condition: 0
no-nested-ternary: 0
no-new-object: 0
no-plusplus: 0
no-restricted-syntax: 0
no-spaced-func: 0
no-ternary: 0
no-trailing-spaces: 0
no-underscore-dangle: 0
no-unneeded-ternary: 0
object-curly-spacing: 0
one-var: 0
operator-assignment: 0
operator-linebreak: 0
padded-blocks: 0
quote-props: 0
quotes: 0
require-jsdoc: 0
semi-spacing: 0
semi: 0
sort-vars: 0
space-after-keywords: 0
space-before-blocks: 0
space-before-function-paren: 0
space-before-keywords: 0
space-in-parens: 0
space-infix-ops: 0
space-return-throw-case: 0
space-unary-ops: 0
spaced-comment: 0
wrap-regex: 0
# ECMAScript 6
arrow-body-style: 0
arrow-parens: 0
arrow-spacing: 0
constructor-super: 0
generator-star-spacing: 0
no-arrow-condition: 0
no-class-assign: 0
no-const-assign: 0
no-dupe-class-members: 0
no-this-before-super: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-const: 0
prefer-reflect: 0
prefer-spread: 0
prefer-template: 0
require-yield: 0
+2 -3
Ver Arquivo
@@ -3,9 +3,8 @@
node_modules/*
custom/*
coverage/*
docs/index.md
bower_components/
coverage/*
.settings/
-7
Ver Arquivo
@@ -3,11 +3,6 @@ node_js:
- "0.11"
- "0.10"
before_install:
- "export CHROME_BIN=chromium-browser"
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
before_script:
- npm install
@@ -16,5 +11,3 @@ script:
notifications:
slack: chartjs:pcfCZR6ugg5TEcaLtmIfQYuA
sudo: false
+3 -1
Ver Arquivo
@@ -35,6 +35,8 @@ Pull requests
Clear, concise pull requests are excellent at continuing the project's community driven growth. But please review [these guidelines](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) and the guidelines below before starting work on the project.
Be advised that **Chart.js 1.0.2 is in feature-complete status**. Pull requests adding new features to the 1.x branch will be disregarded.
Guidlines:
- Please create an issue first:
@@ -45,7 +47,7 @@ Guidlines:
- If adding new functionality, please also update the relevant `.md` file in [`/docs`](https://github.com/nnnick/Chart.js/tree/master/docs)
- Please make your commits in logical sections with clear commit messages
Joining the Project
Joining the project
-------------
- Active committers and contributors are invited to introduce yourself and request commit access to this project. Please send an email to hello@nickdownie.com or file an issue.
externo
+2983 -6457
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+3 -33
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+2 -1
Ver Arquivo
@@ -1,4 +1,5 @@
Copyright (c) 2013-2015 Nick Downie
The MIT License (MIT)
Copyright (c) 2013-2016 Nick Downie
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+31 -14
Ver Arquivo
@@ -1,39 +1,56 @@
[![](http://tannerlinsley.com/memes/chartjs.gif)](http://www.chartjs.org/docs/)
# Chart.js
[![Build Status](https://travis-ci.org/nnnick/Chart.js.svg?branch=v2.0-dev)](https://travis-ci.org/nnnick/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js)
[![Build Status](https://travis-ci.org/nnnick/Chart.js.svg?branch=master)](https://travis-ci.org/nnnick/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js) [![Chart.js on Slack](https://img.shields.io/badge/slack-Chart.js-blue.svg)](https://chartjs-slack-automation.herokuapp.com/)
*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)
## v1.0.2 Stable
- NPM: `npm install chart.js --save`
- Bower: `bower install Chart.js --save`
- CDN: https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js
- Zip: [Download](https://github.com/nnnick/Chart.js/archive/master.zip)
[Examples](https://github.com/nnnick/Chart.js/tree/master/samples) | [Documentation](http://www.chartjs.org/docs/)
## v2.0 Beta
Current Release: [2.0.0-beta](https://github.com/nnnick/Chart.js/releases/tag/2.0.0-beta)
- Release: [2.0.0-beta](https://github.com/nnnick/Chart.js/releases/tag/2.0.0-beta)
- Zip: [Download](https://github.com/nnnick/Chart.js/archive/2.0.0-beta2.zip)
The next generation and release of Chart.js has been well under way this year and we are very close to releasing some amazing new features including, but not limited to:
Documentation for v2.0 is currently located [here](http://nnnick.github.io/Chart.js/docs-v2/).
## v2.0 Bleeding-Edge
- Branch: [v2.0-dev](https://github.com/nnnick/Chart.js/tree/v2.0-dev)
- Zip: [Download](https://github.com/nnnick/Chart.js/archive/v2.0-dev.zip)
The next generation and release of Chart.js (v2.0) has been well under way this year and we are very close to releasing some amazing new features including, but not limited to:
- Rewritten, optimized, and unit-tested
- New and improved scales (log, time, linear, category, multiple scales)
- Improved Tooltips and tooltip callbacks for customization
- Improved responsiveness and resizing
- Powerful support for adding, removing, changing, and updating data on the fly
- Animations on all elements, colors and tooltips
- Animations for everything, including all elements, colors and tooltips
- Powerful customization when you need it. Automatic and dynamic when you don't.
- Excellent support for modern frameworks and modular build systems.
- Even more extensible via new element controllers, combo chart support, and hook system
- Bug fixes not addressed in 1.x, and much, much more...
- Even more extensible via new element controllers, core scale classes, combo chart support, and hook systems
- Bug fixes, stability improvements, etc.
#####Contributing to 2.0
Submit PR's to the v2.0-dev branch.
#####Building and Testing
`gulp build`, `gulp test`
`gulp build`, `gulp test`, `gulp watch --test`
## v1.x Status: Feature Complete
We are now treating v1.x as feature complete. PR's for bug fixes are welcome, but we urge any open PR's for v1.x features to be refactored and resubmitted for v2.x (if the feature has not already been implemented).
#####v1.x Status: Feature Complete
v1.x is now considered feature complete. PR's for bug fixes are still extremely welcome. Any open PR's for v1.x features will need to be reconsidered, refactored and resubmitted for v2.x (if the feature has not already been implemented). For questions on new features refer to the docs in the v2.0-dev branch
## Documentation
You can find documentation at [chartjs.org/docs](http://www.chartjs.org/docs/). The markdown files that build the site are available under `/docs`. Please note - in some of the json examples of configuration you might notice some liquid tags - this is just for the generating the site html, please disregard.
## Bugs, issues and contributing
## Bugs, Issues and Contributing
Before submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](https://github.com/nnnick/Chart.js/blob/master/CONTRIBUTING.md) first.
@@ -41,4 +58,4 @@ For support using Chart.js, please post questions with the [`chartjs` tag on Sta
## License
Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT).
Chart.js is available under the [MIT license](https://github.com/nnnick/Chart.js/blob/master/LICENSE.md).
+20 -12
Ver Arquivo
@@ -1,13 +1,21 @@
{
"name": "Chart.js",
"version": "2.0.0-beta2",
"description": "Simple HTML5 Charts using the canvas element",
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"main": [
"Chart.js"
],
"devDependencies": {
"jquery": "~2.1.4"
}
}
"name": "Chart.js",
"description": "Simple HTML5 Charts using the canvas element",
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"main": [
"Chart.js"
],
"ignore": [
"**/*",
".travis.yml",
"CONTRIBUTING.md",
"Chart.js",
"LICENSE.md",
"README.md",
"gulpfile.js",
"package.json"
],
"dependencies": {},
"version": "1.1.1"
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
{
"name": "nnnick/chartjs",
"type": "library",
"description": "Simple HTML5 charts using the canvas element.",
"keywords": [
"chart",
"js"
],
"homepage": "http://www.chartjs.org/",
"license": "MIT",
"authors": [
{
"name": "NICK DOWNIE",
"email": "hello@nickdownie.com"
}
],
"require": {
"php": ">=5.3.3"
},
"minimum-stability": "stable",
"extra": {
"branch-alias": {
"release/2.0": "v2.0-dev"
}
}
}
+176 -158
Ver Arquivo
@@ -11,214 +11,213 @@ First we need to include the Chart.js library on the page. The library occupies
<script src="Chart.js"></script>
```
Alternatively, if you're using an AMD loader for JavaScript modules, that is also supported in the Chart.js core. Please note: the library will still occupy a global variable of `Chart`, even if it detects `define` and `define.amd`. If this is a problem, you can call `noConflict` to restore the global Chart variable to it's previous owner.
Alternatively, if you're using an AMD loader for JavaScript modules, that is also supported in the Chart.js core. Please note: the library will still occupy a global variable of `Chart`, even if it detects `define` and `define.amd`. If this is a problem, you can call `noConflict` to restore the global Chart variable to its previous owner.
```javascript
// Using requirejs
require(['path/to/Chartjs'], function(Chart){
// Use Chart.js as normal here.
// Chart.noConflict restores the Chart global variable to it's previous owner
// Chart.noConflict restores the Chart global variable to its previous owner
// The function returns what was previously Chart, allowing you to reassign.
var Chartjs = Chart.noConflict();
});
```
You can also grab Chart.js using bower, npm, or CDN:
You can also grab Chart.js using bower:
```bash
bower install Chart.js --save
```
or NPM:
```bash
npm install chart.js --save
```
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.0-beta/Chart.js
Also, Chart.js is available from CDN:
###Creating a Chart
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js
To create a chart, we need to instantiate the `Chart` class. To do this, we need to pass in the node, jQuery instance, or 2d context of the canvas of where we want to draw the chart. Here's an example.
###Creating a chart
To create a chart, we need to instantiate the `Chart` class. To do this, we need to pass in the 2d context of where we want to draw the chart. Here's an example.
```html
<canvas id="myChart" width="400" height="400"></canvas>
```
```javascript
// Any of the following formats may be used
var ctx = document.getElementById("myChart");
// Get the context of the canvas element we want to select
var ctx = document.getElementById("myChart").getContext("2d");
var ctx = $("#myChart");
var myNewChart = new Chart(ctx).PolarArea(data);
```
Once you have the element or context, you're ready to instantiate a pre-defined chart-type or create your own!
We can also get the context of our canvas with jQuery. To do this, we need to get the DOM node out of the jQuery collection, and call the `getContext("2d")` method on that.
The following example instantiates a bar chart showing the number of votes for different colors and the y-axis starting at 0.
```html
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3]
}]
},
options:{
scales:{
yAxes:[{
ticks:{
beginAtZero:true
}
}]
}
}
});
</script>
```javascript
// Get context with jQuery - using jQuery's .get() method.
var ctx = $("#myChart").get(0).getContext("2d");
// This will get the first returned node in the jQuery collection.
var myNewChart = new Chart(ctx);
```
It's that easy to get started using Chart.js! From here you can explore the many options that can help you customise your charts with scales, tooltips, labels, colors, custom actions, and much more.
After we've instantiated the Chart class on the canvas we want to draw on, Chart.js will handle the scaling for retina displays.
With the Chart class set up, we can go on to create one of the charts Chart.js has available. In the example below, we would be drawing a Polar area chart.
```javascript
new Chart(ctx).PolarArea(data, options);
```
We call a method of the name of the chart we want to create. We pass in the data for that chart type, and the options for that chart as parameters. Chart.js will merge the global defaults with chart type specific defaults, then merge any options passed in as a second argument after data.
###Global chart configuration
This concept was introduced in Chart.js 1.0 to keep configuration DRY, and allow for changing options globally across chart types, avoiding the need to specify options for each instance, or the default for a particular chart type.
Chart.js merges configurations and options in a few places with the global defaults using chart type defaults and scales defaults. This way you can be as specific as you want in your individual chart configs, or change the defaults for Chart.js as a whole.
Templates are based on micro templating by John Resig:
The global options are defined in `Chart.defaults.global`.
http://ejohn.org/blog/javascript-micro-templating/
Name | Type | Default | Description
--- | --- | --- | ---
responsive | Boolean | true | Resizes when the canvas container does.
responsiveAnimationDuration | Number | 0 | Duration in milliseconds it takes to animate to new size after a resize event.
maintainAspectRatio | Boolean | true | Maintain the original canvas aspect ratio `(width / height)` when resizing
events | Array[String] | `["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]` | Events that the chart should listen to for tooltips and hovering
hover |-|-|-
*hover*.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)
*hover*.mode | String | 'single' | Sets which elements hover. Acceptable options are `'single'`, `'label'`, or `'dataset'`. `single` highlights the closest element. `label` highlights elements in all datasets at the same `X` value. `dataset` highlights the closest dataset.
*hover*.animationDuration | Number | 400 | Duration in milliseconds it takes to animate hover style changes
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
defaultColor | Color | 'rgba(0,0,0,0.1)' |
legendCallback | Function | ` function (chart) { // the chart object to generate a legend from. }` | Function to generate a legend. Default implementation returns an HTML string.
```javascript
Chart.defaults.global = {
// Boolean - Whether to animate the chart
animation: true,
The global options for the chart title is defined in `Chart.defaults.global.title`
// Number - Number of animation steps
animationSteps: 60,
Name | Type | Default | Description
--- | --- | --- | ---
display | Boolean | true | Show the title block
position | String | 'top' | Position of the title. 'top' or 'bottom' are allowed
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
fontColor | Color | '#666' | Text color
fontFamily | String | 'Helvetica Neue' |
fontSize | Number | 12 |
fontStyle | String | 'bold' |
padding | Number | 10 | Number of pixels to add above and below the title text
text | String | '' | Title text
// String - Animation easing effect
// Possible effects are:
// [easeInOutQuart, linear, easeOutBounce, easeInBack, easeInOutQuad,
// easeOutQuart, easeOutQuad, easeInOutBounce, easeOutSine, easeInOutCubic,
// easeInExpo, easeInOutBack, easeInCirc, easeInOutElastic, easeOutBack,
// easeInQuad, easeInOutExpo, easeInQuart, easeOutQuint, easeInOutCirc,
// easeInSine, easeOutExpo, easeOutCirc, easeOutCubic, easeInQuint,
// easeInElastic, easeInOutSine, easeInOutQuint, easeInBounce,
// easeOutElastic, easeInCubic]
animationEasing: "easeOutQuart",
The global options for the chart legend is defined in `Chart.defaults.global.legend`
// Boolean - If we should show the scale at all
showScale: true,
Name | Type | Default | Description
--- | --- | --- | ---
display | Boolean | true | Is the legend displayed
position | String | 'top' | Position of the legend. Options are 'top' or 'bottom'
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
onClick | Function | `function(event, legendItem) {}` | A callback that is called when a click is registered on top of a label item
labels |-|-|-
*labels*boxWidth | Number | 40 | Width of coloured box
*labels*fontSize | Number | 12 | Font size
*labels*fontStyle | String | "normal" |
*labels*fontColor | Color | "#666" |
*labels*fontFamily | String | "Helvetica Neue" |
*labels*padding | Number | 10 | Padding between rows of colored boxes
*labels*generateLabels: | Function | `function(data) { } | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. Styles that can be returned are `fillStyle`, `strokeStyle`, `lineCap`, `lineDash`, `lineDashOffset`, `lineWidth`, `lineJoin`. Return a `hidden` attribute to indicate that the label refers to something that is not visible. A strikethrough style will be given to the text in this case.
// Boolean - If we want to override with a hard coded scale
scaleOverride: false,
The global options for tooltips are defined in `Chart.defaults.global.tooltips`.
// ** Required if scaleOverride is true **
// Number - The number of steps in a hard coded scale
scaleSteps: null,
// Number - The value jump in the hard coded scale
scaleStepWidth: null,
// Number - The scale starting value
scaleStartValue: null,
Name | Type | Default | Description
--- |:---:| --- | ---
enabled | Boolean | true |
custom | | null |
mode | String | 'single' | Sets which elements appear in the tooltip. Acceptable options are `'single'` or `'label'`. `single` highlights the closest element. `label` highlights elements in all datasets at the same `X` value.
backgroundColor | Color | 'rgba(0,0,0,0.8)' | Background color of the tooltip
| | |
Label | | | There are three labels you can control. `title`, `body`, `footer` the star (\*) represents one of these three. *(i.e. titleFontFamily, footerSpacing)*
\*FontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" |
\*FontSize | Number | 12 |
\*FontStyle | String | title - "bold", body - "normal", footer - "bold" |
\*Spacing | Number | 2 |
\*Color | Color | "#fff" |
\*Align | String | "left" | text alignment. See [MDN Canvas Documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign)
titleMarginBottom | Number | 6 | Margin to add on bottom of title section
footerMarginTop | Number | 6 | Margin to add before drawing the footer
xPadding | Number | 6 | Padding to add on left and right of tooltip
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
| | |
callbacks | - | - | V2.0 introduces callback functions as a replacement for the template engine in v1. The tooltip has the following callbacks for providing text. For all functions, 'this' will be the tooltip object create from the Chart.Tooltip constructor
**Callback Functions** | | | All functions are called with the same arguments
xLabel | String or Array[Strings] | | This is the xDataValue for each item to be displayed in the tooltip
yLabel | String or Array[Strings] | | This is the yDataValue for each item to be displayed in the tooltip
index | Number | | Data index.
data | Object | | Data object passed to chart.
`return`| String or Array[Strings] | | All functions must return either a string or an array of strings. Arrays of strings are treated as multiple lines of text.
| | |
*callbacks*.beforeTitle | Function | none | Text to render before the title
*callbacks*.title | Function | `function(tooltipItems, data) { //Pick first xLabel }` | Text to render as the title
*callbacks*.afterTitle | Function | none | Text to render after the ttiel
*callbacks*.beforeBody | Function | none | Text to render before the body section
*callbacks*.beforeLabel | Function | none | Text to render before an individual label
*callbacks*.label | Function | `function(tooltipItem, data) { // Returns "datasetLabel: tooltipItem.yLabel" }` | Text to render as label
*callbacks*.afterLabel | Function | none | Text to render after an individual label
*callbacks*.afterBody | Function | none | Text to render after the body section
*callbacks*.beforeFooter | Function | none | Text to render before the footer section
*callbacks*.footer | Function | none | Text to render as the footer
*callbacks*.afterFooter | Function | none | Text to render after the footer section
// String - Colour of the scale line
scaleLineColor: "rgba(0,0,0,.1)",
The global options for animations are defined in `Chart.defaults.global.animation`.
// Number - Pixel width of the scale line
scaleLineWidth: 1,
Name | Type | Default | Description
--- |:---:| --- | ---
duration | Number | 1000 | The number of milliseconds an animation takes.
easing | String | "easeOutQuart" | Easing function to use.
onProgress | Function | none | Callback called on each step of an animation. Passed a single argument, an object, containing the chart instance and an object with details of the animation.
onComplete | Function | none | Callback called at the end of an animation. Passed the same arguments as `onProgress
`
The global options for elements are defined in `Chart.defaults.global.elements`.
// Boolean - Whether to show labels on the scale
scaleShowLabels: true,
Name | Type | Default | Description
--- |:---:| --- | ---
arc | - | - | -
*arc*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default fill color for arcs
*arc*.borderColor | Color | "#fff" | Default stroke color for arcs
*arc*.borderWidth | Number | 2 | Default stroke width for arcs
line | - | - | -
*line*.tension | Number | 0.4 | Default bezier curve tension. Set to `0` for no bezier curves.
*line*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default line fill color
*line*.borderWidth | Number | 3 | Default line stroke width
*line*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default line stroke color
*line*.borderCapStyle | String | 'butt' | Default line cap style. See [MDN](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap)
*line*.borderDash | Array | `[]` | Default line dash. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)
*line*.borderDashOffset | Number | 0.0 | Default line dash offset. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
*line*.borderJoinStyle | String | 'miter' | Default line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
*line*.fill | Boolean | true |
point | - | - | -
*point*.radius | Number | 3 | Default point radius
*point*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default point fill color
*point*.borderWidth | Number | 1 | Default point stroke width
*point*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default point stroke color
*point*.hitRadius | Number | 1 | Extra radius added to point radius for hit detection
*point*.hoverRadius | Number | 4 | Default point radius when hovered
*point*.hoverBorderWidth | Number | 1 | Default stroke width when hovered
rectangle | - | - | -
*rectangle*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default bar fill color
*rectangle*.borderWidth | Number | 0 | Default bar stroke width
*rectangle*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default bar stroke color
// Interpolated JS string - can access value
scaleLabel: "<%=value%>",
// Boolean - Whether the scale should stick to integers, not floats even if drawing space is there
scaleIntegersOnly: true,
// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero: false,
// String - Scale label font declaration for the scale label
scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Scale label font size in pixels
scaleFontSize: 12,
// String - Scale label font weight style
scaleFontStyle: "normal",
// String - Scale label font colour
scaleFontColor: "#666",
// Boolean - whether or not the chart should be responsive and resize when the browser does.
responsive: false,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
// Boolean - Determines whether to draw tooltips on the canvas or not
showTooltips: true,
// Function - Determines whether to execute the customTooltips function instead of drawing the built in tooltips (See [Advanced - External Tooltips](#advanced-usage-external-tooltips))
customTooltips: false,
// Array - Array of string names to attach tooltip events
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
// String - Tooltip background colour
tooltipFillColor: "rgba(0,0,0,0.8)",
// String - Tooltip label font declaration for the scale label
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Tooltip label font size in pixels
tooltipFontSize: 14,
// String - Tooltip font weight style
tooltipFontStyle: "normal",
// String - Tooltip label font colour
tooltipFontColor: "#fff",
// String - Tooltip title font declaration for the scale label
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Tooltip title font size in pixels
tooltipTitleFontSize: 14,
// String - Tooltip title font weight style
tooltipTitleFontStyle: "bold",
// String - Tooltip title font colour
tooltipTitleFontColor: "#fff",
// String - Tooltip title template
tooltipTitleTemplate: "<%= label%>",
// Number - pixel width of padding around tooltip text
tooltipYPadding: 6,
// Number - pixel width of padding around tooltip text
tooltipXPadding: 6,
// Number - Size of the caret on the tooltip
tooltipCaretSize: 8,
// Number - Pixel radius of the tooltip border
tooltipCornerRadius: 6,
// Number - Pixel offset from point x to tooltip edge
tooltipXOffset: 10,
{% raw %}
// String - Template string for single tooltips
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
{% endraw %}
// String - Template string for multiple tooltips
multiTooltipTemplate: "<%= value %>",
// Function - Will fire on animation progression.
onAnimationProgress: function(){},
// Function - Will fire on animation completion.
onAnimationComplete: function(){}
}
```
If for example, you wanted all charts created to be responsive, and resize when the browser window does, the following setting can be changed:
@@ -227,3 +226,22 @@ Chart.defaults.global.responsive = true;
```
Now, every time we create a chart, `options.responsive` will be `true`.
###Tooltip Templates
For the `tooltipTemplate` and `multiTooltipTemplate` configuration options, you may use special template blocks. **Do not use user input in the tooltip template, as it may be executed as raw JavaScript.**
Anything in between `<%` and `%>` will be executed as JavaScript. As in the example shown above, `<% if (label) { %>` and later `<% } %>`. Using `<%= expr %>` will print the value of the variable named by `expr` into the tooltip.
The available variables to print into the tooltip depends on the chart type. In general, the following variables are available:
```javascript
{
value : "value of the data point",
label : "label for the position the data point is at",
datasetLabel: "label for the dataset the point is from",
strokeColor : "stroke color for the dataset",
fillColor : "fill color for the dataset",
highlightFill : "highlight fill color for the dataset",
highlightStroke : "highlight stroke color for the dataset"
}
```
+169
Ver Arquivo
@@ -0,0 +1,169 @@
---
title: Line Chart
anchor: line-chart
---
###Introduction
A line chart is a way of plotting data points on a line.
Often, it is used to show trend data, and the comparison of two data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
###Example usage
```javascript
var myLineChart = new Chart(ctx).Line(data, options);
```
###Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The line chart requires an array of labels. This labels are shown on the X axis. There must be one label for each data point. More labels than datapoints are allowed, in which case the line ends at the last data point.
The data for line charts is broken up into an array of datasets. Each dataset has a colour for the fill, a colour for the line and colours for the points and strokes of the points. These colours are strings just like CSS. You can use RGBA, RGB, HEX or HSL notation.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart options
These are the customisation options specific to Line charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - Whether the line is curved between points
bezierCurve : true,
//Number - Tension of the bezier curve between points
bezierCurveTension : 0.4,
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 4,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
{% endraw %}
//Boolean - Whether to horizontally center the label and point dot inside the grid
offsetGridLines : false
};
```
You can override these for your `Chart` instance by passing a second argument into the `Line` method as an object with the keys you want to override.
For example, we could have a line chart without bezier curves between points by doing the following:
```javascript
new Chart(ctx).Line(data, {
bezierCurve: false
});
// This will create a chart with all of the default options, merged from the global config,
// and the Line chart defaults, but this particular instance will have `bezierCurve` set to false.
```
We can also change these defaults values for each Line type that is created, this object is available at `Chart.defaults.Line`.
### Prototype methods
#### .getPointsAtEvent( event )
Calling `getPointsAtEvent(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.getPointsAtEvent(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.
#### .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
myLineChart.datasets[0].points[2].value = 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.
```
#### .addData( valuesArray, label )
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those points.
```javascript
// The values array passed into addData should be one for each dataset in the chart
myLineChart.addData([40, 60], "August");
// This new data will now animate at the end of the chart.
```
#### .removeData( )
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
```javascript
myLineChart.removeData();
// The chart will remove the first point and animate other points into place
```
-280
Ver Arquivo
@@ -1,280 +0,0 @@
---
title: Scales
anchor: scales
---
Scales in v2.0 of Chart.js are significantly more powerful, but also different than those of v1.0.
* Multiple x & y axes are now supported.
* A built-in label auto-skip feature now detects would-be overlapping ticks and labels and removes every nth label to keep things displaying normally.
* Scale titles are now supported
* New scale types can be extended without writing an entirely new chart type
Every scale extends a core scale class with the following options:
Name | Type | Default | Description
--- |:---:| --- | ---
type | String | Chart specific. | Type of scale being employed. Custom scales can be created and registered with a string key. Options: ["category"](#scales-category-scale), ["linear"](#scales-linear-scale), ["logarithmic"](#scales-logarithmic-scale), ["time"](#scales-time-scale), ["radialLinear"](#scales-radial-linear-scale)
display | Boolean | true | If true, show the scale including gridlines, ticks, and labels. Overrides *gridLines.display*, *scaleLabel.display*, and *ticks.display*.
beforeUpdate | Function | undefined | Callback called before the update process starts. Passed a single argument, the scale instance.
beforeSetDimensions | Function | undefined | Callback that runs before dimensions are set. Passed a single argument, the scale instance.
afterSetDimensions | Function | undefined | Callback that runs after dimensions are set. Passed a single argument, the scale instance.
beforeDataLimits | Function | undefined | Callback that runs before data limits are determined. Passed a single argument, the scale instance.
afterDataLimits | Function | undefined | Callback that runs after data limits are determined. Passed a single argument, the scale instance.
beforeBuildTicks | Function | undefined | Callback that runs before ticks are created. Passed a single argument, the scale instance.
afterBuildTicks | Function | undefined | Callback that runs after ticks are created. Useful for filtering ticks. Passed a single argument, the scale instance.
beforeTickToLabelConversion | Function | undefined | Callback that runs before ticks are converted into strings. Passed a single argument, the scale instance.
afterTickToLabelConversion | Function | undefined | Callback that runs after ticks are converted into strings. Passed a single argument, the scale instance.
beforeCalculateTickRotation | Function | undefined | Callback that runs before tick rotation is determined. Passed a single argument, the scale instance.
afterCalculateTickRotation | Function | undefined | Callback that runs after tick rotation is determined. Passed a single argument, the scale instance.
beforeFit | Function | undefined | Callback that runs before the scale fits to the canvas. Passed a single argument, the scale instance.
afterFit | Function | undefined | Callback that runs after the scale fits to the canvas. Passed a single argument, the scale instance.
afterUpdate | Function | undefined | Callback that runs at the end of the update process. Passed a single argument, the scale instance.
**gridLines** | Array | - | Options for the grid lines that run perpendicular to the axis.
*gridLines*.display | Boolean | true |
*gridLines*.color | Color | "rgba(0, 0, 0, 0.1)" | Color of the grid lines.
*gridLines*.lineWidth | Number | 1 | Stroke width of grid lines
*gridLines*.drawOnChartArea | Boolean | true | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn
*gridLines*.drawTicks | Boolean | true | If true, draw lines beside the ticks in the axis area beside the chart.
*gridLines*.zeroLineWidth | Number | 1 | Stroke width of the grid line for the first index (index 0).
*gridLines*.zeroLineColor | Color | "rgba(0, 0, 0, 0.25)" | Stroke color of the grid line for the first index (index 0).
*gridLines*.offsetGridLines | Boolean | false | If true, offset labels from grid lines.
**scaleLabel** | Array | | Title for the entire axis.
*scaleLabel*.display | Boolean | false |
*scaleLabel*.labelString | String | "" | The text for the title. (i.e. "# of People", "Response Choices")
*scaleLabel*.fontColor | Color | "#666" | Font color for the scale title.
*scaleLabel*.fontFamily| String | "Helvetica Neue" | Font family for the scale title, follows CSS font-family options.
*scaleLabel*.fontSize | Number | 12 | Font size for the scale title.
*scaleLabel*.fontStyle | String | "normal" | Font style for the scale title, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
**ticks** | Array | | Settings for the labels that run along the axis.
*ticks*.beginAtZero | Boolean | false | If true the scale will be begin at 0, if false the ticks will begin at your smallest data value.
*ticks*.fontColor | Color | "#666" | Font color for the tick labels.
*ticks*.fontFamily | String | "Helvetica Neue" | Font family for the tick labels, follows CSS font-family options.
*ticks*.fontSize | Number | 12 | Font size for the tick labels.
*ticks*.fontStyle | String | "normal" | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
*ticks*.maxRotation | Number | 90 | Maximum rotation for tick labels when rotating to condense labels. Note: Rotation doesn't occur until necessary. *Note: Only applicable to horizontal scales.*
*ticks*.minRotation | Number | 20 | *currently not-implemented* Minimum rotation for tick labels when condensing is necessary. *Note: Only applicable to horizontal scales.*
*ticks*.padding | Number | 10 | Padding between the tick label and the axis. *Note: Only applicable to horizontal scales.*
*ticks*.mirror | Boolean | false | Flips tick labels around axis, displaying the labels inside the chart instead of outside. *Note: Only applicable to vertical scales.*
*ticks*.reverse | Boolean | false | Reverses order of tick labels.
*ticks*.display | Boolean | true | If true, show the ticks.
*ticks*.suggestedMin | Number | - | User defined minimum number for the scale, overrides minimum value *except for if* it is higher than the minimum value.
*ticks*.suggestedMax | Number | - | User defined maximum number for the scale, overrides maximum value *except for if* it is lower than the maximum value.
*ticks*.min | Number | - | User defined minimum number for the scale, overrides minimum value
*ticks*.max | Number | - | User defined minimum number for the scale, overrides maximum value
*ticks*.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
*ticks*.callback | Function | `function(value) { return '' + value; } ` | Returns the string representation of the tick value as it should be displayed on the chart.
The `callback` method may be used for advanced tick customization. The following callback would display every label in scientific notation
```javascript
{
scales: {
xAxes: [{
ticks: {
// Return an empty string to draw the tick line but hide the tick label
// Return `null` or `undefined` to hide the tick line entirely
userCallback: function(value, index, values) {
return value.toExponential();
}
}
}]
}
}
```
### Category Scale
The category scale will be familiar to those who have used v1.0. Labels are drawn in from the labels array included in the chart data.
The category scale extends the core scale class with the following tick template:
```javascript
{
position: "bottom",
}
```
### Linear Scale
The linear scale can be used to display numerical data. It can be placed on either the x or y axis. The scatter chart type automatically configures a line chart to use one of these scales for the x axis.
The linear scale extends the core scale class with the following tick template:
```javascript
{
position: "left",
ticks: {
callback: function(tickValue, index, ticks) {
var delta = 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 Scale
The logarithmic scale is used to display logarithmic data of course. It can be placed on either the x or y axis.
The log scale extends the core scale class with the following tick template:
```javascript
{
position: "left",
ticks: {
callback: function(value) {
var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));
if (remain === 1 || remain === 2 || remain === 5) {
return value.toExponential();
} else {
return '';
}
}
}
}
```
### Time Scale
The time scale is used to display times and dates. It can be placed on the x axis. When building its ticks, it will automatically calculate the most comfortable unit base on the size of the scale.
The time scale extends the core scale class with the following tick template:
```javascript
{
position: "bottom",
time: {
// string/callback - By default, date objects are expected. You may use a pattern string from http://momentjs.com/docs/#/parsing/string-format/ to parse a time string format, or use a callback function that is passed the label, and must return a moment() instance.
format: false,
// string - By default, unit will automatically be detected. Override with 'week', 'month', 'year', etc. (see supported time measurements)
unit: false,
// string - By default, no rounding is applied. To round, set to a supported time unit eg. 'week', 'month', 'year', etc.
round: false,
// Moment js for each of the units. Replaces `displayFormat`
// To override, use a pattern string from http://momentjs.com/docs/#/displaying/format/
displayFormats: {
'millisecond': 'SSS [ms]',
'second': 'h:mm:ss a', // 11:20:01 AM
'minute': 'h:mm:ss a', // 11:20:01 AM
'hour': 'MMM D, hA', // Sept 4, 5PM
'day': 'll', // Sep 4 2015
'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
'month': 'MMM YYYY', // Sept 2015
'quarter': '[Q]Q - YYYY', // Q3
'year': 'YYYY', // 2015
},
// Sets the display format used in tooltip generation
tooltipFormat: ''
},
}
```
The following time measurements are supported:
```javascript
{
'millisecond': {
display: 'SSS [ms]', // 002 ms
maxStep: 1000,
},
'second': {
display: 'h:mm:ss a', // 11:20:01 AM
maxStep: 60,
},
'minute': {
display: 'h:mm:ss a', // 11:20:01 AM
maxStep: 60,
},
'hour': {
display: 'MMM D, hA', // Sept 4, 5PM
maxStep: 24,
},
'day': {
display: 'll', // Sep 4 2015
maxStep: 7,
},
'week': {
display: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
maxStep: 4.3333,
},
'month': {
display: 'MMM YYYY', // Sept 2015
maxStep: 12,
},
'quarter': {
display: '[Q]Q - YYYY', // Q3
maxStep: 4,
},
'year': {
display: 'YYYY', // 2015
maxStep: false,
},
}
```
### Radial Linear Scale
The radial linear scale is used specifically for the radar chart type.
The radial linear scale extends the core scale class with the following tick template:
```javascript
{
animate: true,
lineArc: false,
position: "chartArea",
angleLines: {
display: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1
},
// label settings
ticks: {
//Boolean - Show a backdrop to the scale label
showLabelBackdrop: true,
//String - The colour of the label backdrop
backdropColor: "rgba(255,255,255,0.75)",
//Number - The backdrop padding above & below the label in pixels
backdropPaddingY: 2,
//Number - The backdrop padding to the side of the label in pixels
backdropPaddingX: 2,
//Number - Limit the maximum number of ticks
maxTicksLimit: 11,
},
pointLabels: {
//String - Point label font declaration
fontFamily: "'Arial'",
//String - Point label font weight
fontStyle: "normal",
//Number - Point label font size in pixels
fontSize: 10,
//String - Point label font colour
fontColor: "#666",
},
}
```
+149
Ver Arquivo
@@ -0,0 +1,149 @@
---
title: Bar Chart
anchor: bar-chart
---
### Introduction
A bar chart is a way of showing data as bars.
It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myBarChart = new Chart(ctx).Bar(data, options);
```
### Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero : true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 1,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
{% endraw %}
}
```
You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override.
For example, we could have a bar chart without a stroke on each bar by doing the following:
```javascript
new Chart(ctx).Bar(data, {
barShowStroke: false
});
// This will create a chart with all of the default options, merged from the global config,
// and the Bar chart defaults but this particular instance will have `barShowStroke` set to false.
```
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
### Prototype methods
#### .getBarsAtEvent( event )
Calling `getBarsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the bar elements that are at that the same position of that event.
```javascript
canvas.onclick = function(evt){
var activeBars = myBarChart.getBarsAtEvent(evt);
// => activeBars is an array of bars 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
myBarChart.datasets[0].bars[2].value = 50;
// Would update the first dataset's value of 'March' to be 50
myBarChart.update();
// Calling update now animates the position of March from 90 to 50.
```
#### .addData( valuesArray, label )
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those bars.
```javascript
// The values array passed into addData should be one for each dataset in the chart
myBarChart.addData([40, 60], "August");
// The new data will now animate at the end of the chart.
```
#### .removeData( )
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
```javascript
myBarChart.removeData();
// The chart will now animate and remove the first bar
```
-154
Ver Arquivo
@@ -1,154 +0,0 @@
---
title: Line Chart
anchor: line-chart
---
###Introduction
A line chart is a way of plotting data points on a line.
Often, it is used to show trend data, and the comparison of two data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
###Example usage
```javascript
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
```
Alternatively a line chart can be created using syntax similar to the v1.0 syntax
```javascript
var myLineChart = Chart.Line(ctx, {
data: data,
options: options
});
```
###Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
// Boolean - if true fill the area under the line
fill: false,
// String - the color to fill the area under the line with if fill is true
backgroundColor: "rgba(220,220,220,0.2)",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - Line color
borderColor: "rgba(220,220,220,1)",
// String - cap style of the line. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap
borderCapStyle: 'butt',
// Array - Length and spacing of dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash
borderDash: [],
// Number - Offset for line dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
borderDashOffset: 0.0,
// String - line join style. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin
borderJoinStyle: 'miter',
// String or array - Point stroke color
pointBorderColor: "rgba(220,220,220,1)",
// String or array - Point fill color
pointBackgroundColor: "#fff",
// Number or array - Stroke width of point border
pointBorderWidth: 1,
// Number or array - Radius of point when hovered
pointHoverRadius: 5,
// String or array - point background color when hovered
pointHoverBackgroundColor: "rgba(220,220,220,1)",
// Point border color when hovered
pointHoverBorderColor: "rgba(220,220,220,1)",
// Number or array - border width of point when hovered
pointHoverBorderWidth: 2,
// Tension - bezier curve tension of the line. Set to 0 to draw straight Wlines connecting points
tension: 0.1,
// The actual data
data: [65, 59, 80, 81, 56, 55, 40],
// String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used.
yAxisID: "y-axis-1",
},
{
label: "My Second dataset",
fill: false,
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBorderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "#fff",
pointBorderWidth: 1,
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(220,220,220,1)",
pointHoverBorderColor: "rgba(220,220,220,1)",
pointHoverBorderWidth: 2,
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The line chart requires an array of labels for each of the data points. This is shown on the X axis.
The data for line charts is broken up into an array of datasets. Each dataset has a colour for the fill, a colour for the line and colours for the points and strokes of the points. These colours are strings just like CSS. You can use RGBA, RGB, HEX or HSL notation.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart options
These are the customisation options specific to Line charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for line chart are defined in `Chart.defaults.Line`.
Name | Type | Default | Description
--- | --- | --- | ---
stacked | Boolean | false | If true, lines stack on top of each other along the y axis.
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
scales | - | - | -
*scales*.xAxes | Array | `[{type:"category","id":"x-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
*Options for xAxes* | | |
type | String | "category" | As defined in ["Category"](#scales-category-scale).
id | String | "x-axis-1" | Id of the axis so that data can bind to it.
| | |
*scales*.yAxes | Array | `[{type:"linear","id":"y-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
*Options for yAxes* | | |
type | String | "linear" | As defined in ["Linear"](#scales-linear-scale).
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
You can override these for your `Chart` instance by passing a member `options` into the `Line` method.
For example, we could have a line chart display without an x axis by doing the following. The config merge is smart enough to handle arrays so that you do not need to specify all axis settings to change one thing.
```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
xAxes: [{
display: false
}]
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Line chart defaults, but this particular instance will have the x axis not displaying.
```
We can also change these defaults values for each Line type that is created, this object is available at `Chart.defaults.line`.
-155
Ver Arquivo
@@ -1,155 +0,0 @@
---
title: Bar Chart
anchor: bar-chart
---
### Introduction
A bar chart is a way of showing data as bars.
It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myBarChart = new Chart(ctx,{
type: 'bar',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - the bar color
backgroundColor: "rgba(220,220,220,0.2)",
// String or array - bar stroke color
borderColor: "rgba(220,220,220,1)",
// Number or array - bar border width
borderWidth: 1,
// String or array - fill color when hovered
hoverBackgroundColor: "rgba(220,220,220,0.2)",
// String or array - border color when hovered
hoverBorderColor: "rgba(220,220,220,1)",
// The actual data
data: [65, 59, 80, 81, 56, 55, 40],
// String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used.
yAxisID: "y-axis-1",
},
{
label: "My Second dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
borderWidth: 1,
hoverBackgroundColor: "rgba(220,220,220,0.2)",
hoverBorderColor: "rgba(220,220,220,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for bar chart are defined in `Chart.defaults.Bar`.
Name | Type | Default | Description
--- |:---:| --- | ---
stacked | Boolean | false |
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
scales | Array | - | -
*scales*.xAxes | Array | | The bar chart officially supports only 1 x-axis but uses an array to keep the API consistent. Use a scatter chart if you need multiple x axes.
*Options for xAxes* | | |
type | String | "Category" | As defined in [Scales](#scales-category-scale).
display | Boolean | true | If true, show the scale.
position | String | "bottom" | Position of the scale. Options are "top" and "bottom" for dataset scales.
id | String | "x-axis-1" | Id of the axis so that data can bind to it
categoryPercentage | Number | 0.8 | Percent (0-1) of the available width (the space between the gridlines for small datasets) for each data-point to use for the bars. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
barPercentage | Number | 0.9 | Percent (0-1) of the available width each bar should be within the category percentage. 1.0 will take the whole category width and put the bars right next to each other. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
gridLines | Array | [See Scales](#scales) |
*gridLines*.offsetGridLines | Boolean | true | If true, the bars for a particular data point fall between the grid lines. If false, the grid line will go right down the middle of the bars.
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
| | |
*scales*.yAxes | Array | `[{ type: "linear" }]` |
*Options for xAxes* | | |
type | String | "linear" | As defined in [Scales](#scales-linear-scale).
display | Boolean | true | If true, show the scale.
position | String | "left" | Position of the scale. Options are "left" and "right" for dataset scales.
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
gridLines | Array | [See Scales](#scales) |
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override.
For example, we could have a bar chart without a stroke on each bar by doing the following:
```javascript
new Chart(ctx,{
type:"bar",
data: data,
options: {
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Bar chart defaults but this particular instance will have `stacked` set to true
// for both x and y axes.
```
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
#### barPercentage vs categoryPercentage
The following shows the relationship between the bar percentage option and the category percentage option.
```text
// categoryPercentage: 1.0
// barPercentage: 1.0
Bar: | 1.0 | 1.0 |
Category: | 1.0 |
Sample: |===========|
// categoryPercentage: 1.0
// barPercentage: 0.5
Bar: |.5| |.5|
Category: | 1.0 |
Sample: |==============|
// categoryPercentage: 0.5
// barPercentage: 1.0
Bar: |1.||1.|
Category: | .5 |
Sample: |==============|
```
+180
Ver Arquivo
@@ -0,0 +1,180 @@
---
title: Radar Chart
anchor: radar-chart
---
###Introduction
A radar chart is a way of showing multiple data points and the variation between them.
They are often useful for comparing the points of two or more different data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
###Example usage
```javascript
var myRadarChart = new Chart(ctx).Radar(data, options);
```
###Data structure
```javascript
var data = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
};
```
For a radar chart, to provide context of what each point means, we include an array of strings that show around each point in the chart.
For the radar chart data, we have an array of datasets. Each of these is an object, with a fill colour, a stroke colour, a colour for the fill of each point, and a colour for the stroke of each point. We also have an array of data values.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart options
These are the customisation options specific to Radar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
//Boolean - Whether to show lines for each scale point
scaleShowLine : true,
//Boolean - Whether we show the angle lines out of the radar
angleShowLineOut : true,
//Boolean - Whether to show labels on the scale
scaleShowLabels : false,
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//String - Colour of the angle line
angleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the angle line
angleLineWidth : 1,
//Number - Interval at which to draw angle lines ("every Nth point")
angleLineInterval: 1,
//String - Point label font declaration
pointLabelFontFamily : "'Arial'",
//String - Point label font weight
pointLabelFontStyle : "normal",
//Number - Point label font size in pixels
pointLabelFontSize : 10,
//String - Point label font colour
pointLabelFontColor : "#666",
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 3,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
{% endraw %}
}
```
You can override these for your `Chart` instance by passing a second argument into the `Radar` method as an object with the keys you want to override.
For example, we could have a radar chart without a point for each on piece of data by doing the following:
```javascript
new Chart(ctx).Radar(data, {
pointDot: false
});
// This will create a chart with all of the default options, merged from the global config,
// and the Bar chart defaults but this particular instance will have `pointDot` set to false.
```
We can also change these defaults values for each Radar type that is created, this object is available at `Chart.defaults.Radar`.
### Prototype methods
#### .getPointsAtEvent( event )
Calling `getPointsAtEvent(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 = myRadarChart.getPointsAtEvent(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.
#### .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
myRadarChart.datasets[0].points[2].value = 50;
// Would update the first dataset's value of 'Sleeping' to be 50
myRadarChart.update();
// Calling update now animates the position of Sleeping from 90 to 50.
```
#### .addData( valuesArray, label )
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those points.
```javascript
// The values array passed into addData should be one for each dataset in the chart
myRadarChart.addData([40, 60], "Dancing");
// The new data will now animate at the end of the chart.
```
#### .removeData( )
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
```javascript
myRadarChart.removeData();
// Other points will now animate to their correct positions.
```
+172
Ver Arquivo
@@ -0,0 +1,172 @@
---
title: Polar Area Chart
anchor: polar-area-chart
---
### Introduction
Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
This type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
new Chart(ctx).PolarArea(data, 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"
}
];
```
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.
### Chart options
These are the customisation options specific to Polar Area charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
//Boolean - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//Number - The backdrop padding above & below the label in pixels
scaleBackdropPaddingY : 2,
//Number - The backdrop padding to the side of the label in pixels
scaleBackdropPaddingX : 2,
//Boolean - Show line for each value in the scale
scaleShowLine : true,
//Boolean - Stroke a line around each segment in the chart
segmentShowStroke : true,
//String - The colour of the stroke on each segment.
segmentStrokeColor : "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth : 2,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect.
animationEasing : "easeOutBounce",
//Boolean - Whether to animate the rotation of the chart
animateRotate : true,
//Boolean - Whether to animate scaling the chart from the centre
animateScale : false,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
{% endraw %}
}
```
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"
});
// 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"`.
```
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.
```
-93
Ver Arquivo
@@ -1,93 +0,0 @@
---
title: Radar Chart
anchor: radar-chart
---
### Introduction
A radar chart is a way of showing multiple data points and the variation between them.
They are often useful for comparing the points of two or more different data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myRadarChart = new Chart(ctx, {
type:'radar',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "rgba(220,220,220,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
};
```
For a radar chart, to provide context of what each point means, we include an array of strings that show around each point in the chart.
For the radar chart data, we have an array of datasets. Each of these is an object, with a fill colour, a stroke colour, a colour for the fill of each point, and a colour for the stroke of each point. We also have an array of data values.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Radar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for radar chart are defined in `Chart.defaults.radar`.
Name | Type | Default | Description
--- | --- | --- | ---
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#scales-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid lines.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*elements*.line | Array | | Options for all line elements used on the chart, as defined in the global elements, duplicated here to show Radar chart specific defaults.
*elements.line*.tension | Number | 0 | Tension exhibited by lines when calculating splineCurve. Setting to 0 creates straight lines.
You can override these for your `Chart` instance by passing a second argument into the `Radar` method as an object with the keys you want to override.
For example, we could have a radar chart without a point for each on piece of data by doing the following:
```javascript
new Chart(ctx, {
type:"radar",
data: data,
options: {
scale: {
reverse: true,
ticks: {
beginAtZero: true
}
}
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Radar chart defaults but this particular instance's scale will be reversed as
// well as the ticks beginning at zero.
```
We can also change these defaults values for each Radar type that is created, this object is available at `Chart.defaults.radar`.
+160
Ver Arquivo
@@ -0,0 +1,160 @@
---
title: Pie & Doughnut Charts
anchor: doughnut-pie-chart
---
###Introduction
Pie and doughnut charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
They are excellent at showing the relational proportions between data.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
// For a pie chart
var myPieChart = new Chart(ctx[0]).Pie(data,options);
// And for a doughnut chart
var myDoughnutChart = new Chart(ctx[1]).Doughnut(data,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"
}
]
```
For a pie chart, you must pass in an array of objects with a value and an optional color property. The value attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
### Chart options
These are the customisation options specific to Pie & Doughnut charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//Number - The percentage of the chart that we cut out of the middle
percentageInnerCutout : 50, // This is 0 for Pie charts
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
{% endraw %}
}
```
You can override these for your `Chart` instance by passing a second argument into the `Doughnut` method as an object with the keys you want to override.
For example, we could have a doughnut chart that animates by scaling out from the centre like so:
```javascript
new Chart(ctx).Doughnut(data, {
animateScale: true
});
// This will create a chart with all of the default options, merged from the global config,
// and the Doughnut chart defaults but this particular instance will have `animateScale` set to `true`.
```
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.Doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.Pie`, with the only difference being `percentageInnerCutout` being set to 0.
### 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 the same position of that event.
```javascript
canvas.onclick = function(evt){
var activePoints = myDoughnutChart.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
myDoughnutChart.segments[1].value = 10;
// Would update the first dataset's value of 'Green' to be 10
myDoughnutChart.update();
// Calling update now animates the circumference of the segment 'Green' from 50 to 10.
// and transitions other segment widths
```
#### .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 optional second argument of 'index', this determines at what index the new segment should be inserted into the chart.
If you don't specify a color and highliht, one will be chosen from the global default array: segmentColorDefault and the corresponding segmentHighlightColorDefault. The index of the addded data is used to lookup a corresponding color from the defaults.
```javascript
// An object in the same format as the original data source
myDoughnutChart.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
myDoughnutChart.removeData();
// Other segments will update to fill the empty space left.
```
-91
Ver Arquivo
@@ -1,91 +0,0 @@
---
title: Polar Area Chart
anchor: polar-area-chart
---
### Introduction
Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
This type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
new Chart(ctx, {
data:data,
type: 'polarArea',
options: options
});
```
### Data structure
```javascript
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.
### Chart options
These are the customisation options specific to Polar Area charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
Name | Type | Default | Description
--- | --- | --- | ---
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.
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, {
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 `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`.
+187
Ver Arquivo
@@ -0,0 +1,187 @@
---
title: Advanced usage
anchor: advanced-usage
---
### Prototype methods
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.
```javascript
// For example:
var myLineChart = new Chart(ctx).Line(data);
```
#### .clear()
Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
```javascript
// Will clear the canvas that myLineChart is drawn on
myLineChart.clear();
// => returns 'this' for chainability
```
#### .stop()
Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.
```javascript
// Stops the charts animation loop at its current frame
myLineChart.stop();
// => returns 'this' for chainability
```
#### .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.
```javascript
// Resizes & redraws to fill its container element
myLineChart.resize();
// => returns 'this' for chainability
```
#### .destroy()
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.
```javascript
// Destroys a specific chart instance
myLineChart.destroy();
```
#### .toBase64Image()
This returns a base 64 encoded string of the chart in its current state.
```javascript
myLineChart.toBase64Image();
// => returns png data url of the image on the canvas
```
#### .generateLegend()
Returns an HTML string of a legend for that chart. The template for this legend is at `legendTemplate` in the chart options.
```javascript
myLineChart.generateLegend();
// => returns HTML string of a legend for this chart
```
### 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) {
// 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...
}
});
```
See files `sample/pie-customTooltips.html` and `sample/line-customTooltips.html` for examples on how to get started.
### Writing new chart types
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.
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.
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.
```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
},
// Used to draw something on the canvas
draw: function() {
}
});
// Now we can create a new instance of our chart, using the Chart.js API
new Chart(ctx).Scatter(data);
// initialize is now run
```
### Extending existing chart types
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.
```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);
}
});
// Creates a line chart in the same way
new Chart(ctx).LineAlt(data);
// but this logs 'My Line chart extension' in the console.
```
### Community extensions
- <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>
### Creating custom builds
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.
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:
```bash
npm install
npm install -g gulp
```
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-separated 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:
```bash
gulp build --types=Line,Radar,Bar
```
This will output to the `/custom` directory, and write two files, Chart.js, and Chart.min.js with only those chart types included.
-99
Ver Arquivo
@@ -1,99 +0,0 @@
---
title: Pie & Doughnut Charts
anchor: doughnut-pie-chart
---
###Introduction
Pie and doughnut charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
They are excellent at showing the relational proportions between data.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
// For a pie chart
var myPieChart = new Chart(ctx[0],{
type:'pie',
data: data,
options: options
});
// And for a doughnut chart
var myDoughnutChart = new Chart(ctx[1], {
type:'doughnut',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: [
"Red",
"Green",
"Yellow"
],
datasets: [
{
data: [300, 50, 100],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C"
],
hoverBackgroundColor: [
"#FF5A5E",
"#5AD3D1",
"#FFC870"
]
}]
};
```
For a pie chart, you must pass in an array of objects with a value and an optional color property. The value attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
### Chart options
These are the customisation options specific to Pie & Doughnut charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
Name | Type | Default | Description
--- | --- | --- | ---
cutoutPercentage | Number | 50 - for doughnut, 0 - for pie | The percentage of the chart that is cut out of the middle.
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 arced compared to straight when false.
*animation*.animateRotate | Boolean |true | If true, will animate the rotation of the chart.
*animation*.animateScale | Boolean | false | If true, will animate scaling the Doughnut from the centre.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
*legend*.onClick | Function | function(event, legendItem) {} ` | Handles clicking an individual legend item
You can override these for your `Chart` instance by passing a second argument into the `Doughnut` method as an object with the keys you want to override.
For example, we could have a doughnut chart that animates by scaling out from the centre like so:
```javascript
new Chart(ctx,{
type:"doughnut",
animation:{
animateScale:true
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Doughnut chart defaults but this particular instance will have `animateScale` set to `true`.
```
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.Doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.Pie`, with the only difference being `percentageInnerCutout` being set to 0.
-386
Ver Arquivo
@@ -1,386 +0,0 @@
---
title: Advanced usage
anchor: advanced-usage
---
### Prototype methods
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.
```javascript
// For example:
var myLineChart = new Chart(ctx, config);
```
#### .destroy()
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
// 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()
Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.
```javascript
// Stops the charts animation loop at its current frame
myLineChart.stop();
// => returns 'this' for chainability
```
#### .resize()
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
myLineChart.resize();
// => returns 'this' for chainability
```
#### .clear()
Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
```javascript
// Will clear the canvas that myLineChart is drawn on
myLineChart.clear();
// => returns 'this' for chainability
```
#### .toBase64Image()
This returns a base 64 encoded string of the chart in it's current state.
```javascript
myLineChart.toBase64Image();
// => returns png data url of the image on the canvas
```
#### .generateLegend()
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
```javascript
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, {
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...
}
}
}
});
```
See `sample/line-customTooltips.html` for examples on how to get started.
### Writing new scale types
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
```
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);
```
To use the new scale, simply pass in the string key to the config when creating a chart.
```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
}]
}
}
})
```
#### Scale Properties
Scale instances are given the following properties during the fitting process.
```javascript
{
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,
},
// 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
{
// Determines the data limits. Should set this.min and this.max to be the data max/min
determineDataLimits: function() {},
// 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.
```javascript
{
// 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, {
// 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`
#### 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.
### 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:
```bash
npm install
npm install -g gulp
```
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.
```bash
gulp build
```
Ver Arquivo
+70 -149
Ver Arquivo
@@ -13,102 +13,52 @@ var gulp = require('gulp'),
fs = require('fs'),
package = require('./package.json'),
bower = require('./bower.json'),
karma = require('gulp-karma'),
umd = require('gulp-umd');
livereload = require('gulp-livereload');
var srcDir = './src/';
var testDir = './test/';
/*
* Usage : gulp build --types=Bar,Line,Doughnut
* Output: - A built Chart.js file with Core and types Bar, Line and Doughnut concatenated together
* - A minified version of this code, in Chart.min.js
* Usage : gulp build --types=Bar,Line,Doughnut
* Output: - A built Chart.js file with Core and types Bar, Line and Doughnut concatenated together
* - A minified version of this code, in Chart.min.js
*/
var srcFiles = [
'./node_modules/color/dist/color.min.js',
'./src/core/core.js',
'./src/core/core.helpers.js',
'./src/core/core.element.js',
'./src/core/**',
'./src/controllers/**',
'./src/scales/**',
'./src/elements/**',
'./src/charts/**',
];
gulp.task('build', function(){
var preTestFiles = [
'./node_modules/moment/min/moment.min.js',
];
var testFiles = [
'./test/mockContext.js',
'./test/*.js'
];
gulp.task('build', buildTask);
gulp.task('coverage', coverageTask);
gulp.task('watch', watchTask);
gulp.task('bump', bumpTask);
gulp.task('release', ['build'], releaseTask);
gulp.task('jshint', jshintTask);
gulp.task('test', ['jshint', 'validHTML', 'unittest']);
gulp.task('size', ['library-size', 'module-sizes']);
gulp.task('server', serverTask);
gulp.task('validHTML', validHTMLTask);
gulp.task('unittest', unittestTask);
gulp.task('unittestWatch', unittestWatchTask);
gulp.task('library-size', librarySizeTask);
gulp.task('module-sizes', moduleSizesTask);
gulp.task('_open', _openTask);
gulp.task('dev', ['server', 'default']);
gulp.task('default', ['build', 'watch']);
function buildTask() {
var isCustom = !!(util.env.types),
// Default to all of the chart types, with Chart.Core first
var srcFiles = [FileName('Core')],
isCustom = !!(util.env.types),
outputDir = (isCustom) ? 'custom' : '.';
if (isCustom){
util.env.types.split(',').forEach(function(type){ return srcFiles.push(FileName(type));});
}
else{
// Seems gulp-concat remove duplicates - nice!
// So we can use this to sort out dependency order - aka include Core first!
srcFiles.push(srcDir+'*');
}
return gulp.src(srcFiles)
.pipe(concat('Chart.js'))
.pipe(replace('{{ version }}', package.version))
.pipe(umd({
// We want a global always to ensure that we match previous behaviour
templateSource:
";(function(root, factory) {\n"+
" if (typeof define === 'function' && define.amd) {\n"+
" define(<%= amd %>, factory);\n"+
" } else if (typeof exports === 'object') {\n"+
" module.exports = factory.call(root,<%= cjs %>);\n"+
" } else {\n"+
" root.<%= namespace %> = factory.call(root,<%= global %>);\n"+
" }\n"+
"}(this, function(<%= param %>) {\n"+
"<%= contents %>\n"+
"return <%= exports %>;\n"+
"}));\n",
dependencies: function() {
return ['moment']
}
}))
.pipe(gulp.dest(outputDir))
.pipe(uglify({
preserveComments: 'some'
}))
.pipe(uglify({preserveComments:'some'}))
.pipe(concat('Chart.min.js'))
.pipe(gulp.dest(outputDir));
}
function FileName(moduleName){
return srcDir+'Chart.'+moduleName+'.js';
}
});
/*
* Usage : gulp bump
* Prompts: Version increment to bump
* Output: - New version number written into package.json & bower.json
* Usage : gulp bump
* Prompts: Version increment to bump
* Output: - New version number written into package.json & bower.json
*/
function bumpTask(complete) {
gulp.task('bump', function(complete){
util.log('Current version:', util.colors.cyan(package.version));
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType) {
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType){
return versionType + ' (v' + semver.inc(package.version, versionType) + ')';
});
inquirer.prompt({
@@ -116,7 +66,7 @@ function bumpTask(complete) {
name: 'version',
message: 'What version update would you like?',
choices: choices
}, function(res) {
}, function(res){
var increment = res.version.split(' ')[0],
newVersion = semver.inc(package.version, increment);
@@ -130,97 +80,68 @@ function bumpTask(complete) {
complete();
});
}
});
function releaseTask() {
gulp.task('release', ['build'], function(){
exec('git tag -a v' + package.version);
}
});
function jshintTask() {
return gulp.src(srcDir + '**/*.js')
gulp.task('jshint', function(){
return gulp.src(srcDir + '*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
}
});
function validHTMLTask() {
gulp.task('valid', function(){
return gulp.src('samples/*.html')
.pipe(htmlv());
}
.pipe(htmlv());
});
function unittestTask() {
var files = srcFiles.slice();
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.conf.ci.js',
action: 'run'
}));
}
function unittestWatchTask() {
var files = srcFiles.slice();
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.conf.js',
action: 'watch'
}));
}
function coverageTask() {
var files = srcFiles.slice();
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.coverage.conf.js',
action: 'run'
}));
}
function librarySizeTask() {
gulp.task('library-size', function(){
return gulp.src('Chart.min.js')
.pipe(size({
gzip: true
}));
}
});
function moduleSizesTask() {
gulp.task('module-sizes', function(){
return gulp.src(srcDir + '*.js')
.pipe(uglify({
preserveComments: 'some'
}))
.pipe(size({
showFiles: true,
gzip: true
}));
}
.pipe(uglify({preserveComments:'some'}))
.pipe(size({
showFiles: true,
gzip: true
}));
});
function watchTask() {
if (util.env.test) {
return gulp.watch('./src/**', ['build', 'unittest', 'unittestWatch']);
}
return gulp.watch('./src/**', ['build']);
}
gulp.task('watch', function(){
gulp.watch('./src/*', ['build']);
function serverTask() {
livereload.listen(35729);
var reloadPage = function (evt) {
livereload.changed(evt.path);
};
gulp.watch(['Chart.js', 'samples/*'], reloadPage);
});
gulp.task('test', ['jshint', 'valid']);
gulp.task('size', ['library-size', 'module-sizes']);
gulp.task('default', ['build', 'watch']);
gulp.task('server', function(){
connect.server({
port: 8000
});
}
});
// Convenience task for opening the project straight from the command line
function _openTask() {
gulp.task('_open', function(){
exec('open http://localhost:8000');
exec('subl .');
}
});
gulp.task('dev', ['server', 'default']);
-19
Ver Arquivo
@@ -1,19 +0,0 @@
module.exports = function(config) {
var configuration = {
browsers: ['Firefox'],
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
frameworks: ['jasmine'],
reporters: ['progress', 'html'],
};
if (process.env.TRAVIS) {
configuration.browsers.push('Chrome_travis_ci');
}
config.set(configuration);
};
-7
Ver Arquivo
@@ -1,7 +0,0 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox'],
frameworks: ['jasmine'],
reporters: ['progress', 'html'],
});
};
-18
Ver Arquivo
@@ -1,18 +0,0 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox'],
coverageReporter: {
type: 'html',
dir: 'coverage/'
},
frameworks: ['jasmine'],
preprocessors: {
'src/**/*.js': ['coverage']
},
reporters: ['progress', 'coverage'],
});
};
+8 -20
Ver Arquivo
@@ -2,41 +2,29 @@
"name": "chart.js",
"homepage": "http://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "2.0.0-beta2",
"version": "1.1.1",
"main": "Chart.js",
"repository": {
"type": "git",
"url": "https://github.com/nnnick/Chart.js.git"
},
"license": "MIT",
"dependences": {},
"devDependencies": {
"color": "git://github.com/chartjs/color",
"gulp": "3.5.x",
"gulp": "3.9.x",
"gulp-concat": "~2.1.x",
"gulp-connect": "~2.0.5",
"gulp-html-validator": "^0.0.2",
"gulp-jshint": "~1.5.1",
"gulp-karma": "0.0.4",
"gulp-replace": "^0.4.0",
"gulp-size": "~0.4.0",
"gulp-uglify": "~0.2.x",
"gulp-uglify": "~1.5.x",
"gulp-util": "~2.2.x",
"gulp-html-validator": "^0.0.2",
"inquirer": "^0.5.1",
"jasmine": "^2.3.2",
"jasmine-core": "^2.3.4",
"jquery": "^2.1.4",
"karma": "^0.12.37",
"karma-chrome-launcher": "^0.2.0",
"karma-coverage": "^0.5.1",
"karma-firefox-launcher": "^0.1.6",
"karma-jasmine": "^0.3.6",
"karma-jasmine-html-reporter": "^0.1.8",
"semver": "^3.0.1",
"gulp-umd": "~0.2.0"
"gulp-livereload": "^3.8.0"
},
"spm": {
"main": "Chart.js"
},
"dependencies": {
"moment": "^2.10.6"
}
}
}
-161
Ver Arquivo
@@ -1,161 +0,0 @@
<!doctype html>
<html>
<head>
<title> Animation Callbacks </title>
<script src="../../Chart.js"></script>
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width: 100 %;">
<canvas id="canvas" style="width: 100 % ;height: 100 %"></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 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: {
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) {
config.data.labels.push('dataset #' + config.data.labels.length);
$.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>
-91
Ver Arquivo
@@ -1,91 +0,0 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Multi Axis</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../Chart.js"></script>
</head>
<body>
<div style="width: 50%">
<canvas id="canvas" height="450" width="600"></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,
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>
-73
Ver Arquivo
@@ -1,73 +0,0 @@
<!doctype html>
<html>
<head>
<title>Stacked Bar Chart</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../Chart.js"></script>
</head>
<body>
<div style="width: 50%">
<canvas id="canvas" height="450" width="600"></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: {
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>
+37 -144
Ver Arquivo
@@ -1,152 +1,45 @@
<!doctype html>
<html>
<head>
<title>Bar Chart</title>
<script src="../Chart.js"></script>
</head>
<body>
<div style="width: 50%">
<canvas id="canvas" height="450" width="600"></canvas>
</div>
<head>
<title>Bar Chart</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../Chart.js"></script>
<style type="text/css">
canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<div id="container" style="width: 50%; height: 25%;">
<canvas id="canvas" height="450" width="600"></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>
<button id="show">Show</button>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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)';
};
<script>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
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()]
}, {
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()]
}]
var barChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,0.8)",
highlightFill : "rgba(151,187,205,0.75)",
highlightStroke : "rgba(151,187,205,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myBar.generateLegend());
}
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Our 3 Favorite Datasets'
}
}
});
updateLegend();
};
$('#randomizeData').click(function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
dataset.data = dataset.data.map(function() {
return zero ? 0.0 : randomScalingFactor();
});
});
window.myBar.update();
updateLegend();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + barChartData.datasets.length,
backgroundColor: randomColor(),
data: []
};
for (var index = 0; index < barChartData.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
barChartData.datasets.push(newDataset);
window.myBar.update();
updateLegend();
});
$('#addData').click(function() {
if (barChartData.datasets.length > 0) {
barChartData.labels.push('data #' + barChartData.labels.length);
for (var index = 0; index < barChartData.datasets.length; ++index) {
//window.myBar.addData(randomScalingFactor(), index);
barChartData.datasets[index].data.push(randomScalingFactor());
}
window.myBar.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
barChartData.datasets.splice(0, 1);
window.myBar.update();
updateLegend();
});
$('#removeData').click(function() {
barChartData.labels.splice(-1, 1); // remove the label first
barChartData.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myBar.update();
updateLegend();
});
$('#show').click(function() {
document.getElementById('container').style.display = '';
});
</script>
</body>
}
window.onload = function(){
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
responsive : true
});
}
</script>
</body>
</html>
-206
Ver Arquivo
@@ -1,206 +0,0 @@
<!doctype html>
<html>
<head>
<title>Bar Chart</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../Chart.js"></script>
<style type="text/css">
canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<div id="container" style="width: 100%; height: 25%;">
<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>
<button id="show">Show</button>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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 bubbleChartData = {
animation: {
duration: 10000
},
datasets: [{
label: "My First dataset",
backgroundColor: randomColor(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}]
}, {
label: "My Second dataset",
backgroundColor: randomColor(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}]
}]
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myChart.generateLegend());
}
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myChart = new Chart(ctx, {
type: 'bubble',
data: bubbleChartData,
options: {
responsive: true,
}
});
updateLegend();
};
$('#randomizeData').click(function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(bubbleChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
dataset.data = dataset.data.map(function() {
return {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
};
});
});
window.myChart.update();
updateLegend();
});
$('#addDataset').click(function() {
var newDataset = {
backgroundColor: randomColor(),
data: []
};
for (var index = 0; index < bubbleChartData.datasets[0].data.length; ++index) {
newDataset.data.push({
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
});
}
bubbleChartData.datasets.push(newDataset);
window.myChart.update();
updateLegend();
});
$('#addData').click(function() {
if (bubbleChartData.datasets.length > 0) {
for (var index = 0; index < bubbleChartData.datasets.length; ++index) {
//window.myChart.addData(randomScalingFactor(), index);
bubbleChartData.datasets[index].data.push({
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
});
}
window.myChart.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
bubbleChartData.datasets.splice(0, 1);
window.myChart.update();
updateLegend();
});
$('#removeData').click(function() {
bubbleChartData.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myChart.update();
updateLegend();
});
$('#show').click(function() {
document.getElementById('container').style.display = '';
});
</script>
</body>
</html>
-69
Ver Arquivo
@@ -1,69 +0,0 @@
<!doctype html>
<html>
<head>
<title>Combo Bar-Line Chart</title>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../Chart.js"></script>
</head>
<body>
<div style="width: 50%">
<canvas id="canvas" height="450" width="600"></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,
}
});
};
$('#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>
+58
Ver Arquivo
@@ -0,0 +1,58 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../src/Chart.Core.js"></script>
<script src="../src/Chart.Doughnut.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
#canvas-holder{
width:30%;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="500" height="500"/>
</div>
<script>
var doughnutData = [
{
value: 1,
label: "One"
},
{
value: 2,
label: "Two"
},
{
value: 3,
label: "Three"
},
{
value: 4,
label: "Four"
},
{
value: 5,
label: "Five"
}
];
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
};
</script>
</body>
</html>
+56 -188
Ver Arquivo
@@ -1,199 +1,67 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../Chart.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
#canvas-holder{
width:30%;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="500" height="500"/>
</div>
<head>
<title>Doughnut Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
body {
padding: 0;
margin: 0;
}
#canvas-holder {
width: 30%;
}
</style>
</head>
<body>
<div id="canvas-holder" style="width:100%">
<canvas id="chart-area" />
</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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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') + ')';
};
<script>
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
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",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Our Favorite Datasets'
}
}
};
var doughnutData = [
{
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"
}
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myDoughnut.generateLegend());
}
];
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config);
console.log(window.myDoughnut);
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
};
updateLegend();
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
dataset.backgroundColor = dataset.backgroundColor.map(function() {
return randomColor(0.7);
});
});
window.myDoughnut.update();
updateLegend();
});
$('#addDataset').click(function() {
var newDataset = {
backgroundColor: [],
data: [],
label: 'New dataset ' + config.data.datasets.length,
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
newDataset.backgroundColor.push(randomColor(0.7));
}
config.data.datasets.push(newDataset);
window.myDoughnut.update();
updateLegend();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('data #' + config.data.labels.length);
$.each(config.data.datasets, function(index, dataset) {
dataset.data.push(randomScalingFactor());
dataset.backgroundColor.push(randomColor(0.7));
});
window.myDoughnut.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myDoughnut.update();
updateLegend();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
dataset.backgroundColor.pop();
});
window.myDoughnut.update();
updateLegend();
});
</script>
</body>
</script>
</body>
</html>
+99 -114
Ver Arquivo
@@ -2,143 +2,128 @@
<html>
<head>
<title>Line Chart with Custom Tooltips</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
<title>Line Chart with Custom Tooltips</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
#canvas-holder1 {
width: 300px;
margin: 20px auto;
width: 300px;
margin: 20px auto;
}
#canvas-holder2 {
width: 50%;
margin: 20px 25%;
width: 50%;
margin: 20px 25%;
}
#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);
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
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>
.chartjs-tooltip-key{
display:inline-block;
width:10px;
height:10px;
}
</style>
</head>
<body>
<div id="canvas-holder1">
<canvas id="chart1" width="300" height="100" />
</div>
<script>
window.count = 0;
<div id="canvas-holder1">
<canvas id="chart1" width="300" height="30" />
</div>
<div id="canvas-holder2">
<canvas id="chart2" width="450" height="600" />
</div>
<div id="chartjs-tooltip"></div>
<script>
Chart.defaults.global.pointHitDetectionRadius = 1;
var customTooltips = function(tooltip) {
Chart.defaults.global.customTooltips = function(tooltip) {
console.log(window.count++, tooltip);
var tooltipEl = $('#chartjs-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;
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
}
var offset = $(this._chart.canvas).offset();
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
width: tooltip.width ? (tooltip.width + 'px') : 'auto',
left: offset.left + tooltip.x + 'px',
top: offset.top + top + 'px',
fontFamily: tooltip._fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip._fontStyle,
padding: tooltip.yPadding + 'px ' + tooltip.xPadding + 'px',
});
var innerHtml = '';
for (var i = tooltip.labels.length - 1; i >= 0; i--) {
innerHtml += [
'<div class="chartjs-tooltip-section">',
' <span class="chartjs-tooltip-key" style="background-color:' + tooltip.legendColors[i].fill + '"></span>',
' <span class="chartjs-tooltip-value">' + tooltip.labels[i] + '</span>',
'</div>'
].join('');
}
tooltipEl.html(innerHtml);
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
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()]
}]
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
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: {
tooltips: {
enabled: false,
custom: customTooltips
}
}
});
var ctx1 = document.getElementById("chart1").getContext("2d");
window.myLine = new Chart(ctx1).Line(lineChartData, {
showScale: false,
pointDot : true,
responsive: true
});
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine = new Chart(ctx2).Line(lineChartData, {
responsive: true
});
};
</script>
</script>
</body>
</html>
-182
Ver Arquivo
@@ -1,182 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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 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",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
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: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
}
}]
},
title: {
display: true,
text: 'Our 4 Favorite Datasets'
}
}
};
$.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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
-166
Ver Arquivo
@@ -1,166 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:50%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<script>
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,
scales: {
xAxes: [{
display: true,
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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push(randomScalingFactor());
}
window.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
-92
Ver Arquivo
@@ -1,92 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart Multiple Axes</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
</head>
<body>
<div style="width:50%;">
<canvas id="canvas" style="width:100%;height:100%"></canvas>
</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()],
yAxisID: "y-axis-1",
}, {
label: "My Second dataset",
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;
});
console.log(lineChartData);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = Chart.Line(ctx, {
data: lineChartData,
options: {
responsive: true,
hoverMode: 'label',
stacked: false,
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,
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",
// grid line settings
gridLines: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
}],
}
}
});
};
$('#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()];
window.myLine.update();
});
</script>
</body>
</html>
-175
Ver Arquivo
@@ -1,175 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<script>
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],
}, {
label: "My Second dataset",
// Skip first and last points
data: [NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN],
}]
},
options: {
responsive: true,
tooltips: {
mode: 'label',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
-174
Ver Arquivo
@@ -1,174 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<script>
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,
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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
-144
Ver Arquivo
@@ -1,144 +0,0 @@
<!doctype html>
<html>
<head>
<title>Chart with xAxis Filtering</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:50%;">
<canvas id="canvas" style="width:100%;height:100%"></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 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 is a long month", "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,
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;
});
console.log(config.data);
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) {
config.data.labels.push('dataset #' + config.data.labels.length);
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>
+45 -220
Ver Arquivo
@@ -1,229 +1,54 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
</head>
<body>
<div style="width:30%">
<div>
<canvas id="canvas" height="450" width="600"></canvas>
</div>
</div>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<script>
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') + ')';
};
<script>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
label: "My First dataset",
fillColor : "rgba(220,220,220,0.2)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(220,220,220,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
},
{
label: "My Second dataset",
fillColor : "rgba(151,187,205,0.2)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(151,187,205,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
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: [],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
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).Line(lineChartData, {
responsive: true
});
}
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</script>
</body>
</html>
+156
Ver Arquivo
@@ -0,0 +1,156 @@
<!doctype html>
<html>
<head>
<title>Pie Chart with Custom Tooltips</title>
<script src="../Chart.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;
padding: 3px;
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.below {
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.below:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 0 8px 8px 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above {
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 8px 8px 0 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
top: 100%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area1" width="50" height="50" />
</div>
<div id="canvas-holder">
<canvas id="chart-area2" width="300" height="300" />
</div>
<div id="chartjs-tooltip"></div>
<script>
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var pieData = [{
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"
}];
window.onload = function() {
var ctx1 = document.getElementById("chart-area1").getContext("2d");
window.myPie = new Chart(ctx1).Pie(pieData);
var ctx2 = document.getElementById("chart-area2").getContext("2d");
window.myPie = new Chart(ctx2).Pie(pieData);
};
</script>
</body>
</html>
+47 -111
Ver Arquivo
@@ -1,122 +1,58 @@
<!doctype html>
<html>
<head>
<title>Pie Chart</title>
<script src="../Chart.js"></script>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="300" height="300"/>
</div>
<head>
<title>Pie Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:50%">
<canvas id="chart-area" width="300" height="300" />
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</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') + ')';
};
<script>
var config = {
type: 'pie',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
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",
],
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true
}
};
var pieData = [
{
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"
}
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
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.backgroundColor[i] = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
});
});
window.myPie.update();
});
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPie = new Chart(ctx).Pie(pieData);
};
$('#addDataset').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()]
};
config.data.datasets.push(newDataset);
window.myPie.update();
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myPie.update();
});
</script>
</body>
</script>
</body>
</html>
+49 -120
Ver Arquivo
@@ -1,131 +1,60 @@
<!doctype html>
<html>
<head>
<title>Polar Area Chart</title>
<script src="../Chart.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:30%">
<canvas id="chart-area" width="300" height="300"/>
</div>
<head>
<title>Polar Area Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="canvas-holder" style="width:100%">
<canvas id="chart-area"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<div>
<h3>Legend</h3>
<div id="legendContainer">
<script>
</div>
</div>
<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 polarData = [
{
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 config = {
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Our Favorite Dataset'
},
scale: {
ticks: {
beginAtZero: true
},
reverse: false
},
animateRotate:false
}
};
];
window.onload = function() {
var ctx = document.getElementById("chart-area");
window.myPolarArea = Chart.PolarArea(ctx, config);
updateLegend();
};
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPolarArea = new Chart(ctx).PolarArea(polarData, {
responsive:true
});
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myPolarArea.generateLegend());
}
$('#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();
});
});
window.myPolarArea.update();
updateLegend();
});
$('#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.backgroundColor.push(randomColor());
dataset.data.push(randomScalingFactor());
});
window.myPolarArea.update();
updateLegend();
}
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.backgroundColor.pop();
dataset.data.pop();
});
window.myPolarArea.update();
updateLegend();
});
</script>
</body>
</script>
</body>
</html>
-152
Ver Arquivo
@@ -1,152 +0,0 @@
<!doctype html>
<html>
<head>
<title>Radar Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width:50%">
<canvas id="canvas" height="450" width="450"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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)",
hoverPointBackgroundColor: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
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)",
hoverPointBackgroundColor: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN]
}]
},
options: {
elements: {
line: {
tension: 0.0,
}
},
scale: {
beginAtZero: true,
reverse: false
}
}
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myRadar.generateLegend());
}
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
updateLegend();
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
updateLegend();
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.data.pop();
});
window.myRadar.update();
updateLegend();
});
</script>
</body>
</html>
+46 -143
Ver Arquivo
@@ -1,150 +1,53 @@
<!doctype html>
<html>
<head>
<title>Radar Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
</head>
<body>
<div style="width:30%">
<canvas id="canvas" height="450" width="450"></canvas>
</div>
<head>
<title>Radar Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width:100%">
<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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
<script>
var radarChartData = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65,59,90,81,56,55,40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28,48,40,19,96,27,100]
}
]
};
</div>
</div>
<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: "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: [],
}, {
label: "My Second dataset",
backgroundColor: "rgba(151,187,205,0.2)",
pointBackgroundColor: "rgba(151,187,205,1)",
hoverPointBackgroundColor: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
},]
},
options: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Our 3 Favorite Datasets'
},
scale: {
reverse: false,
ticks: {
beginAtZero: true
}
}
}
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myRadar.generateLegend());
}
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
updateLegend();
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
updateLegend();
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.data.pop();
});
window.myRadar.update();
updateLegend();
});
</script>
</body>
window.onload = function(){
window.myRadar = new Chart(document.getElementById("canvas").getContext("2d")).Radar(radarChartData, {
responsive: true
});
}
</script>
</body>
</html>
-174
Ver Arquivo
@@ -1,174 +0,0 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
</head>
<body>
<div style="width:50%">
<div>
<canvas id="canvas" height="450" width="600" style="border: 1px solid red;"></canvas>
</div>
</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 scatterChartData = {
datasets: [{
label: "V(node2)",
data: [{
x: 1,
y: -1.711e-2,
}, {
x: 1.26,
y: -2.708e-2,
}, {
x: 1.58,
y: -4.285e-2,
}, {
x: 2.0,
y: -6.772e-2,
}, {
x: 2.51,
y: -1.068e-1,
}, {
x: 3.16,
y: -1.681e-1,
}, {
x: 3.98,
y: -2.635e-1,
}, {
x: 5.01,
y: -4.106e-1,
}, {
x: 6.31,
y: -6.339e-1,
}, {
x: 7.94,
y: -9.659e-1,
}, {
x: 10.00,
y: -1.445,
}, {
x: 12.6,
y: -2.110,
}, {
x: 15.8,
y: -2.992,
}, {
x: 20.0,
y: -4.102,
}, {
x: 25.1,
y: -5.429,
}, {
x: 31.6,
y: -6.944,
}, {
x: 39.8,
y: -8.607,
}, {
x: 50.1,
y: -1.038e1,
}, {
x: 63.1,
y: -1.223e1,
}, {
x: 79.4,
y: -1.413e1,
}, {
x: 100.00,
y: -1.607e1,
}, {
x: 126,
y: -1.803e1,
}, {
x: 158,
y: -2e1,
}, {
x: 200,
y: -2.199e1,
}, {
x: 251,
y: -2.398e1,
}, {
x: 316,
y: -2.597e1,
}, {
x: 398,
y: -2.797e1,
}, {
x: 501,
y: -2.996e1,
}, {
x: 631,
y: -3.196e1,
}, {
x: 794,
y: -3.396e1,
}, {
x: 1000,
y: -3.596e1,
},]
}]
};
$.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: {
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom',
ticks: {
userCallback: function(tick) {
var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));
if (remain === 1 || remain === 2 || remain === 5) {
return tick.toString() + "Hz";
}
return '';
},
},
scaleLabel: {
labelString: 'Frequency',
display: true,
}
}],
yAxes: [{
type: 'linear',
ticks: {
userCallback: function(tick) {
return tick.toString() + "dB";
}
},
scaleLabel: {
labelString: 'Voltage',
display: true
}
}]
}
}
});
};
</script>
</body>
</html>
-177
Ver Arquivo
@@ -1,177 +0,0 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart Multi Axis</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width:50%">
<div>
<canvas id="canvas" height="450" width="600"></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;
});
console.log(scatterChartData);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
responsive: true,
hoverMode: 'single',
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>
-168
Ver Arquivo
@@ -1,168 +0,0 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width:50%">
<div>
<canvas id="canvas" height="450" width="600"></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;
});
console.log(scatterChartData);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
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>
-180
Ver Arquivo
@@ -1,180 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../Chart.js"></script>
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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 config = {
type: 'bar',
data: {
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
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'line',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, ]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: "time",
display: true,
time: {
format: timeFormat,
// round: 'day'
}
}],
},
}
};
$.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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(
myLine.scales['x-axis-0'].labelMoments[myLine.scales['x-axis-0'].labelMoments.length - 1].add(1, 'day')
.format('MM/DD/YYYY')
);
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push(randomScalingFactor());
}
window.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
config.data.datasets[datasetIndex].data.pop();
});
window.myLine.update();
updateLegend();
});
</script>
</body>
</html>
-172
Ver Arquivo
@@ -1,172 +0,0 @@
<!doctype html>
<html>
<head>
<title>Time Scale Point Data</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../Chart.js"></script>
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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();
}
function newDateString(days) {
return moment().add(days, 'd').format();
}
var config = {
type: 'line',
data: {
datasets: [{
label: "Dataset with string point data",
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(2),
y: randomScalingFactor()
}, {
x: newDateString(4),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}],
fill: false
}, {
label: "Dataset with date object point data",
data: [{
x: newDate(0),
y: randomScalingFactor()
}, {
x: newDate(2),
y: randomScalingFactor()
}, {
x: newDate(4),
y: randomScalingFactor()
}, {
x: newDate(5),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: "time",
display: true,
scaleLabel: {
display: true,
labelString: 'Date'
}
}, ],
yAxes: [{
display: true,
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);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
$.each(dataset.data, function(j, dataObj) {
dataObj.y = randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var newTime = myLine.scales['x-axis-0'].labelMoments[0][myLine.scales['x-axis-0'].labelMoments[0].length - 1]
.clone()
.add(1, 'day')
.format('MM/DD/YYYY HH:mm');
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push({
x: newTime,
y: randomScalingFactor()
});
}
window.myLine.update();
updateLegend();
}
});
$('#removeData').click(function() {
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
updateLegend();
});
</script>
</body>
</html>
-211
Ver Arquivo
@@ -1,211 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../Chart.js"></script>
<script src="../../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<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();
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
function newTimestamp(days) {
return moment().add(days, 'd').unix();
}
var config = {
type: 'line',
data: {
labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
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()],
}, {
label: "Dataset with point data",
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}, {
x: newDateString(7),
y: randomScalingFactor()
}, {
x: newDateString(15),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
scales: {
xAxes: [{
type: "time",
time: {
format: timeFormat,
// round: 'day'
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}, ],
yAxes: [{
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;
});
console.log(config.data);
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
$.each(dataset.data, function(j, dataObj) {
if (typeof dataObj === 'object') {
dataObj.y = randomScalingFactor();
} else {
dataset.data[j] = randomScalingFactor();
}
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push(newDate(config.data.labels.length));
for (var index = 0; index < config.data.datasets.length; ++index) {
if (typeof config.data.datasets[index].data[0] === "object") {
config.data.datasets[index].data.push({
x: newDate(config.data.datasets[index].data.length),
y: randomScalingFactor(),
})
} else {
config.data.datasets[index].data.push(randomScalingFactor());
}
}
window.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
-191
Ver Arquivo
@@ -1,191 +0,0 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<style>
canvas {
-webkit-box-shadow: 0 0 20px 0 rgba(0, 0, 0, .5);
}
</style>
</head>
<body>
<div style="width:100%;">
<canvas id="canvas" style="width:100%;height:100%"></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>
<div>
<h3>Legend</h3>
<div id="legendContainer">
</div>
</div>
<script>
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,
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: '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);
updateLegend();
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myLine.generateLegend());
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
$('#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.myLine.update();
updateLegend();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
updateLegend();
});
$('#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();
updateLegend();
});
</script>
</body>
</html>
+305
Ver Arquivo
@@ -0,0 +1,305 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero : true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 1,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span class=\"<%=name.toLowerCase()%>-legend-icon\" style=\"background-color:<%=datasets[i].fillColor%>\"></span><span class=\"<%=name.toLowerCase()%>-legend-text\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
};
Chart.Type.extend({
name: "Bar",
defaults : defaultConfig,
initialize: function(data){
//Expose options as a scope variable here so we can access it in the ScaleClass
var options = this.options;
this.ScaleClass = Chart.Scale.extend({
offsetGridLines : true,
calculateBarX : function(datasetCount, datasetIndex, barIndex){
//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
var xWidth = this.calculateBaseWidth(),
xAbsolute = this.calculateX(barIndex) - (xWidth/2),
barWidth = this.calculateBarWidth(datasetCount);
return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
},
calculateBaseWidth : function(){
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
},
calculateBarWidth : function(datasetCount){
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
return (baseWidth / datasetCount);
}
});
this.datasets = [];
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
this.eachBars(function(bar){
bar.restore(['fillColor', 'strokeColor']);
});
helpers.each(activeBars, function(activeBar){
if (activeBar) {
activeBar.fillColor = activeBar.highlightFill;
activeBar.strokeColor = activeBar.highlightStroke;
}
});
this.showTooltip(activeBars);
});
}
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.BarClass = Chart.Rectangle.extend({
strokeWidth : this.options.barStrokeWidth,
showStroke : this.options.barShowStroke,
ctx : this.chart.ctx
});
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset,datasetIndex){
var datasetObject = {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
bars : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
datasetObject.bars.push(new this.BarClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
strokeColor : (typeof dataset.strokeColor == 'object') ? dataset.strokeColor[index] : dataset.strokeColor,
fillColor : (typeof dataset.fillColor == 'object') ? dataset.fillColor[index] : dataset.fillColor,
highlightFill : (dataset.highlightFill) ? (typeof dataset.highlightFill == 'object') ? dataset.highlightFill[index] : dataset.highlightFill : (typeof dataset.fillColor == 'object') ? dataset.fillColor[index] : dataset.fillColor,
highlightStroke : (dataset.highlightStroke) ? (typeof dataset.highlightStroke == 'object') ? dataset.highlightStroke[index] : dataset.highlightStroke : (typeof dataset.strokeColor == 'object') ? dataset.strokeColor[index] : dataset.strokeColor
}));
},this);
},this);
this.buildScale(data.labels);
this.BarClass.prototype.base = this.scale.endPoint;
this.eachBars(function(bar, index, datasetIndex){
helpers.extend(bar, {
width : this.scale.calculateBarWidth(this.datasets.length),
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
y: this.scale.endPoint
});
bar.save();
}, this);
this.render();
},
update : function(){
this.scale.update();
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor', 'strokeColor']);
});
this.eachBars(function(bar){
bar.save();
});
this.render();
},
eachBars : function(callback){
helpers.each(this.datasets,function(dataset, datasetIndex){
helpers.each(dataset.bars, callback, this, datasetIndex);
},this);
},
getBarsAtEvent : function(e){
var barsArray = [],
eventPosition = helpers.getRelativePosition(e),
datasetIterator = function(dataset){
barsArray.push(dataset.bars[barIndex]);
},
barIndex;
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
helpers.each(this.datasets, datasetIterator);
return barsArray;
}
}
}
return barsArray;
},
buildScale : function(labels){
var self = this;
var dataTotal = function(){
var values = [];
self.eachBars(function(bar){
values.push(bar.value);
});
return values;
};
var scaleOptions = {
templateString : this.options.scaleLabel,
height : this.chart.height,
width : this.chart.width,
ctx : this.chart.ctx,
textColor : this.options.scaleFontColor,
fontSize : this.options.scaleFontSize,
fontStyle : this.options.scaleFontStyle,
fontFamily : this.options.scaleFontFamily,
valuesCount : labels.length,
beginAtZero : this.options.scaleBeginAtZero,
integersOnly : this.options.scaleIntegersOnly,
calculateYRange: function(currentHeight){
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly
);
helpers.extend(this, updatedRanges);
},
xLabels : labels,
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth : this.options.scaleLineWidth,
lineColor : this.options.scaleLineColor,
showHorizontalLines : this.options.scaleShowHorizontalLines,
showVerticalLines : this.options.scaleShowVerticalLines,
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
showLabels : this.options.scaleShowLabels,
display : this.options.showScale
};
if (this.options.scaleOverride){
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new this.ScaleClass(scaleOptions);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
helpers.each(valuesArray,function(value,datasetIndex){
//Add a new point for each piece of data, passing any required data to draw.
this.datasets[datasetIndex].bars.push(new this.BarClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
y: this.scale.endPoint,
width : this.scale.calculateBarWidth(this.datasets.length),
base : this.scale.endPoint,
strokeColor : this.datasets[datasetIndex].strokeColor,
fillColor : this.datasets[datasetIndex].fillColor
}));
},this);
this.scale.addXLabel(label);
//Then re-render the chart.
this.update();
},
removeData : function(){
this.scale.removeXLabel();
//Then re-render the chart.
helpers.each(this.datasets,function(dataset){
dataset.bars.shift();
},this);
this.update();
},
reflow : function(){
helpers.extend(this.BarClass.prototype,{
y: this.scale.endPoint,
base : this.scale.endPoint
});
var newScaleProps = helpers.extend({
height : this.chart.height,
width : this.chart.width
});
this.scale.update(newScaleProps);
},
draw : function(ease){
var easingDecimal = ease || 1;
this.clear();
var ctx = this.chart.ctx;
this.scale.draw(easingDecimal);
//Draw all the bars for each dataset
helpers.each(this.datasets,function(dataset,datasetIndex){
helpers.each(dataset.bars,function(bar,index){
if (bar.hasValue()){
bar.base = this.scale.endPoint;
//Transition then draw
bar.transition({
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
y : this.scale.calculateY(bar.value),
width : this.scale.calculateBarWidth(this.datasets.length)
}, easingDecimal).draw();
}
},this);
},this);
}
});
}).call(this);
Arquivo executável
+2249
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+194
Ver Arquivo
@@ -0,0 +1,194 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//The percentage of the chart that we cut out of the middle.
percentageInnerCutout : 50,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span class=\"<%=name.toLowerCase()%>-legend-icon\" style=\"background-color:<%=segments[i].fillColor%>\"></span><span class=\"<%=name.toLowerCase()%>-legend-text\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
};
Chart.Type.extend({
//Passing in a name registers this chart in the Chart namespace
name: "Doughnut",
//Providing a defaults will also register the defaults in the chart namespace
defaults : defaultConfig,
//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){
//Declare segments as a static property to prevent inheriting across the Chart type prototype
this.segments = [];
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
this.SegmentArc = Chart.Arc.extend({
ctx : this.chart.ctx,
x : this.chart.width/2,
y : this.chart.height/2
});
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
helpers.each(this.segments,function(segment){
segment.restore(["fillColor"]);
});
helpers.each(activeSegments,function(activeSegment){
activeSegment.fillColor = activeSegment.highlightColor;
});
this.showTooltip(activeSegments);
});
}
this.calculateTotal(data);
helpers.each(data,function(datapoint, index){
if (!datapoint.color) {
datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';
}
this.addData(datapoint, index, true);
},this);
this.render();
},
getSegmentsAtEvent : function(e){
var segmentsArray = [];
var location = helpers.getRelativePosition(e);
helpers.each(this.segments,function(segment){
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
},this);
return segmentsArray;
},
addData : function(segment, atIndex, silent){
var index = atIndex !== undefined ? atIndex : this.segments.length;
if ( typeof(segment.color) === "undefined" ) {
segment.color = Chart.defaults.global.segmentColorDefault[index % Chart.defaults.global.segmentColorDefault.length];
segment.highlight = Chart.defaults.global.segmentHighlightColorDefaults[index % Chart.defaults.global.segmentHighlightColorDefaults.length];
}
this.segments.splice(index, 0, new this.SegmentArc({
value : segment.value,
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
fillColor : segment.color,
highlightColor : segment.highlight || segment.color,
showStroke : this.options.segmentShowStroke,
strokeWidth : this.options.segmentStrokeWidth,
strokeColor : this.options.segmentStrokeColor,
startAngle : Math.PI * 1.5,
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
label : segment.label
}));
if (!silent){
this.reflow();
this.update();
}
},
calculateCircumference : function(value) {
if ( this.total > 0 ) {
return (Math.PI*2)*(value / this.total);
} else {
return 0;
}
},
calculateTotal : function(data){
this.total = 0;
helpers.each(data,function(segment){
this.total += Math.abs(segment.value);
},this);
},
update : function(){
this.calculateTotal(this.segments);
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor']);
});
helpers.each(this.segments,function(segment){
segment.save();
});
this.render();
},
removeData: function(atIndex){
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
this.segments.splice(indexToDelete, 1);
this.reflow();
this.update();
},
reflow : function(){
helpers.extend(this.SegmentArc.prototype,{
x : this.chart.width/2,
y : this.chart.height/2
});
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
helpers.each(this.segments, function(segment){
segment.update({
outerRadius : this.outerRadius,
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
});
}, this);
},
draw : function(easeDecimal){
var animDecimal = (easeDecimal) ? easeDecimal : 1;
this.clear();
helpers.each(this.segments,function(segment,index){
segment.transition({
circumference : this.calculateCircumference(segment.value),
outerRadius : this.outerRadius,
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
},animDecimal);
segment.endAngle = segment.startAngle + segment.circumference;
segment.draw();
if (index === 0){
segment.startAngle = Math.PI * 1.5;
}
//Check to see if it's the last segment, if not get the next and update the start angle
if (index < this.segments.length-1){
this.segments[index+1].startAngle = segment.endAngle;
}
},this);
}
});
Chart.types.Doughnut.extend({
name : "Pie",
defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
});
}).call(this);
+383
Ver Arquivo
@@ -0,0 +1,383 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - Whether the line is curved between points
bezierCurve : true,
//Number - Tension of the bezier curve between points
bezierCurveTension : 0.4,
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 4,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span class=\"<%=name.toLowerCase()%>-legend-icon\" style=\"background-color:<%=datasets[i].strokeColor%>\"></span><span class=\"<%=name.toLowerCase()%>-legend-text\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>",
//Boolean - Whether to horizontally center the label and point dot inside the grid
offsetGridLines : false
};
Chart.Type.extend({
name: "Line",
defaults : defaultConfig,
initialize: function(data){
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.PointClass = Chart.Point.extend({
offsetGridLines : this.options.offsetGridLines,
strokeWidth : this.options.pointDotStrokeWidth,
radius : this.options.pointDotRadius,
display: this.options.pointDot,
hitDetectionRadius : this.options.pointHitDetectionRadius,
ctx : this.chart.ctx,
inRange : function(mouseX){
return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
}
});
this.datasets = [];
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
this.eachPoints(function(point){
point.restore(['fillColor', 'strokeColor']);
});
helpers.each(activePoints, function(activePoint){
activePoint.fillColor = activePoint.highlightFill;
activePoint.strokeColor = activePoint.highlightStroke;
});
this.showTooltip(activePoints);
});
}
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset){
var datasetObject = {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
points : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
datasetObject.points.push(new this.PointClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
}));
},this);
this.buildScale(data.labels);
this.eachPoints(function(point, index){
helpers.extend(point, {
x: this.scale.calculateX(index),
y: this.scale.endPoint
});
point.save();
}, this);
},this);
this.render();
},
update : function(){
this.scale.update();
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor', 'strokeColor']);
});
this.eachPoints(function(point){
point.save();
});
this.render();
},
eachPoints : function(callback){
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,callback,this);
},this);
},
getPointsAtEvent : function(e){
var pointsArray = [],
eventPosition = helpers.getRelativePosition(e);
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,function(point){
if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);
});
},this);
return pointsArray;
},
buildScale : function(labels){
var self = this;
var dataTotal = function(){
var values = [];
self.eachPoints(function(point){
values.push(point.value);
});
return values;
};
var scaleOptions = {
templateString : this.options.scaleLabel,
height : this.chart.height,
width : this.chart.width,
ctx : this.chart.ctx,
textColor : this.options.scaleFontColor,
offsetGridLines : this.options.offsetGridLines,
fontSize : this.options.scaleFontSize,
fontStyle : this.options.scaleFontStyle,
fontFamily : this.options.scaleFontFamily,
valuesCount : labels.length,
beginAtZero : this.options.scaleBeginAtZero,
integersOnly : this.options.scaleIntegersOnly,
calculateYRange : function(currentHeight){
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly
);
helpers.extend(this, updatedRanges);
},
xLabels : labels,
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth : this.options.scaleLineWidth,
lineColor : this.options.scaleLineColor,
showHorizontalLines : this.options.scaleShowHorizontalLines,
showVerticalLines : this.options.scaleShowVerticalLines,
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
showLabels : this.options.scaleShowLabels,
display : this.options.showScale
};
if (this.options.scaleOverride){
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new Chart.Scale(scaleOptions);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
helpers.each(valuesArray,function(value,datasetIndex){
//Add a new point for each piece of data, passing any required data to draw.
this.datasets[datasetIndex].points.push(new this.PointClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: this.scale.calculateX(this.scale.valuesCount+1),
y: this.scale.endPoint,
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
fillColor : this.datasets[datasetIndex].pointColor
}));
},this);
this.scale.addXLabel(label);
//Then re-render the chart.
this.update();
},
removeData : function(){
this.scale.removeXLabel();
//Then re-render the chart.
helpers.each(this.datasets,function(dataset){
dataset.points.shift();
},this);
this.update();
},
reflow : function(){
var newScaleProps = helpers.extend({
height : this.chart.height,
width : this.chart.width
});
this.scale.update(newScaleProps);
},
draw : function(ease){
var easingDecimal = ease || 1;
this.clear();
var ctx = this.chart.ctx;
// Some helper methods for getting the next/prev points
var hasValue = function(item){
return item.value !== null;
},
nextPoint = function(point, collection, index){
return helpers.findNextWhere(collection, hasValue, index) || point;
},
previousPoint = function(point, collection, index){
return helpers.findPreviousWhere(collection, hasValue, index) || point;
};
if (!this.scale) return;
this.scale.draw(easingDecimal);
helpers.each(this.datasets,function(dataset){
var pointsWithValues = helpers.where(dataset.points, hasValue);
//Transition each point first so that the line and point drawing isn't out of sync
//We can use this extra loop to calculate the control points of this dataset also in this loop
helpers.each(dataset.points, function(point, index){
if (point.hasValue()){
point.transition({
y : this.scale.calculateY(point.value),
x : this.scale.calculateX(index)
}, easingDecimal);
}
},this);
// Control points need to be calculated in a separate loop, because we need to know the current x/y of the point
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
if (this.options.bezierCurve){
helpers.each(pointsWithValues, function(point, index){
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
point.controlPoints = helpers.splineCurve(
previousPoint(point, pointsWithValues, index),
point,
nextPoint(point, pointsWithValues, index),
tension
);
// Prevent the bezier going outside of the bounds of the graph
// Cap puter bezier handles to the upper/lower scale bounds
if (point.controlPoints.outer.y > this.scale.endPoint){
point.controlPoints.outer.y = this.scale.endPoint;
}
else if (point.controlPoints.outer.y < this.scale.startPoint){
point.controlPoints.outer.y = this.scale.startPoint;
}
// Cap inner bezier handles to the upper/lower scale bounds
if (point.controlPoints.inner.y > this.scale.endPoint){
point.controlPoints.inner.y = this.scale.endPoint;
}
else if (point.controlPoints.inner.y < this.scale.startPoint){
point.controlPoints.inner.y = this.scale.startPoint;
}
},this);
}
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
helpers.each(pointsWithValues, function(point, index){
if (index === 0){
ctx.moveTo(point.x, point.y);
}
else{
if(this.options.bezierCurve){
var previous = previousPoint(point, pointsWithValues, index);
ctx.bezierCurveTo(
previous.controlPoints.outer.x,
previous.controlPoints.outer.y,
point.controlPoints.inner.x,
point.controlPoints.inner.y,
point.x,
point.y
);
}
else{
ctx.lineTo(point.x,point.y);
}
}
}, this);
if (this.options.datasetStroke) {
ctx.stroke();
}
if (this.options.datasetFill && pointsWithValues.length > 0){
//Round off the line by going to the base of the chart, back to the start, then fill.
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
ctx.fillStyle = dataset.fillColor;
ctx.closePath();
ctx.fill();
}
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
helpers.each(pointsWithValues,function(point){
point.draw();
});
},this);
}
});
}).call(this);
+250
Ver Arquivo
@@ -0,0 +1,250 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//Number - The backdrop padding above & below the label in pixels
scaleBackdropPaddingY : 2,
//Number - The backdrop padding to the side of the label in pixels
scaleBackdropPaddingX : 2,
//Boolean - Show line for each value in the scale
scaleShowLine : true,
//Boolean - Stroke a line around each segment in the chart
segmentShowStroke : true,
//String - The colour of the stroke on each segment.
segmentStrokeColor : "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth : 2,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect.
animationEasing : "easeOutBounce",
//Boolean - Whether to animate the rotation of the chart
animateRotate : true,
//Boolean - Whether to animate scaling the chart from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span class=\"<%=name.toLowerCase()%>-legend-icon\" style=\"background-color:<%=segments[i].fillColor%>\"></span><span class=\"<%=name.toLowerCase()%>-legend-text\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
};
Chart.Type.extend({
//Passing in a name registers this chart in the Chart namespace
name: "PolarArea",
//Providing a defaults will also register the defaults in the chart namespace
defaults : defaultConfig,
//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.segments = [];
//Declare segment class as a chart instance specific class, so it can share props for this instance
this.SegmentArc = Chart.Arc.extend({
showStroke : this.options.segmentShowStroke,
strokeWidth : this.options.segmentStrokeWidth,
strokeColor : this.options.segmentStrokeColor,
ctx : this.chart.ctx,
innerRadius : 0,
x : this.chart.width/2,
y : this.chart.height/2
});
this.scale = new Chart.RadialScale({
display: this.options.showScale,
fontStyle: this.options.scaleFontStyle,
fontSize: this.options.scaleFontSize,
fontFamily: this.options.scaleFontFamily,
fontColor: this.options.scaleFontColor,
showLabels: this.options.scaleShowLabels,
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
backdropColor: this.options.scaleBackdropColor,
backdropPaddingY : this.options.scaleBackdropPaddingY,
backdropPaddingX: this.options.scaleBackdropPaddingX,
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
lineColor: this.options.scaleLineColor,
lineArc: true,
width: this.chart.width,
height: this.chart.height,
xCenter: this.chart.width/2,
yCenter: this.chart.height/2,
ctx : this.chart.ctx,
templateString: this.options.scaleLabel,
valuesCount: data.length
});
this.updateScaleRange(data);
this.scale.update();
helpers.each(data,function(segment,index){
this.addData(segment,index,true);
},this);
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
helpers.each(this.segments,function(segment){
segment.restore(["fillColor"]);
});
helpers.each(activeSegments,function(activeSegment){
activeSegment.fillColor = activeSegment.highlightColor;
});
this.showTooltip(activeSegments);
});
}
this.render();
},
getSegmentsAtEvent : function(e){
var segmentsArray = [];
var location = helpers.getRelativePosition(e);
helpers.each(this.segments,function(segment){
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
},this);
return segmentsArray;
},
addData : function(segment, atIndex, silent){
var index = atIndex || this.segments.length;
this.segments.splice(index, 0, new this.SegmentArc({
fillColor: segment.color,
highlightColor: segment.highlight || segment.color,
label: segment.label,
value: segment.value,
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
startAngle: Math.PI * 1.5
}));
if (!silent){
this.reflow();
this.update();
}
},
removeData: function(atIndex){
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
this.segments.splice(indexToDelete, 1);
this.reflow();
this.update();
},
calculateTotal: function(data){
this.total = 0;
helpers.each(data,function(segment){
this.total += segment.value;
},this);
this.scale.valuesCount = this.segments.length;
},
updateScaleRange: function(datapoints){
var valuesArray = [];
helpers.each(datapoints,function(segment){
valuesArray.push(segment.value);
});
var scaleSizes = (this.options.scaleOverride) ?
{
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
} :
helpers.calculateScaleRange(
valuesArray,
helpers.min([this.chart.width, this.chart.height])/2,
this.options.scaleFontSize,
this.options.scaleBeginAtZero,
this.options.scaleIntegersOnly
);
helpers.extend(
this.scale,
scaleSizes,
{
size: helpers.min([this.chart.width, this.chart.height]),
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
}
);
},
update : function(){
this.calculateTotal(this.segments);
helpers.each(this.segments,function(segment){
segment.save();
});
this.reflow();
this.render();
},
reflow : function(){
helpers.extend(this.SegmentArc.prototype,{
x : this.chart.width/2,
y : this.chart.height/2
});
this.updateScaleRange(this.segments);
this.scale.update();
helpers.extend(this.scale,{
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
});
helpers.each(this.segments, function(segment){
segment.update({
outerRadius : this.scale.calculateCenterOffset(segment.value)
});
}, this);
},
draw : function(ease){
var easingDecimal = ease || 1;
//Clear & draw the canvas
this.clear();
helpers.each(this.segments,function(segment, index){
segment.transition({
circumference : this.scale.getCircumference(),
outerRadius : this.scale.calculateCenterOffset(segment.value)
},easingDecimal);
segment.endAngle = segment.startAngle + segment.circumference;
// If we've removed the first segment we need to set the first one to
// start at the top.
if (index === 0){
segment.startAngle = Math.PI * 1.5;
}
//Check to see if it's the last segment, if not get the next and update the start angle
if (index < this.segments.length - 1){
this.segments[index+1].startAngle = segment.endAngle;
}
segment.draw();
}, this);
this.scale.draw();
}
});
}).call(this);
+350
Ver Arquivo
@@ -0,0 +1,350 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.Type.extend({
name: "Radar",
defaults:{
//Boolean - Whether to show lines for each scale point
scaleShowLine : true,
//Boolean - Whether we show the angle lines out of the radar
angleShowLineOut : true,
//Boolean - Whether to show labels on the scale
scaleShowLabels : false,
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//String - Colour of the angle line
angleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the angle line
angleLineWidth : 1,
//Number - Interval at which to draw angle lines ("every Nth point")
angleLineInterval: 1,
//String - Point label font declaration
pointLabelFontFamily : "'Arial'",
//String - Point label font weight
pointLabelFontStyle : "normal",
//Number - Point label font size in pixels
pointLabelFontSize : 10,
//String - Point label font colour
pointLabelFontColor : "#666",
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 3,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span class=\"<%=name.toLowerCase()%>-legend-icon\" style=\"background-color:<%=datasets[i].strokeColor%>\"></span><span class=\"<%=name.toLowerCase()%>-legend-text\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%></span></li><%}%></ul>"
},
initialize: function(data){
this.PointClass = Chart.Point.extend({
strokeWidth : this.options.pointDotStrokeWidth,
radius : this.options.pointDotRadius,
display: this.options.pointDot,
hitDetectionRadius : this.options.pointHitDetectionRadius,
ctx : this.chart.ctx
});
this.datasets = [];
this.buildScale(data);
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
this.eachPoints(function(point){
point.restore(['fillColor', 'strokeColor']);
});
helpers.each(activePointsCollection, function(activePoint){
activePoint.fillColor = activePoint.highlightFill;
activePoint.strokeColor = activePoint.highlightStroke;
});
this.showTooltip(activePointsCollection);
});
}
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset){
var datasetObject = {
label: dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
points : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
var pointPosition;
if (!this.scale.animation){
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
}
datasetObject.points.push(new this.PointClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
}));
},this);
},this);
this.render();
},
eachPoints : function(callback){
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,callback,this);
},this);
},
getPointsAtEvent : function(evt){
var mousePosition = helpers.getRelativePosition(evt),
fromCenter = helpers.getAngleFromPoint({
x: this.scale.xCenter,
y: this.scale.yCenter
}, mousePosition);
var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
activePointsCollection = [];
// If we're at the top, make the pointIndex 0 to get the first of the array.
if (pointIndex >= this.scale.valuesCount || pointIndex < 0){
pointIndex = 0;
}
if (fromCenter.distance <= this.scale.drawingArea){
helpers.each(this.datasets, function(dataset){
activePointsCollection.push(dataset.points[pointIndex]);
});
}
return activePointsCollection;
},
buildScale : function(data){
this.scale = new Chart.RadialScale({
display: this.options.showScale,
fontStyle: this.options.scaleFontStyle,
fontSize: this.options.scaleFontSize,
fontFamily: this.options.scaleFontFamily,
fontColor: this.options.scaleFontColor,
showLabels: this.options.scaleShowLabels,
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
backdropColor: this.options.scaleBackdropColor,
backgroundColors: this.options.scaleBackgroundColors,
backdropPaddingY : this.options.scaleBackdropPaddingY,
backdropPaddingX: this.options.scaleBackdropPaddingX,
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
lineColor: this.options.scaleLineColor,
angleLineColor : this.options.angleLineColor,
angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
angleLineInterval: (this.options.angleLineInterval) ? this.options.angleLineInterval : 1,
// Point labels at the edge of each line
pointLabelFontColor : this.options.pointLabelFontColor,
pointLabelFontSize : this.options.pointLabelFontSize,
pointLabelFontFamily : this.options.pointLabelFontFamily,
pointLabelFontStyle : this.options.pointLabelFontStyle,
height : this.chart.height,
width: this.chart.width,
xCenter: this.chart.width/2,
yCenter: this.chart.height/2,
ctx : this.chart.ctx,
templateString: this.options.scaleLabel,
labels: data.labels,
valuesCount: data.datasets[0].data.length
});
this.scale.setScaleSize();
this.updateScaleRange(data.datasets);
this.scale.buildYLabels();
},
updateScaleRange: function(datasets){
var valuesArray = (function(){
var totalDataArray = [];
helpers.each(datasets,function(dataset){
if (dataset.data){
totalDataArray = totalDataArray.concat(dataset.data);
}
else {
helpers.each(dataset.points, function(point){
totalDataArray.push(point.value);
});
}
});
return totalDataArray;
})();
var scaleSizes = (this.options.scaleOverride) ?
{
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
} :
helpers.calculateScaleRange(
valuesArray,
helpers.min([this.chart.width, this.chart.height])/2,
this.options.scaleFontSize,
this.options.scaleBeginAtZero,
this.options.scaleIntegersOnly
);
helpers.extend(
this.scale,
scaleSizes
);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
this.scale.valuesCount++;
helpers.each(valuesArray,function(value,datasetIndex){
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
this.datasets[datasetIndex].points.push(new this.PointClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: pointPosition.x,
y: pointPosition.y,
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
fillColor : this.datasets[datasetIndex].pointColor
}));
},this);
this.scale.labels.push(label);
this.reflow();
this.update();
},
removeData : function(){
this.scale.valuesCount--;
this.scale.labels.shift();
helpers.each(this.datasets,function(dataset){
dataset.points.shift();
},this);
this.reflow();
this.update();
},
update : function(){
this.eachPoints(function(point){
point.save();
});
this.reflow();
this.render();
},
reflow: function(){
helpers.extend(this.scale, {
width : this.chart.width,
height: this.chart.height,
size : helpers.min([this.chart.width, this.chart.height]),
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
});
this.updateScaleRange(this.datasets);
this.scale.setScaleSize();
this.scale.buildYLabels();
},
draw : function(ease){
var easeDecimal = ease || 1,
ctx = this.chart.ctx;
this.clear();
this.scale.draw();
helpers.each(this.datasets,function(dataset){
//Transition each point first so that the line and point drawing isn't out of sync
helpers.each(dataset.points,function(point,index){
if (point.hasValue()){
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
}
},this);
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
helpers.each(dataset.points,function(point,index){
if (index === 0){
ctx.moveTo(point.x,point.y);
}
else{
ctx.lineTo(point.x,point.y);
}
},this);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = dataset.fillColor;
if(this.options.datasetFill){
ctx.fill();
}
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
helpers.each(dataset.points,function(point){
if (point.hasValue()){
point.draw();
}
});
},this);
}
});
}).call(this);
-14
Ver Arquivo
@@ -1,14 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
Chart.Bar = function(context, config) {
config.type = 'bar';
return new Chart(context, config);
};
}).call(this);
-48
Ver Arquivo
@@ -1,48 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
var defaultConfig = {
hover: {
mode: 'single',
},
scales: {
xAxes: [{
type: "linear", // bubble should probably use a linear scale by default
position: "bottom",
id: "x-axis-0", // need an ID so datasets can reference the scale
}],
yAxes: [{
type: "linear",
position: "left",
id: "y-axis-0",
}],
},
tooltips: {
callbacks: {
title: function(tooltipItems, data) {
// Title doesn't make sense for scatter since we format the data as a point
return '';
},
label: function(tooltipItem, data) {
return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
}
}
},
};
// Register the default config for this type
Chart.defaults.bubble = defaultConfig;
Chart.Bubble = function(context, config) {
config.type = 'bubble';
return new Chart(context, config);
};
}).call(this);
-14
Ver Arquivo
@@ -1,14 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
Chart.Doughnut = function(context, config) {
config.type = 'doughnut';
return new Chart(context, config);
};
}).call(this);
-14
Ver Arquivo
@@ -1,14 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
Chart.Line = function(context, config) {
config.type = 'line';
return new Chart(context, config);
};
}).call(this);
-14
Ver Arquivo
@@ -1,14 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
Chart.PolarArea = function(context, config) {
config.type = 'polarArea';
return new Chart(context, config);
};
}).call(this);
-19
Ver Arquivo
@@ -1,19 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
var defaultConfig = {
aspectRatio: 1,
};
Chart.Radar = function(context, config) {
config.options = helpers.configMerge(defaultConfig, config.options);
config.type = 'radar';
return new Chart(context, config);
};
}).call(this);
-50
Ver Arquivo
@@ -1,50 +0,0 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
var defaultConfig = {
hover: {
mode: 'single',
},
scales: {
xAxes: [{
type: "linear", // scatter should not use a category axis
position: "bottom",
id: "x-axis-1", // need an ID so datasets can reference the scale
}],
yAxes: [{
type: "linear",
position: "left",
id: "y-axis-1",
}],
},
tooltips: {
callbacks: {
title: function(tooltipItems, data) {
// Title doesn't make sense for scatter since we format the data as a point
return '';
},
label: function(tooltipItem, data) {
return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
}
}
},
};
// Register the default config for this type
Chart.defaults.scatter = defaultConfig;
// Scatter charts use line controllers
Chart.controllers.scatter = Chart.controllers.line;
Chart.Scatter = function(context, config) {
config.type = 'scatter';
return new Chart(context, config);
};
}).call(this);
-314
Ver Arquivo
@@ -1,314 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.bar = {
hover: {
mode: "label"
},
scales: {
xAxes: [{
type: "category",
// Specific to Bar Controller
categoryPercentage: 0.8,
barPercentage: 0.9,
// grid line settings
gridLines: {
offsetGridLines: true,
},
}],
yAxes: [{
type: "linear",
}],
},
};
Chart.controllers.bar = Chart.DatasetController.extend({
initialize: function(chart, datasetIndex) {
Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
// Use this to indicate that this is a bar dataset.
this.getDataset().bar = true;
},
// Get the number of datasets that display bars. We use this to correctly calculate the bar width
getBarCount: function getBarCount() {
var barCount = 0;
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && dataset.bar) {
++barCount;
}
}, this);
return barCount;
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var rectangle = new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
var numBars = this.getBarCount();
this.updateElement(rectangle, index, true, numBars);
this.getDataset().metaData.splice(index, 0, rectangle);
},
update: function update(reset) {
var numBars = this.getBarCount();
helpers.each(this.getDataset().metaData, function(rectangle, index) {
this.updateElement(rectangle, index, reset, numBars);
}, this);
},
updateElement: function updateElement(rectangle, index, reset, numBars) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var yScalePoint;
if (yScale.min < 0 && yScale.max < 0) {
// all less than 0. use the top
yScalePoint = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
yScalePoint = yScale.getPixelForValue(yScale.min);
} else {
yScalePoint = yScale.getPixelForValue(0);
}
helpers.extend(rectangle, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: this.calculateBarX(index, this.index),
y: reset ? yScalePoint : this.calculateBarY(index, this.index),
// Tooltip
label: this.chart.data.labels[index],
datasetLabel: this.getDataset().label,
// Appearance
base: this.calculateBarBase(this.index, index),
width: this.calculateBarWidth(numBars),
backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor),
borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor),
borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth),
},
});
rectangle.pivot();
},
calculateBarBase: function(datasetIndex, index) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var base = 0;
if (yScale.options.stacked) {
var value = this.chart.data.datasets[datasetIndex].data[index];
if (value < 0) {
for (var i = 0; i < datasetIndex; i++) {
var negDS = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(negDS) && negDS.yAxisID === yScale.id) {
base += negDS.data[index] < 0 ? negDS.data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
var posDS = this.chart.data.datasets[j];
if (helpers.isDatasetVisible(posDS) && posDS.yAxisID === yScale.id) {
base += posDS.data[index] > 0 ? posDS.data[index] : 0;
}
}
}
return yScale.getPixelForValue(base);
}
base = yScale.getPixelForValue(yScale.min);
if (yScale.beginAtZero || ((yScale.min <= 0 && yScale.max >= 0) || (yScale.min >= 0 && yScale.max <= 0))) {
base = yScale.getPixelForValue(0, 0);
//base += yScale.options.gridLines.lineWidth;
} else if (yScale.min < 0 && yScale.max < 0) {
// All values are negative. Use the top as the base
base = yScale.getPixelForValue(yScale.max);
}
return base;
},
getRuler: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var datasetCount = this.getBarCount();
var tickWidth = (function() {
var min = xScale.getPixelForTick(1) - xScale.getPixelForTick(0);
for (var i = 2; i < this.getDataset().data.length; i++) {
min = Math.min(xScale.getPixelForTick(i) - xScale.getPixelForTick(i - 1), min);
}
return min;
}).call(this);
var categoryWidth = tickWidth * xScale.options.categoryPercentage;
var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
var fullBarWidth = categoryWidth / datasetCount;
var barWidth = fullBarWidth * xScale.options.barPercentage;
var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
return {
datasetCount: datasetCount,
tickWidth: tickWidth,
categoryWidth: categoryWidth,
categorySpacing: categorySpacing,
fullBarWidth: fullBarWidth,
barWidth: barWidth,
barSpacing: barSpacing,
};
},
calculateBarWidth: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var ruler = this.getRuler();
if (xScale.options.stacked) {
return ruler.categoryWidth;
}
return ruler.barWidth;
},
// Get bar index from the given dataset index accounting for the fact that not all bars are visible
getBarIndex: function(datasetIndex) {
var barIndex = 0;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j]) && this.chart.data.datasets[j].bar) {
++barIndex;
}
}
return barIndex;
},
calculateBarX: function(index, datasetIndex) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var barIndex = this.getBarIndex(datasetIndex);
var ruler = this.getRuler();
var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo);
leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0;
if (xScale.options.stacked) {
return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
}
return leftTick +
(ruler.barWidth / 2) +
ruler.categorySpacing +
(ruler.barWidth * barIndex) +
(ruler.barSpacing / 2) +
(ruler.barSpacing * barIndex);
},
calculateBarY: function(index, datasetIndex) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var value = this.getDataset().data[index];
if (yScale.options.stacked) {
var sumPos = 0,
sumNeg = 0;
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(ds)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
sumPos += ds.data[index] || 0;
}
}
}
if (value < 0) {
return yScale.getPixelForValue(sumNeg + value);
} else {
return yScale.getPixelForValue(sumPos + value);
}
return yScale.getPixelForValue(value);
}
return yScale.getPixelForValue(value);
},
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(rectangle, index) {
rectangle.transition(easingDecimal).draw();
}, this);
},
setHoverStyle: function(rectangle) {
var dataset = this.chart.data.datasets[rectangle._datasetIndex];
var index = rectangle._index;
rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.hoverBackgroundColor ? rectangle.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(rectangle._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
rectangle._model.borderColor = rectangle.custom && rectangle.custom.hoverBorderColor ? rectangle.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(rectangle._model.borderColor).saturate(0.5).darken(0.1).rgbString());
rectangle._model.borderWidth = rectangle.custom && rectangle.custom.hoverBorderWidth ? rectangle.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth);
},
removeHoverStyle: function(rectangle) {
var dataset = this.chart.data.datasets[rectangle._datasetIndex];
var index = rectangle._index;
rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor);
rectangle._model.borderColor = rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor);
rectangle._model.borderWidth = rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth);
}
});
}).call(this);
-161
Ver Arquivo
@@ -1,161 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.bubble = {
hover: {
mode: "single"
},
scales: {
xAxes: [{
type: "linear", // bubble should probably use a linear scale by default
position: "bottom",
id: "x-axis-0", // need an ID so datasets can reference the scale
}],
yAxes: [{
type: "linear",
position: "left",
id: "y-axis-0",
}],
},
tooltips: {
template: "(<%= value.x %>, <%= value.y %>, <%= value.r %>)",
multiTemplate: "<%if (datasetLabel){%><%=datasetLabel%>: <%}%>(<%= value.x %>, <%= value.y %>, <%= value.r %>)",
},
};
Chart.controllers.bubble = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
},
update: function update(reset) {
var points = this.getDataset().metaData;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
helpers.extend(point, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index),
// Appearance
radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]),
backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor),
borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor),
borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
},
});
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
point.pivot();
},
getRadius: function(value) {
return value.r || this.chart.options.elements.point.radius;
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition and Draw the Points
helpers.each(this.getDataset().metaData, function(point, index) {
point.transition(easingDecimal);
point.draw();
}, this);
},
setHoverStyle: function(point) {
// Point
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]);
point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth);
},
removeHoverStyle: function(point) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]);
point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor);
point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor);
point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth);
}
});
}).call(this);
-254
Ver Arquivo
@@ -1,254 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
Chart.defaults.doughnut = {
animation: {
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false,
},
aspectRatio: 1,
hover: {
mode: 'single'
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
if (chart.data.datasets.length) {
for (var i = 0; i < chart.data.datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</span></li>');
}
}
text.push('</ul>');
return text.join("");
},
legend: {
labels: {
generateLabels: function(data) {
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
// Extra data used for toggling the correct item
index: i
};
});
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
this.chart.update();
}
},
//The percentage of the chart that we cut out of the middle.
cutoutPercentage: 50,
// Need to override these to give a nice default
tooltips: {
callbacks: {
title: function() { return '';},
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
}
}
}
};
Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut);
helpers.extend(Chart.defaults.pie, {
cutoutPercentage: 0
});
Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
linkScales: function() {
// no scales for doughnut
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
}, this);
},
addElementAndReset: function(index, colorForNewElement) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
if (colorForNewElement && helpers.isArray(this.getDataset().backgroundColor)) {
this.getDataset().backgroundColor.splice(index, 0, colorForNewElement);
}
// Reset the point
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) { return helpers.isDatasetVisible(ds); }).length;
},
// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
getRingIndex: function getRingIndex(datasetIndex) {
var ringIndex = 0;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j])) {
++ringIndex;
}
}
return ringIndex;
},
update: function update(reset) {
var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top);
this.chart.outerRadius = Math.max((minSize / 2) - this.chart.options.elements.arc.borderWidth / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
if (!isNaN(value)) {
this.getDataset().total += Math.abs(value);
}
}, this);
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index));
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
updateElement: function(arc, index, reset) {
var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2;
var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2;
var resetModel = {
x: centerX,
y: centerY,
startAngle: Math.PI * -0.5, // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
endAngle: Math.PI * -0.5,
circumference: (this.chart.options.animation.animateRotate) ? 0 : this.calculateCircumference(this.getDataset().data[index]),
outerRadius: (this.chart.options.animation.animateScale) ? 0 : this.outerRadius,
innerRadius: (this.chart.options.animation.animateScale) ? 0 : this.innerRadius
};
helpers.extend(arc, {
// Utility
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: reset ? resetModel : {
x: centerX,
y: centerY,
circumference: this.calculateCircumference(this.getDataset().data[index]),
outerRadius: this.outerRadius,
innerRadius: this.innerRadius,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor),
borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth),
borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor),
label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index])
},
});
if (!reset) {
if (index === 0) {
arc._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function
} else {
arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle;
}
arc._model.endAngle = arc._model.startAngle + arc._model.circumference;
//Check to see if it's the last arc, if not get the next and update its start angle
if (index < this.getDataset().data.length - 1) {
this.getDataset().metaData[index + 1]._model.startAngle = arc._model.endAngle;
}
}
arc.pivot();
},
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(arc, index) {
arc.transition(easingDecimal).draw();
}, this);
},
setHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth);
},
removeHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor);
arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor);
arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth);
},
calculateCircumference: function(value) {
if (this.getDataset().total > 0 && !isNaN(value)) {
return (Math.PI * 1.999999) * (value / this.getDataset().total);
} else {
return 0;
}
},
});
}).call(this);
-290
Ver Arquivo
@@ -1,290 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.line = {
hover: {
mode: "label"
},
scales: {
xAxes: [{
type: "category",
id: 'x-axis-0'
}],
yAxes: [{
type: "linear",
id: 'y-axis-0'
}],
},
};
Chart.controllers.line = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData,
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
// Update Line
helpers.extend(line, {
// Utility
_scale: yScale,
_datasetIndex: this.index,
// Data
_children: points,
// Model
_model: {
// Appearance
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle),
borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash),
borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset),
borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle),
fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill),
// Scale
scaleTop: yScale.top,
scaleBottom: yScale.bottom,
scaleZero: scaleBase,
},
});
line.pivot();
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
this.updateBezierControlPoints();
},
getPointBackgroundColor: function(point, index) {
var backgroundColor = this.chart.options.elements.point.backgroundColor;
var dataset = this.getDataset();
if (point.custom && point.custom.backgroundColor) {
backgroundColor = point.custom.backgroundColor;
} else if (dataset.pointBackgroundColor) {
backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
} else if (dataset.backgroundColor) {
backgroundColor = dataset.backgroundColor;
}
return backgroundColor;
},
getPointBorderColor: function(point, index) {
var borderColor = this.chart.options.elements.point.borderColor;
var dataset = this.getDataset();
if (point.custom && point.custom.borderColor) {
borderColor = point.custom.borderColor;
} else if (dataset.pointBorderColor) {
borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor);
} else if (dataset.borderColor) {
borderColor = dataset.borderColor;
}
return borderColor;
},
getPointBorderWidth: function(point, index) {
var borderWidth = this.chart.options.elements.point.borderWidth;
var dataset = this.getDataset();
if (point.custom && point.custom.borderWidth !== undefined) {
borderWidth = point.custom.borderWidth;
} else if (dataset.pointBorderWidth !== undefined) {
borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
} else if (dataset.borderWidth !== undefined) {
borderWidth = dataset.borderWidth;
}
return borderWidth;
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
helpers.extend(point, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo),
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius),
backgroundColor: this.getPointBackgroundColor(point, index),
borderColor: this.getPointBorderColor(point, index),
borderWidth: this.getPointBorderWidth(point, index),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
},
});
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
calculatePointY: function(value, index, datasetIndex, isCombo) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
if (yScale.options.stacked) {
var sumPos = 0,
sumNeg = 0;
for (var i = this.chart.data.datasets.length - 1; i > datasetIndex; i--) {
var ds = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(ds)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
sumPos += ds.data[index] || 0;
}
}
}
if (value < 0) {
return yScale.getPixelForValue(sumNeg + value);
} else {
return yScale.getPixelForValue(sumPos + value);
}
return yScale.getPixelForValue(value);
}
return yScale.getPixelForValue(value);
},
updateBezierControlPoints: function() {
// Update bezier control points
helpers.each(this.getDataset().metaData, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index)._model,
point._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
// Now pivot the point for animation
point.pivot();
}, this);
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point, index) {
point.transition(easingDecimal);
}, this);
// Transition and Draw the line
this.getDataset().metaDataset.transition(easingDecimal).draw();
// Draw the points
helpers.each(this.getDataset().metaData, function(point) {
point.draw();
});
},
setHoverStyle: function(point) {
// Point
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth);
},
removeHoverStyle: function(point) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius);
point._model.backgroundColor = this.getPointBackgroundColor(point, index);
point._model.borderColor = this.getPointBorderColor(point, index);
point._model.borderWidth = this.getPointBorderWidth(point, index);
}
});
}).call(this);
-232
Ver Arquivo
@@ -1,232 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
Chart.defaults.polarArea = {
scale: {
type: "radialLinear",
lineArc: true, // so that lines are circular
},
//Boolean - Whether to animate the rotation of the chart
animateRotate: true,
animateScale: true,
aspectRatio: 1,
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
if (chart.data.datasets.length) {
for (var i = 0; i < chart.data.datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</span></li>');
}
}
text.push('</ul>');
return text.join("");
},
legend: {
labels: {
generateLabels: function(data) {
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
// Extra data used for toggling the correct item
index: i
};
});
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
this.chart.update();
}
},
// Need to override these to give a nice default
tooltips: {
callbacks: {
title: function() { return ''; },
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;
}
}
}
};
Chart.controllers.polarArea = Chart.DatasetController.extend({
linkScales: function() {
// no scales for doughnut
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
// Reset the point
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) { return helpers.isDatasetVisible(ds); }).length;
},
update: function update(reset) {
var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top);
this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
this.getDataset().total += Math.abs(value);
}, this);
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index);
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
updateElement: function(arc, index, reset) {
var circumference = this.calculateCircumference(this.getDataset().data[index]);
var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2;
var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2;
// If there is NaN data before us, we need to calculate the starting angle correctly.
// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
var notNullIndex = 0;
for (var i = 0; i < index; ++i) {
if (!isNaN(this.getDataset().data[i])) {
++notNullIndex;
}
}
var startAngle = (-0.5 * Math.PI) + (circumference * notNullIndex);
var endAngle = startAngle + circumference;
var resetModel = {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.options.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : startAngle,
endAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : endAngle,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor),
borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth),
borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor),
label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index])
};
helpers.extend(arc, {
// Utility
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
_scale: this.chart.scale,
// Desired view properties
_model: reset ? resetModel : {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: startAngle,
endAngle: endAngle,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor),
borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth),
borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor),
label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index])
},
});
arc.pivot();
},
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(arc, index) {
arc.transition(easingDecimal).draw();
}, this);
},
setHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, arc._model.borderWidth);
},
removeHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor);
arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor);
arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth);
},
calculateCircumference: function(value) {
if (isNaN(value)) {
return 0;
} else {
// Count the number of NaN values
var numNaN = helpers.where(this.getDataset().data, function(data) {
return isNaN(data);
}).length;
return (2 * Math.PI) / (this.getDataset().data.length - numNaN);
}
}
});
}).call(this);
-202
Ver Arquivo
@@ -1,202 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.radar = {
scale: {
type: "radialLinear",
},
elements: {
line: {
tension: 0, // no bezier in radar
}
},
};
Chart.controllers.radar = Chart.DatasetController.extend({
linkScales: function() {
// No need. Single scale only
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData,
_loop: true
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
_model: {
x: 0, //xScale.getPixelForValue(null, index, true),
y: 0, //this.chartArea.bottom,
},
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var scale = this.chart.scale;
var scaleBase;
if (scale.min < 0 && scale.max < 0) {
scaleBase = scale.getPointPositionForValue(0, scale.max);
} else if (scale.min > 0 && scale.max > 0) {
scaleBase = scale.getPointPositionForValue(0, scale.min);
} else {
scaleBase = scale.getPointPositionForValue(0, 0);
}
helpers.extend(this.getDataset().metaDataset, {
// Utility
_datasetIndex: this.index,
// Data
_children: this.getDataset().metaData,
// Model
_model: {
// Appearance
tension: helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
backgroundColor: this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor,
borderWidth: this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth,
borderColor: this.getDataset().borderColor || this.chart.options.elements.line.borderColor,
fill: this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill, // use the value from the this.getDataset() if it was provided. else fall back to the default
// Scale
scaleTop: scale.top,
scaleBottom: scale.bottom,
scaleZero: scaleBase,
},
});
this.getDataset().metaDataset.pivot();
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
// Update bezier control points
this.updateBezierControlPoints();
},
updateElement: function(point, index, reset) {
var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]);
helpers.extend(point, {
// Utility
_datasetIndex: this.index,
_index: index,
_scale: this.chart.scale,
// Desired view properties
_model: {
x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
y: reset ? this.chart.scale.yCenter : pointPosition.y,
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
radius: point.custom && point.custom.radius ? point.custom.pointRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius),
backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor),
borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor),
borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
},
});
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
updateBezierControlPoints: function() {
helpers.each(this.getDataset().metaData, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index, true)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index, true)._model,
point._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
// Now pivot the point for animation
point.pivot();
}, this);
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point, index) {
point.transition(easingDecimal);
}, this);
// Transition and Draw the line
this.getDataset().metaDataset.transition(easingDecimal).draw();
// Draw the points
helpers.each(this.getDataset().metaData, function(point) {
point.draw();
});
},
setHoverStyle: function(point) {
// Point
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, point._model.borderWidth);
},
removeHoverStyle: function(point) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius);
point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor);
point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor);
point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth);
}
});
}).call(this);
-120
Ver Arquivo
@@ -1,120 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.animation = {
duration: 1000,
easing: "easeOutQuart",
onProgress: helpers.noop,
onComplete: helpers.noop,
};
Chart.Animation = Chart.Element.extend({
currentStep: null, // the current animation step
numSteps: 60, // default number of steps
easing: "", // the easing to use for this animation
render: null, // render function used by the animation service
onAnimationProgress: null, // user specified callback to fire on each step of the animation
onAnimationComplete: null, // user specified callback to fire when the animation finishes
});
Chart.animationService = {
frameDuration: 17,
animations: [],
dropFrames: 0,
addAnimation: function(chartInstance, animationObject, duration, lazy) {
if (!lazy) {
chartInstance.animating = true;
}
for (var index = 0; index < this.animations.length; ++index) {
if (this.animations[index].chartInstance === chartInstance) {
// replacing an in progress animation
this.animations[index].animationObject = animationObject;
return;
}
}
this.animations.push({
chartInstance: chartInstance,
animationObject: animationObject
});
// If there are no animations queued, manually kickstart a digest, for lack of a better word
if (this.animations.length == 1) {
helpers.requestAnimFrame.call(window, this.digestWrapper);
}
},
// Cancel the animation for a given chart instance
cancelAnimation: function(chartInstance) {
var index = helpers.findNextWhere(this.animations, function(animationWrapper) {
return animationWrapper.chartInstance === chartInstance;
});
if (index) {
this.animations.splice(index, 1);
chartInstance.animating = false;
}
},
// calls startDigest with the proper context
digestWrapper: function() {
Chart.animationService.startDigest.call(Chart.animationService);
},
startDigest: function() {
var startTime = Date.now();
var framesToDrop = 0;
if (this.dropFrames > 1) {
framesToDrop = Math.floor(this.dropFrames);
this.dropFrames = this.dropFrames % 1;
}
for (var i = 0; i < this.animations.length; i++) {
if (this.animations[i].animationObject.currentStep === null) {
this.animations[i].animationObject.currentStep = 0;
}
this.animations[i].animationObject.currentStep += 1 + framesToDrop;
if (this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps) {
this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps;
}
this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject);
if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) {
this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]);
}
if (this.animations[i].animationObject.currentStep == this.animations[i].animationObject.numSteps) {
if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) {
this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]);
}
// executed the last frame. Remove the animation.
this.animations[i].chartInstance.animating = false;
this.animations.splice(i, 1);
// Keep the index in place to offset the splice
i--;
}
}
var endTime = Date.now();
var dropFrames = (endTime - startTime) / this.frameDuration;
this.dropFrames += dropFrames;
// Do we have more stuff to animate?
if (this.animations.length > 0) {
helpers.requestAnimFrame.call(window, this.digestWrapper);
}
}
};
}).call(this);
-548
Ver Arquivo
@@ -1,548 +0,0 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
//Create a dictionary of chart types, to allow for extension of existing types
Chart.types = {};
//Store a reference to each instance - allowing us to globally resize chart instances on window resize.
//Destroy method on the chart will remove the instance of the chart from this reference.
Chart.instances = {};
// Controllers available for dataset visualization eg. bar, line, slice, etc.
Chart.controllers = {};
// The main controller of a chart
Chart.Controller = function(instance) {
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();
Object.defineProperty(this, 'data', {
get: function() {
return this.config.data;
},
});
//Add the chart instance to the global namespace
Chart.instances[this.id] = this;
if (this.options.responsive) {
// Silent resize before chart draws
this.resize(true);
}
this.initialize.call(this);
return this;
};
helpers.extend(Chart.Controller.prototype, {
initialize: function initialize() {
// TODO
// If BeforeInit(this) doesn't return false, proceed
this.bindEvents();
// Make sure controllers are built first so that each dataset is bound to an axis before the scales
// are built
this.ensureScalesHaveIDs();
this.buildOrUpdateControllers();
this.buildScales();
this.buildSurroundingItems();
this.updateLayout();
this.resetElements();
this.initToolTip();
this.update();
// TODO
// If AfterInit(this) doesn't return false, proceed
return this;
},
clear: function clear() {
helpers.clear(this.chart);
return this;
},
stop: function stop() {
// Stops any current animation loop occuring
Chart.animationService.cancelAnimation(this);
return this;
},
resize: function resize(silent) {
this.stop();
var canvas = this.chart.canvas;
var newWidth = helpers.getMaximumWidth(this.chart.canvas);
var newHeight = (this.options.maintainAspectRatio && isNaN(this.chart.aspectRatio) === false && isFinite(this.chart.aspectRatio) && this.chart.aspectRatio !== 0) ? newWidth / this.chart.aspectRatio : helpers.getMaximumHeight(this.chart.canvas);
canvas.width = this.chart.width = newWidth;
canvas.height = this.chart.height = newHeight;
helpers.retinaScale(this.chart);
if (!silent) {
this.update(this.options.responsiveAnimationDuration);
}
return this;
},
ensureScalesHaveIDs: function ensureScalesHaveIDs() {
var defaultXAxisID = 'x-axis-';
var defaultYAxisID = 'y-axis-';
if (this.options.scales) {
if (this.options.scales.xAxes && this.options.scales.xAxes.length) {
helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) {
xAxisOptions.id = xAxisOptions.id || (defaultXAxisID + index);
}, this);
}
if (this.options.scales.yAxes && this.options.scales.yAxes.length) {
// Build the y axes
helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) {
yAxisOptions.id = yAxisOptions.id || (defaultYAxisID + index);
}, this);
}
}
},
buildScales: function buildScales() {
// Map of scale ID to scale object so we can lookup later
this.scales = {};
// Build the x axes
if (this.options.scales) {
if (this.options.scales.xAxes && this.options.scales.xAxes.length) {
helpers.each(this.options.scales.xAxes, function(xAxisOptions, index) {
var ScaleClass = Chart.scaleService.getScaleConstructor(xAxisOptions.type);
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: xAxisOptions,
chart: this,
id: xAxisOptions.id,
});
this.scales[scale.id] = scale;
}, this);
}
if (this.options.scales.yAxes && this.options.scales.yAxes.length) {
// Build the y axes
helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) {
var ScaleClass = Chart.scaleService.getScaleConstructor(yAxisOptions.type);
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: yAxisOptions,
chart: this,
id: yAxisOptions.id,
});
this.scales[scale.id] = scale;
}, this);
}
}
if (this.options.scale) {
// Build radial axes
var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type);
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: this.options.scale,
chart: this,
});
this.scale = scale;
this.scales.radialScale = scale;
}
Chart.scaleService.addScalesToLayout(this);
},
buildSurroundingItems: function() {
if (this.options.title) {
this.titleBlock = new Chart.Title({
ctx: this.chart.ctx,
options: this.options.title,
chart: this
});
Chart.layoutService.addBox(this, this.titleBlock);
}
if (this.options.legend) {
this.legend = new Chart.Legend({
ctx: this.chart.ctx,
options: this.options.legend,
chart: this,
});
Chart.layoutService.addBox(this, this.legend);
}
},
updateLayout: function() {
Chart.layoutService.update(this, this.chart.width, this.chart.height);
},
buildOrUpdateControllers: function buildOrUpdateControllers(resetNewControllers) {
var types = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (!dataset.type) {
dataset.type = this.config.type;
}
var type = dataset.type;
types.push(type);
if (dataset.controller) {
dataset.controller.updateIndex(datasetIndex);
} else {
dataset.controller = new Chart.controllers[type](this, datasetIndex);
if (resetNewControllers) {
dataset.controller.reset();
}
}
}, this);
if (types.length > 1) {
for (var i = 1; i < types.length; i++) {
if (types[i] != types[i - 1]) {
this.isCombo = true;
break;
}
}
}
},
resetElements: function resetElements() {
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.reset();
}, this);
},
update: function update(animationDuration, lazy) {
// In case the entire data object changed
this.tooltip._data = this.data;
// Make sure dataset controllers are updated and new controllers are reset
this.buildOrUpdateControllers(true);
Chart.layoutService.update(this, this.chart.width, this.chart.height);
// Make sure all dataset controllers have correct meta data counts
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.buildOrUpdateElements();
}, this);
// This will loop through any data and do the appropriate element update for the type
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.update();
}, this);
this.render(animationDuration, lazy);
},
render: function render(duration, lazy) {
if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration == 'undefined' && this.options.animation.duration !== 0))) {
var animation = new Chart.Animation();
animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps
animation.easing = this.options.animation.easing;
// render function
animation.render = function(chartInstance, animationObject) {
var easingFunction = helpers.easingEffects[animationObject.easing];
var stepDecimal = animationObject.currentStep / animationObject.numSteps;
var easeDecimal = easingFunction(stepDecimal);
chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
};
// user events
animation.onAnimationProgress = this.options.animation.onProgress;
animation.onAnimationComplete = this.options.animation.onComplete;
Chart.animationService.addAnimation(this, animation, duration, lazy);
} else {
this.draw();
if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) {
this.options.animation.onComplete.call(this);
}
}
return this;
},
draw: function(ease) {
var easingDecimal = ease || 1;
this.clear();
// Draw all the scales
helpers.each(this.boxes, function(box) {
box.draw(this.chartArea);
}, this);
if (this.scale) {
this.scale.draw();
}
// Draw each dataset via its respective controller (reversed to support proper line stacking)
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
dataset.controller.draw(ease);
}
}, this);
// Finally draw the tooltip
this.tooltip.transition(easingDecimal).draw();
},
// 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 eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
helpers.each(dataset.metaData, function(element, index) {
if (element.inRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
return elementsArray;
}
}, this);
}
}, this);
return elementsArray;
},
getElementsAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
var found = (function(){
for (var i = 0; i < this.data.datasets.length; i++) {
if (helpers.isDatasetVisible(this.data.datasets[i])) {
for (var j = 0; j < this.data.datasets[i].metaData.length; j++) {
if (this.data.datasets[i].metaData[j].inRange(eventPosition.x, eventPosition.y)) {
return this.data.datasets[i].metaData[j];
}
}
}
}
}).call(this);
if(!found){
return elementsArray;
}
helpers.each(this.data.datasets, function(dataset, dsIndex){
if(helpers.isDatasetVisible(dataset)){
elementsArray.push(dataset.metaData[found._index]);
}
}, this);
return elementsArray;
},
getDatasetAtEvent: function(e) {
var elementsArray = this.getElementAtEvent(e);
if (elementsArray.length > 0) {
elementsArray = this.data.datasets[elementsArray[0]._datasetIndex].metaData;
}
return elementsArray;
},
generateLegend: function generateLegend() {
return this.options.legendCallback(this);
},
destroy: function destroy() {
this.clear();
helpers.unbindEvents(this, this.events);
helpers.removeResizeListener(this.chart.canvas.parentNode);
// Reset canvas height/width attributes
var canvas = this.chart.canvas;
canvas.width = this.chart.width;
canvas.height = this.chart.height;
// if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here
if (this.chart.originalDevicePixelRatio !== undefined) {
this.chart.ctx.scale(1 / this.chart.originalDevicePixelRatio, 1 / this.chart.originalDevicePixelRatio);
}
// Reset to the old style since it may have been changed by the device pixel ratio changes
canvas.style.width = this.chart.originalCanvasStyleWidth;
canvas.style.height = this.chart.originalCanvasStyleHeight;
delete Chart.instances[this.id];
},
toBase64Image: function toBase64Image() {
return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
},
initToolTip: function initToolTip() {
this.tooltip = new Chart.Tooltip({
_chart: this.chart,
_chartInstance: this,
_data: this.data,
_options: this.options,
}, this);
},
bindEvents: function bindEvents() {
helpers.bindEvents(this, this.options.events, function(evt) {
this.eventHandler(evt);
});
},
eventHandler: function eventHandler(e) {
this.lastActive = this.lastActive || [];
this.lastTooltipActive = this.lastTooltipActive || [];
// Find Active Elements for hover and tooltips
if (e.type == 'mouseout') {
this.active = [];
this.tooltipActive = [];
} else {
var _this = this;
var getItemsForMode = function(mode) {
switch (mode) {
case 'single':
return _this.getElementAtEvent(e);
case 'label':
return _this.getElementsAtEvent(e);
case 'dataset':
return _this.getDatasetAtEvent(e);
default:
return e;
}
};
this.active = getItemsForMode(this.options.hover.mode);
this.tooltipActive = getItemsForMode(this.options.tooltips.mode);
}
// On Hover hook
if (this.options.hover.onHover) {
this.options.hover.onHover.call(this, this.active);
}
if (e.type == 'mouseup' || e.type == 'click') {
if (this.options.onClick) {
this.options.onClick.call(this, e, this.active);
}
if (this.legend && this.legend.handleEvent) {
this.legend.handleEvent(e);
}
}
var dataset;
var index;
// Remove styling for last active (even if it may still be active)
if (this.lastActive.length) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
break;
case 'label':
case 'dataset':
for (var i = 0; i < this.lastActive.length; i++) {
if (this.lastActive[i])
this.data.datasets[this.lastActive[i]._datasetIndex].controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
}
break;
default:
// Don't change anything
}
}
// Built in hover styling
if (this.active.length && this.options.hover.mode) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.active[0]._datasetIndex].controller.setHoverStyle(this.active[0]);
break;
case 'label':
case 'dataset':
for (var j = 0; j < this.active.length; j++) {
if (this.active[j])
this.data.datasets[this.active[j]._datasetIndex].controller.setHoverStyle(this.active[j]);
}
break;
default:
// Don't change anything
}
}
// Built in Tooltips
if (this.options.tooltips.enabled || this.options.tooltips.custom) {
// The usual updates
this.tooltip.initialize();
this.tooltip._active = this.tooltipActive;
this.tooltip.update();
}
// Hover animations
this.tooltip.pivot();
if (!this.animating) {
var changed;
helpers.each(this.active, function(element, index) {
if (element !== this.lastActive[index]) {
changed = true;
}
}, this);
helpers.each(this.tooltipActive, function(element, index) {
if (element !== this.lastTooltipActive[index]) {
changed = true;
}
}, this);
// If entering, leaving, or changing elements, animate the change via pivot
if ((this.lastActive.length !== this.active.length) ||
(this.lastTooltipActive.length !== this.tooltipActive.length) ||
changed) {
this.stop();
if (this.options.tooltips.enabled || this.options.tooltips.custom) {
this.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.
this.render(this.options.hover.animationDuration, true);
}
}
// Remember Last Actives
this.lastActive = this.active;
this.lastTooltipActive = this.tooltipActive;
return this;
},
});
}).call(this);
-77
Ver Arquivo
@@ -1,77 +0,0 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
// Base class for all dataset controllers (line, bar, etc)
Chart.DatasetController = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.DatasetController.prototype, {
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
linkScales: function() {
if (!this.getDataset().xAxisID) {
this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id;
}
if (!this.getDataset().yAxisID) {
this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id;
}
},
getDataset: function() {
return this.chart.data.datasets[this.index];
},
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var numData = this.getDataset().data.length;
var numMetaData = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numMetaData) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numMetaData - numData);
} else if (numData > numMetaData) {
// Add new elements
for (var index = numMetaData; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
// Controllers should implement the following
addElements: helpers.noop,
addElementAndReset: helpers.noop,
draw: helpers.noop,
removeHoverStyle: helpers.noop,
setHoverStyle: helpers.noop,
update: helpers.noop,
});
Chart.DatasetController.extend = helpers.inherits;
}).call(this);
-91
Ver Arquivo
@@ -1,91 +0,0 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.elements = {};
Chart.Element = function(configuration) {
helpers.extend(this, configuration);
this.initialize.apply(this, arguments);
};
helpers.extend(Chart.Element.prototype, {
initialize: function() {},
pivot: function() {
if (!this._view) {
this._view = helpers.clone(this._model);
}
this._start = helpers.clone(this._view);
return this;
},
transition: function(ease) {
if (!this._view) {
this._view = helpers.clone(this._model);
}
if (!this._start) {
this.pivot();
}
helpers.each(this._model, function(value, key) {
if (key[0] === '_' || !this._model.hasOwnProperty(key)) {
// Only non-underscored properties
}
// Init if doesn't exist
else if (!this._view[key]) {
if (typeof value === 'number' && isNaN(this._view[key]) === false) {
this._view[key] = value * ease;
} else {
this._view[key] = value || null;
}
}
// No unnecessary computations
else if (this._model[key] === this._view[key]) {
// It's the same! Woohoo!
}
// Color transitions if possible
else if (typeof value === 'string') {
try {
var color = helpers.color(this._start[key]).mix(helpers.color(this._model[key]), ease);
this._view[key] = color.rgbString();
} catch (err) {
this._view[key] = value;
}
}
// Number transitions
else if (typeof value === 'number') {
var startVal = this._start[key] !== undefined && isNaN(this._start[key]) === false ? this._start[key] : 0;
this._view[key] = ((this._model[key] - startVal) * ease) + startVal;
}
// Everything else
else {
this._view[key] = value;
}
}, this);
if (ease === 1) {
delete this._start;
}
return this;
},
tooltipPosition: function() {
return {
x: this._model.x,
y: this._model.y
};
},
hasValue: function() {
return helpers.isNumber(this._model.x) && helpers.isNumber(this._model.y);
}
});
Chart.Element.extend = helpers.inherits;
}).call(this);
-857
Ver Arquivo
@@ -1,857 +0,0 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
Chart = root.Chart;
//Global Chart helpers object for utility methods and classes
var helpers = Chart.helpers = {};
//-- Basic js utility methods
var each = helpers.each = function(loopable, callback, self, reverse) {
var additionalArgs = Array.prototype.slice.call(arguments, 3);
// Check to see if null or undefined firstly.
if (loopable) {
if (loopable.length === +loopable.length) {
var i;
if (reverse) {
for (i = loopable.length - 1; i >= 0; i--) {
callback.apply(self, [loopable[i], i].concat(additionalArgs));
}
} else {
for (i = 0; i < loopable.length; i++) {
callback.apply(self, [loopable[i], i].concat(additionalArgs));
}
}
} else {
for (var item in loopable) {
callback.apply(self, [loopable[item], item].concat(additionalArgs));
}
}
}
},
clone = helpers.clone = function(obj) {
var objClone = {};
each(obj, function(value, key) {
if (obj.hasOwnProperty(key)) {
if (helpers.isArray(value)) {
objClone[key] = value.slice(0);
} else if (typeof value === 'object' && value !== null) {
objClone[key] = clone(value);
} else {
objClone[key] = value;
}
}
});
return objClone;
},
extend = helpers.extend = function(base) {
each(Array.prototype.slice.call(arguments, 1), function(extensionObject) {
each(extensionObject, function(value, key) {
if (extensionObject.hasOwnProperty(key)) {
base[key] = value;
}
});
});
return base;
},
// Need a special merge function to chart configs since they are now grouped
configMerge = helpers.configMerge = function(_base) {
var base = clone(_base);
helpers.each(Array.prototype.slice.call(arguments, 1), function(extension) {
helpers.each(extension, function(value, key) {
if (extension.hasOwnProperty(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);
} 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") {
// If we are overwriting an object with an object, do a merge of the properties.
base[key] = helpers.configMerge(base[key], value);
} else {
// can just overwrite the value in this case
base[key] = value;
}
}
});
});
return base;
},
extendDeep = helpers.extendDeep = function(_base) {
return _extendDeep.apply(this, arguments);
function _extendDeep(dst) {
helpers.each(arguments, function(obj) {
if (obj !== dst) {
helpers.each(obj, function(value, key) {
if (dst[key] && dst[key].constructor && dst[key].constructor === Object) {
_extendDeep(dst[key], value);
} else {
dst[key] = value;
}
});
}
});
return dst;
}
},
scaleMerge = helpers.scaleMerge = function(_base, extension) {
var base = clone(_base);
helpers.each(extension, function(value, key) {
if (extension.hasOwnProperty(key)) {
if (key === 'xAxes' || key === 'yAxes') {
// These properties are arrays of items
if (base.hasOwnProperty(key)) {
helpers.each(value, function(valueObj, index) {
if (index >= base[key].length || !base[key][index].type) {
base[key].push(helpers.configMerge(valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj));
} else if (valueObj.type !== base[key][index].type) {
// Type changed. Bring in the new defaults before we bring in valueObj so that valueObj can override the correct scale defaults
base[key][index] = helpers.configMerge(base[key][index], valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj);
} else {
// Type is the same
base[key][index] = helpers.configMerge(base[key][index], valueObj);
}
});
} else {
base[key] = [];
helpers.each(value, function(valueObj) {
base[key].push(helpers.configMerge(valueObj.type ? Chart.scaleService.getScaleDefaults(valueObj.type) : {}, valueObj));
});
}
} else if (base.hasOwnProperty(key) && typeof base[key] == "object" && base[key] !== null && typeof value == "object") {
// If we are overwriting an object with an object, do a merge of the properties.
base[key] = helpers.configMerge(base[key], value);
} else {
// can just overwrite the value in this case
base[key] = value;
}
}
});
return base;
},
getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault = function(value, index, defaultValue) {
if (value === undefined || value === null) {
return defaultValue;
}
if (helpers.isArray(value)) {
return index < value.length ? value[index] : defaultValue;
}
return value;
},
getValueOrDefault = helpers.getValueOrDefault = function(value, defaultValue) {
return value === undefined ? defaultValue : value;
},
indexOf = helpers.indexOf = function(arrayToSearch, item) {
if (Array.prototype.indexOf) {
return arrayToSearch.indexOf(item);
} else {
for (var i = 0; i < arrayToSearch.length; i++) {
if (arrayToSearch[i] === item) return i;
}
return -1;
}
},
where = helpers.where = function(collection, filterCallback) {
var filtered = [];
helpers.each(collection, function(item) {
if (filterCallback(item)) {
filtered.push(item);
}
});
return filtered;
},
findNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {
// Default to start of the array
if (startIndex === undefined || startIndex === null) {
startIndex = -1;
}
for (var i = startIndex + 1; i < arrayToSearch.length; i++) {
var currentItem = arrayToSearch[i];
if (filterCallback(currentItem)) {
return currentItem;
}
}
},
findPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {
// Default to end of the array
if (startIndex === undefined || startIndex === null) {
startIndex = arrayToSearch.length;
}
for (var i = startIndex - 1; i >= 0; i--) {
var currentItem = arrayToSearch[i];
if (filterCallback(currentItem)) {
return currentItem;
}
}
},
inherits = helpers.inherits = function(extensions) {
//Basic javascript inheritance based on the model created in Backbone.js
var parent = this;
var ChartElement = (extensions && extensions.hasOwnProperty("constructor")) ? extensions.constructor : function() {
return parent.apply(this, arguments);
};
var Surrogate = function() {
this.constructor = ChartElement;
};
Surrogate.prototype = parent.prototype;
ChartElement.prototype = new Surrogate();
ChartElement.extend = inherits;
if (extensions) extend(ChartElement.prototype, extensions);
ChartElement.__super__ = parent.prototype;
return ChartElement;
},
noop = helpers.noop = function() {},
uid = helpers.uid = (function() {
var id = 0;
return function() {
return "chart-" + id++;
};
})(),
warn = helpers.warn = function(str) {
//Method for warning of errors
if (console && typeof console.warn === "function") {
console.warn(str);
}
},
//-- Math methods
isNumber = helpers.isNumber = function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
},
max = helpers.max = function(array) {
return Math.max.apply(Math, array);
},
min = helpers.min = function(array) {
return Math.min.apply(Math, array);
},
sign = helpers.sign = function(x) {
if (Math.sign) {
return Math.sign(x);
} else {
x = +x; // convert to a number
if (x === 0 || isNaN(x)) {
return x;
}
return x > 0 ? 1 : -1;
}
},
log10 = helpers.log10 = function(x) {
if (Math.log10) {
return Math.log10(x);
} else {
return Math.log(x) / Math.LN10;
}
},
getDecimalPlaces = helpers.getDecimalPlaces = function(num) {
if (num % 1 !== 0 && isNumber(num)) {
var s = num.toString();
if (s.indexOf("e-") < 0) {
// no exponent, e.g. 0.01
return s.split(".")[1].length;
} else if (s.indexOf(".") < 0) {
// no decimal point, e.g. 1e-9
return parseInt(s.split("e-")[1]);
} else {
// exponent and decimal point, e.g. 1.23e-9
var parts = s.split(".")[1].split("e-");
return parts[0].length + parseInt(parts[1]);
}
} else {
return 0;
}
},
toRadians = helpers.toRadians = function(degrees) {
return degrees * (Math.PI / 180);
},
toDegrees = helpers.toDegrees = function(radians) {
return radians * (180 / Math.PI);
},
// Gets the angle from vertical upright to the point about a centre.
getAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint) {
var distanceFromXCenter = anglePoint.x - centrePoint.x,
distanceFromYCenter = anglePoint.y - centrePoint.y,
radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);
var angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);
if (angle < (-0.5 * Math.PI)) {
angle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]
}
return {
angle: angle,
distance: radialDistanceFromCenter
};
},
aliasPixel = helpers.aliasPixel = function(pixelWidth) {
return (pixelWidth % 2 === 0) ? 0 : 0.5;
},
splineCurve = helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
//Props to Rob Spencer at scaled innovation for his post on splining between points
//http://scaledinnovation.com/analytics/splines/aboutSplines.html
// This function must also respect "skipped" points
var previous = firstPoint.skip ? middlePoint : firstPoint,
current = middlePoint,
next = afterPoint.skip ? middlePoint : afterPoint;
var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
var s01 = d01 / (d01 + d12);
var s12 = d12 / (d01 + d12);
// If all points are the same, s01 & s02 will be inf
s01 = isNaN(s01) ? 0 : s01;
s12 = isNaN(s12) ? 0 : s12;
var fa = t * s01; // scaling factor for triangle Ta
var fb = t * s12;
return {
previous: {
x: current.x - fa * (next.x - previous.x),
y: current.y - fa * (next.y - previous.y)
},
next: {
x: current.x + fb * (next.x - previous.x),
y: current.y + fb * (next.y - previous.y)
}
};
},
nextItem = helpers.nextItem = function(collection, index, loop) {
if (loop) {
return index >= collection.length - 1 ? collection[0] : collection[index + 1];
}
return index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];
},
previousItem = helpers.previousItem = function(collection, index, loop) {
if (loop) {
return index <= 0 ? collection[collection.length - 1] : collection[index - 1];
}
return index <= 0 ? collection[0] : collection[index - 1];
},
// Implementation of the nice number algorithm used in determining where axis labels will go
niceNum = helpers.niceNum = function(range, round) {
var exponent = Math.floor(helpers.log10(range));
var fraction = range / Math.pow(10, exponent);
var niceFraction;
if (round) {
if (fraction < 1.5) {
niceFraction = 1;
} else if (fraction < 3) {
niceFraction = 2;
} else if (fraction < 7) {
niceFraction = 5;
} else {
niceFraction = 10;
}
} else {
if (fraction <= 1.0) {
niceFraction = 1;
} else if (fraction <= 2) {
niceFraction = 2;
} else if (fraction <= 5) {
niceFraction = 5;
} else {
niceFraction = 10;
}
}
return niceFraction * Math.pow(10, exponent);
},
//Easing functions adapted from Robert Penner's easing equations
//http://www.robertpenner.com/easing/
easingEffects = helpers.easingEffects = {
linear: function(t) {
return t;
},
easeInQuad: function(t) {
return t * t;
},
easeOutQuad: function(t) {
return -1 * t * (t - 2);
},
easeInOutQuad: function(t) {
if ((t /= 1 / 2) < 1) {
return 1 / 2 * t * t;
}
return -1 / 2 * ((--t) * (t - 2) - 1);
},
easeInCubic: function(t) {
return t * t * t;
},
easeOutCubic: function(t) {
return 1 * ((t = t / 1 - 1) * t * t + 1);
},
easeInOutCubic: function(t) {
if ((t /= 1 / 2) < 1) {
return 1 / 2 * t * t * t;
}
return 1 / 2 * ((t -= 2) * t * t + 2);
},
easeInQuart: function(t) {
return t * t * t * t;
},
easeOutQuart: function(t) {
return -1 * ((t = t / 1 - 1) * t * t * t - 1);
},
easeInOutQuart: function(t) {
if ((t /= 1 / 2) < 1) {
return 1 / 2 * t * t * t * t;
}
return -1 / 2 * ((t -= 2) * t * t * t - 2);
},
easeInQuint: function(t) {
return 1 * (t /= 1) * t * t * t * t;
},
easeOutQuint: function(t) {
return 1 * ((t = t / 1 - 1) * t * t * t * t + 1);
},
easeInOutQuint: function(t) {
if ((t /= 1 / 2) < 1) {
return 1 / 2 * t * t * t * t * t;
}
return 1 / 2 * ((t -= 2) * t * t * t * t + 2);
},
easeInSine: function(t) {
return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;
},
easeOutSine: function(t) {
return 1 * Math.sin(t / 1 * (Math.PI / 2));
},
easeInOutSine: function(t) {
return -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);
},
easeInExpo: function(t) {
return (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));
},
easeOutExpo: function(t) {
return (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);
},
easeInOutExpo: function(t) {
if (t === 0) {
return 0;
}
if (t === 1) {
return 1;
}
if ((t /= 1 / 2) < 1) {
return 1 / 2 * Math.pow(2, 10 * (t - 1));
}
return 1 / 2 * (-Math.pow(2, -10 * --t) + 2);
},
easeInCirc: function(t) {
if (t >= 1) {
return t;
}
return -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);
},
easeOutCirc: function(t) {
return 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);
},
easeInOutCirc: function(t) {
if ((t /= 1 / 2) < 1) {
return -1 / 2 * (Math.sqrt(1 - t * t) - 1);
}
return 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);
},
easeInElastic: function(t) {
var s = 1.70158;
var p = 0;
var a = 1;
if (t === 0) {
return 0;
}
if ((t /= 1) == 1) {
return 1;
}
if (!p) {
p = 1 * 0.3;
}
if (a < Math.abs(1)) {
a = 1;
s = p / 4;
} else {
s = p / (2 * Math.PI) * Math.asin(1 / a);
}
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
},
easeOutElastic: function(t) {
var s = 1.70158;
var p = 0;
var a = 1;
if (t === 0) {
return 0;
}
if ((t /= 1) == 1) {
return 1;
}
if (!p) {
p = 1 * 0.3;
}
if (a < Math.abs(1)) {
a = 1;
s = p / 4;
} else {
s = p / (2 * Math.PI) * Math.asin(1 / a);
}
return a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;
},
easeInOutElastic: function(t) {
var s = 1.70158;
var p = 0;
var a = 1;
if (t === 0) {
return 0;
}
if ((t /= 1 / 2) == 2) {
return 1;
}
if (!p) {
p = 1 * (0.3 * 1.5);
}
if (a < Math.abs(1)) {
a = 1;
s = p / 4;
} else {
s = p / (2 * Math.PI) * Math.asin(1 / a);
}
if (t < 1) {
return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));
}
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;
},
easeInBack: function(t) {
var s = 1.70158;
return 1 * (t /= 1) * t * ((s + 1) * t - s);
},
easeOutBack: function(t) {
var s = 1.70158;
return 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);
},
easeInOutBack: function(t) {
var s = 1.70158;
if ((t /= 1 / 2) < 1) {
return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));
}
return 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);
},
easeInBounce: function(t) {
return 1 - easingEffects.easeOutBounce(1 - t);
},
easeOutBounce: function(t) {
if ((t /= 1) < (1 / 2.75)) {
return 1 * (7.5625 * t * t);
} else if (t < (2 / 2.75)) {
return 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);
} else if (t < (2.5 / 2.75)) {
return 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);
} else {
return 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);
}
},
easeInOutBounce: function(t) {
if (t < 1 / 2) {
return easingEffects.easeInBounce(t * 2) * 0.5;
}
return easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;
}
},
//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
requestAnimFrame = helpers.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
return window.setTimeout(callback, 1000 / 60);
};
})(),
cancelAnimFrame = helpers.cancelAnimFrame = (function() {
return window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
window.msCancelAnimationFrame ||
function(callback) {
return window.clearTimeout(callback, 1000 / 60);
};
})(),
//-- DOM methods
getRelativePosition = helpers.getRelativePosition = function(evt, chart) {
var mouseX, mouseY;
var e = evt.originalEvent || evt,
canvas = evt.currentTarget || evt.srcElement,
boundingRect = canvas.getBoundingClientRect();
if (e.touches && e.touches.length > 0) {
mouseX = e.touches[0].clientX;
mouseY = e.touches[0].clientY;
} else {
mouseX = e.clientX;
mouseY = e.clientY;
}
// Scale mouse coordinates into canvas coordinates
// by following the pattern laid out by 'jerryj' in the comments of
// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
mouseX = Math.round((mouseX - boundingRect.left) / (boundingRect.right - boundingRect.left) * canvas.width / chart.currentDevicePixelRatio);
mouseY = Math.round((mouseY - boundingRect.top) / (boundingRect.bottom - boundingRect.top) * canvas.height / chart.currentDevicePixelRatio);
return {
x: mouseX,
y: mouseY
};
},
addEvent = helpers.addEvent = function(node, eventType, method) {
if (node.addEventListener) {
node.addEventListener(eventType, method);
} else if (node.attachEvent) {
node.attachEvent("on" + eventType, method);
} else {
node["on" + eventType] = method;
}
},
removeEvent = helpers.removeEvent = function(node, eventType, handler) {
if (node.removeEventListener) {
node.removeEventListener(eventType, handler, false);
} else if (node.detachEvent) {
node.detachEvent("on" + eventType, handler);
} else {
node["on" + eventType] = noop;
}
},
bindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {
// Create the events object if it's not already present
if (!chartInstance.events) chartInstance.events = {};
each(arrayOfEvents, function(eventName) {
chartInstance.events[eventName] = function() {
handler.apply(chartInstance, arguments);
};
addEvent(chartInstance.chart.canvas, eventName, chartInstance.events[eventName]);
});
},
unbindEvents = helpers.unbindEvents = function(chartInstance, arrayOfEvents) {
each(arrayOfEvents, function(handler, eventName) {
removeEvent(chartInstance.chart.canvas, eventName, handler);
});
},
getConstraintWidth = helpers.getConstraintWidth = function(domNode) { // returns Number or undefined if no constraint
var constrainedWidth;
var constrainedWNode = document.defaultView.getComputedStyle(domNode)['max-width'];
var constrainedWContainer = document.defaultView.getComputedStyle(domNode.parentNode)['max-width'];
var hasCWNode = constrainedWNode !== null && constrainedWNode !== "none";
var hasCWContainer = constrainedWContainer !== null && constrainedWContainer !== "none";
if (hasCWNode || hasCWContainer) {
constrainedWidth = Math.min((hasCWNode ? parseInt(constrainedWNode, 10) : Number.POSITIVE_INFINITY), (hasCWContainer ? parseInt(constrainedWContainer, 10) : Number.POSITIVE_INFINITY));
}
return constrainedWidth;
},
getConstraintHeight = helpers.getConstraintHeight = function(domNode) { // returns Number or undefined if no constraint
var constrainedHeight;
var constrainedHNode = document.defaultView.getComputedStyle(domNode)['max-height'];
var constrainedHContainer = document.defaultView.getComputedStyle(domNode.parentNode)['max-height'];
var hasCHNode = constrainedHNode !== null && constrainedHNode !== "none";
var hasCHContainer = constrainedHContainer !== null && constrainedHContainer !== "none";
if (constrainedHNode || constrainedHContainer) {
constrainedHeight = Math.min((hasCHNode ? parseInt(constrainedHNode, 10) : Number.POSITIVE_INFINITY), (hasCHContainer ? parseInt(constrainedHContainer, 10) : Number.POSITIVE_INFINITY));
}
return constrainedHeight;
},
getMaximumWidth = helpers.getMaximumWidth = function(domNode) {
var container = domNode.parentNode;
var padding = parseInt(getStyle(container, 'padding-left')) + parseInt(getStyle(container, 'padding-right'));
var w = container.clientWidth - padding;
var cw = getConstraintWidth(domNode);
if (cw !== undefined) {
w = Math.min(w, cw);
}
return w;
},
getMaximumHeight = helpers.getMaximumHeight = function(domNode) {
var container = domNode.parentNode;
var padding = parseInt(getStyle(container, 'padding-top')) + parseInt(getStyle(container, 'padding-bottom'));
var h = container.clientHeight - padding;
var ch = getConstraintHeight(domNode);
if (ch !== undefined) {
h = Math.min(h, ch);
}
return h;
},
getStyle = helpers.getStyle = function(el, property) {
return el.currentStyle ?
el.currentStyle[property] :
document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
},
getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support
retinaScale = helpers.retinaScale = function(chart) {
var ctx = chart.ctx;
var width = chart.canvas.width;
var height = chart.canvas.height;
var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
if (pixelRatio !== 1) {
ctx.canvas.height = height * pixelRatio;
ctx.canvas.width = width * pixelRatio;
ctx.scale(pixelRatio, pixelRatio);
ctx.canvas.style.width = width + 'px';
ctx.canvas.style.height = height + 'px';
// 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;
}
},
//-- Canvas methods
clear = helpers.clear = function(chart) {
chart.ctx.clearRect(0, 0, chart.width, chart.height);
},
fontString = helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
return fontStyle + " " + pixelSize + "px " + fontFamily;
},
longestText = helpers.longestText = function(ctx, font, arrayOfStrings) {
ctx.font = font;
var longest = 0;
each(arrayOfStrings, function(string) {
var textWidth = ctx.measureText(string).width;
longest = (textWidth > longest) ? textWidth : longest;
});
return longest;
},
drawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
},
color = helpers.color = function(color) {
if (!root.Color) {
console.log('Color.js not found!');
return color;
}
return root.Color(color);
},
addResizeListener = helpers.addResizeListener = function(node, callback) {
// Hide an iframe before the node
var hiddenIframe = document.createElement('iframe');
var hiddenIframeClass = 'chartjs-hidden-iframe';
if (hiddenIframe.classlist) {
// can use classlist
hiddenIframe.classlist.add(hiddenIframeClass);
} else {
hiddenIframe.setAttribute('class', hiddenIframeClass);
}
// Set the style
hiddenIframe.style.width = '100%';
hiddenIframe.style.display = 'block';
hiddenIframe.style.border = 0;
hiddenIframe.style.height = 0;
hiddenIframe.style.margin = 0;
hiddenIframe.style.position = 'absolute';
hiddenIframe.style.left = 0;
hiddenIframe.style.right = 0;
hiddenIframe.style.top = 0;
hiddenIframe.style.bottom = 0;
// Insert the iframe so that contentWindow is available
node.insertBefore(hiddenIframe, node.firstChild);
var timer = 0;
(hiddenIframe.contentWindow || hiddenIframe).onresize = function() {
if (callback) {
callback();
}
};
},
removeResizeListener = helpers.removeResizeListener = function(node) {
var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
// Remove the resize detect iframe
if (hiddenIframe) {
hiddenIframe.parentNode.removeChild(hiddenIframe);
}
},
isArray = helpers.isArray = function(obj) {
if (!Array.isArray) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return Array.isArray(obj);
},
isDatasetVisible = helpers.isDatasetVisible = function(dataset) {
return !dataset.hidden;
};
helpers.callCallback = function(fn, args, _tArg) {
if (fn && typeof fn.call === 'function') {
fn.apply(_tArg, args);
}
}
}).call(this);
-119
Ver Arquivo
@@ -1,119 +0,0 @@
/*!
* Chart.js
* http://chartjs.org/
* Version: {{ version }}
*
* Copyright 2015 Nick Downie
* Released under the MIT license
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
previous = root.Chart;
//Occupy the global variable of Chart, and create a simple base class
var Chart = function(context, config) {
this.config = config;
// 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");
}
this.ctx = context;
this.canvas = context.canvas;
// 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
this.width = context.canvas.width || parseInt(Chart.helpers.getStyle(context.canvas, 'width')) || Chart.helpers.getMaximumWidth(context.canvas);
this.height = context.canvas.height || parseInt(Chart.helpers.getStyle(context.canvas, 'height')) || Chart.helpers.getMaximumHeight(context.canvas);
this.aspectRatio = this.width / this.height;
if (isNaN(this.aspectRatio) || isFinite(this.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
this.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
}
// Store the original style of the element so we can set it back
this.originalCanvasStyleWidth = context.canvas.style.width;
this.originalCanvasStyleHeight = context.canvas.style.height;
// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
Chart.helpers.retinaScale(this);
if (config) {
this.controller = new Chart.Controller(this);
}
// Always bind this so that if the responsive state changes we still work
var _this = this;
Chart.helpers.addResizeListener(context.canvas.parentNode, function() {
if (_this.controller && _this.controller.config.options.responsive) {
_this.controller.resize();
}
});
return this.controller ? this.controller : this;
};
//Globally expose the defaults to allow for user updating/changing
Chart.defaults = {
global: {
responsive: true,
responsiveAnimationDuration: 0,
maintainAspectRatio: true,
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"],
hover: {
onHover: null,
mode: 'single',
animationDuration: 400,
},
onClick: null,
defaultColor: 'rgba(0,0,0,0.1)',
// Element defaults defined in element extensions
elements: {},
// Legend callback string
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
for (var i = 0; i < chart.data.datasets.length; i++) {
text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '">');
if (chart.data.datasets[i].label) {
text.push(chart.data.datasets[i].label);
}
text.push('</span></li>');
}
text.push('</ul>');
return text.join("");
}
},
};
root.Chart = Chart;
Chart.noConflict = function() {
root.Chart = previous;
return Chart;
};
}).call(this);
-324
Ver Arquivo
@@ -1,324 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
// The layout service is ver self explanatory. It's responsible for the layout within a chart.
// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
// It is this service's responsibility of carrying out that layout.
Chart.layoutService = {
defaults: {},
// Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.
addBox: function(chartInstance, box) {
if (!chartInstance.boxes) {
chartInstance.boxes = [];
}
chartInstance.boxes.push(box);
},
removeBox: function(chartInstance, box) {
if (!chartInstance.boxes) {
return;
}
chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);
},
// The most important function
update: function(chartInstance, width, height) {
if (!chartInstance) {
return;
}
var xPadding = width > 30 ? 5 : 2;
var yPadding = height > 30 ? 5 : 2;
var leftBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position == "left";
});
var rightBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position == "right";
});
var topBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position == "top";
});
var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position == "bottom";
});
// Boxes that overlay the chartarea such as the radialLinear scale
var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position == "chartArea";
});
function fullWidthSorter(a, b) {
}
// Ensure that full width boxes are at the very top / bottom
topBoxes.sort(function(a, b) {
return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);
});
bottomBoxes.sort(function(a, b) {
return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);
});
// Essentially we now have any number of boxes on each of the 4 sides.
// Our canvas looks like the following.
// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
// B1 is the bottom axis
// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
// These locations are single-box locations only, when trying to register a chartArea location that is already taken,
// an error will be thrown.
//
// |----------------------------------------------------|
// | T1 (Full Width) |
// |----------------------------------------------------|
// | | | T2 | |
// | |----|-------------------------------------|----|
// | | | C1 | | C2 | |
// | | |----| |----| |
// | | | | |
// | L1 | L2 | ChartArea (C0) | R1 |
// | | | | |
// | | |----| |----| |
// | | | C3 | | C4 | |
// | |----|-------------------------------------|----|
// | | | B1 | |
// |----------------------------------------------------|
// | B2 (Full Width) |
// |----------------------------------------------------|
//
// What we do to find the best sizing, we do the following
// 1. Determine the minimum size of the chart area.
// 2. Split the remaining width equally between each vertical axis
// 3. Split the remaining height equally between each horizontal axis
// 4. Give each layout the maximum size it can be. The layout will return it's minimum size
// 5. Adjust the sizes of each axis based on it's minimum reported size.
// 6. Refit each axis
// 7. Position each axis in the final location
// 8. Tell the chart the final location of the chart area
// 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 chartAreaWidth = chartWidth / 2; // min 50%
var chartAreaHeight = chartHeight / 2; // min 50%
// Step 2
var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
// Step 3
var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
// Step 4
var maxChartAreaWidth = chartWidth;
var maxChartAreaHeight = chartHeight;
var minBoxSizes = [];
helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
function getMinimumBoxSize(box) {
var minSize;
var isHorizontal = box.isHorizontal();
if (isHorizontal) {
minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
maxChartAreaHeight -= minSize.height;
} else {
minSize = box.update(verticalBoxWidth, chartAreaHeight);
maxChartAreaWidth -= minSize.width;
}
minBoxSizes.push({
horizontal: isHorizontal,
minSize: minSize,
box: box,
});
}
// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
// 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;
// Update, and calculate the left and right margins for the horizontal boxes
helpers.each(leftBoxes.concat(rightBoxes), fitBox);
helpers.each(leftBoxes, function(box) {
totalLeftBoxesWidth += box.width;
});
helpers.each(rightBoxes, function(box) {
totalRightBoxesWidth += box.width;
});
// Set the Left and Right margins for the horizontal boxes
helpers.each(topBoxes.concat(bottomBoxes), fitBox);
// Function to fit a box
function fitBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
return minBoxSize.box === box;
});
if (minBoxSize) {
if (box.isHorizontal()) {
var scaleMargin = {
left: totalLeftBoxesWidth,
right: totalRightBoxesWidth,
top: 0,
bottom: 0,
};
box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, minBoxSize.minSize.height, scaleMargin);
} else {
box.update(minBoxSize.minSize.width, maxChartAreaHeight);
}
}
}
// Figure out how much margin is on the top and bottom of the vertical boxes
helpers.each(topBoxes, function(box) {
totalTopBoxesHeight += box.height;
});
helpers.each(bottomBoxes, function(box) {
totalBottomBoxesHeight += box.height;
});
// Let the left layout know the final margin
helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
function finalFitVerticalBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
return minBoxSize.box === box;
});
var scaleMargin = {
left: 0,
right: 0,
top: totalTopBoxesHeight,
bottom: totalBottomBoxesHeight
};
if (minBoxSize) {
box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
}
}
// 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;
helpers.each(leftBoxes, function(box) {
totalLeftBoxesWidth += box.width;
});
helpers.each(rightBoxes, function(box) {
totalRightBoxesWidth += box.width;
});
helpers.each(topBoxes, function(box) {
totalTopBoxesHeight += box.height;
});
helpers.each(bottomBoxes, function(box) {
totalBottomBoxesHeight += box.height;
});
// Figure out if our chart area changed. This would occur if the dataset layout label rotation
// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
// without calling `fit` again
var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
helpers.each(leftBoxes, function(box) {
box.height = newMaxChartAreaHeight;
});
helpers.each(rightBoxes, function(box) {
box.height = newMaxChartAreaHeight;
});
helpers.each(topBoxes, function(box) {
box.width = newMaxChartAreaWidth;
});
helpers.each(bottomBoxes, function(box) {
box.width = newMaxChartAreaWidth;
});
maxChartAreaHeight = newMaxChartAreaHeight;
maxChartAreaWidth = newMaxChartAreaWidth;
}
// Step 7 - Position the boxes
var left = xPadding;
var top = yPadding;
var right = 0;
var bottom = 0;
helpers.each(leftBoxes.concat(topBoxes), placeBox);
// Account for chart width and height
left += maxChartAreaWidth;
top += maxChartAreaHeight;
helpers.each(rightBoxes, placeBox);
helpers.each(bottomBoxes, placeBox);
function placeBox(box) {
if (box.isHorizontal()) {
box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;
box.top = top;
box.bottom = top + box.height;
// Move to next point
top = box.bottom;
} else {
box.left = left;
box.right = left + box.width;
box.top = totalTopBoxesHeight;
box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
// Move to next point
left = box.right;
}
}
// Step 8
chartInstance.chartArea = {
left: totalLeftBoxesWidth,
top: totalTopBoxesHeight,
right: totalLeftBoxesWidth + maxChartAreaWidth,
bottom: totalTopBoxesHeight + maxChartAreaHeight,
};
// Step 9
helpers.each(chartAreaBoxes, function(box) {
box.left = chartInstance.chartArea.left;
box.top = chartInstance.chartArea.top;
box.right = chartInstance.chartArea.right;
box.bottom = chartInstance.chartArea.bottom;
box.update(maxChartAreaWidth, maxChartAreaHeight);
});
}
};
}).call(this);
-325
Ver Arquivo
@@ -1,325 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.legend = {
display: true,
position: 'top',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
// a callback that will handle
onClick: function(e, legendItem) {
var dataset = this.chart.data.datasets[legendItem.datasetIndex];
dataset.hidden = !dataset.hidden;
// We hid a dataset ... rerender the chart
this.chart.update();
},
labels: {
boxWidth: 40,
fontSize: 12,
fontStyle: "normal",
fontColor: "#666",
fontFamily: "Helvetica Neue",
padding: 10,
// Generates labels shown in the legend
// Valid properties to return:
// text : text to display
// fillStyle : fill of coloured box
// strokeStyle: stroke of coloured box
// hidden : if this legend item refers to a hidden item
// lineCap : cap style for line
// lineDash
// lineDashOffset :
// lineJoin :
// lineWidth :
generateLabels: function(data) {
return data.datasets.map(function(dataset, i) {
return {
text: dataset.label,
fillStyle: dataset.backgroundColor,
hidden: dataset.hidden,
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
lineJoin: dataset.borderJoinStyle,
lineWidth: dataset.borderWidth,
strokeStyle: dataset.borderColor,
// Below is extra data used for toggling the datasets
datasetIndex: i
};
}, this);
}
},
};
Chart.Legend = Chart.Element.extend({
initialize: function(config) {
helpers.extend(this, config);
// Contains hit boxes for each dataset (in dataset order)
this.legendHitBoxes = [];
// Are we in doughnut mode which has a different data type
this.doughnutMode = false;
},
// These methods are ordered by lifecyle. Utilities then follow.
// Any function defined here is inherited by all legend types.
// Any function can be extended by the legend type
beforeUpdate: helpers.noop,
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = margins;
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Labels
this.beforeBuildLabels();
this.buildLabels();
this.afterBuildLabels();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: helpers.noop,
//
beforeSetDimensions: helpers.noop,
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
// Reset minSize
this.minSize = {
width: 0,
height: 0,
};
},
afterSetDimensions: helpers.noop,
//
beforeBuildLabels: helpers.noop,
buildLabels: function() {
this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data);
},
afterBuildLabels: helpers.noop,
//
beforeFit: helpers.noop,
fit: function() {
var ctx = this.ctx;
var labelFont = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
// Reset hit boxes
this.legendHitBoxes = [];
// Width
if (this.isHorizontal()) {
this.minSize.width = this.maxWidth; // fill all the width
} else {
this.minSize.width = this.options.display ? 10 : 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.display ? 10 : 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Increase sizes here
if (this.options.display) {
if (this.isHorizontal()) {
// Labels
// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
this.lineWidths = [0];
var totalHeight = this.legendItems.length ? this.options.labels.fontSize + (this.options.labels.padding) : 0;
ctx.textAlign = "left";
ctx.textBaseline = 'top';
ctx.font = labelFont;
helpers.each(this.legendItems, function(legendItem, i) {
var width = this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + ctx.measureText(legendItem.text).width;
if (this.lineWidths[this.lineWidths.length - 1] + width >= this.width) {
totalHeight += this.options.labels.fontSize + (this.options.labels.padding);
this.lineWidths[this.lineWidths.length] = this.left;
}
// Store the hitbox width and height here. Final position will be updated in `draw`
this.legendHitBoxes[i] = {
left: 0,
top: 0,
width: width,
height: this.options.labels.fontSize,
};
this.lineWidths[this.lineWidths.length - 1] += width + this.options.labels.padding;
}, this);
this.minSize.height += totalHeight;
} else {
// TODO vertical
}
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: helpers.noop,
// Shared Methods
isHorizontal: function() {
return this.options.position == "top" || this.options.position == "bottom";
},
// Actualy draw the legend on the canvas
draw: function() {
if (this.options.display) {
var ctx = this.ctx;
var cursor = {
x: this.left + ((this.width - this.lineWidths[0]) / 2),
y: this.top + this.options.labels.padding,
line: 0,
};
var labelFont = helpers.fontString(this.options.labels.fontSize, this.options.labels.fontStyle, this.options.labels.fontFamily);
// Horizontal
if (this.isHorizontal()) {
// Labels
ctx.textAlign = "left";
ctx.textBaseline = 'top';
ctx.lineWidth = 0.5;
ctx.strokeStyle = this.options.labels.fontColor; // for strikethrough effect
ctx.fillStyle = this.options.labels.fontColor; // render in correct colour
ctx.font = labelFont;
helpers.each(this.legendItems, function(legendItem, i) {
var textWidth = ctx.measureText(legendItem.text).width;
var width = this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + textWidth;
if (cursor.x + width >= this.width) {
cursor.y += this.options.labels.fontSize + (this.options.labels.padding);
cursor.line++;
cursor.x = this.left + ((this.width - this.lineWidths[cursor.line]) / 2);
}
// Set the ctx for the box
ctx.save();
var itemOrDefault = function(item, defaulVal) {
return item !== undefined ? item : defaulVal;
};
ctx.fillStyle = itemOrDefault(legendItem.fillStyle, Chart.defaults.global.defaultColor);
ctx.lineCap = itemOrDefault(legendItem.lineCap, Chart.defaults.global.elements.line.borderCapStyle);
ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, Chart.defaults.global.elements.line.borderDashOffset);
ctx.lineJoin = itemOrDefault(legendItem.lineJoin, Chart.defaults.global.elements.line.borderJoinStyle);
ctx.lineWidth = itemOrDefault(legendItem.lineWidth, Chart.defaults.global.elements.line.borderWidth);
ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, Chart.defaults.global.defaultColor);
if (ctx.setLineDash) {
// IE 9 and 10 do not support line dash
ctx.setLineDash(itemOrDefault(legendItem.lineDash, Chart.defaults.global.elements.line.borderDash));
}
// Draw the box
ctx.strokeRect(cursor.x, cursor.y, this.options.labels.boxWidth, this.options.labels.fontSize);
ctx.fillRect(cursor.x, cursor.y, this.options.labels.boxWidth, this.options.labels.fontSize);
ctx.restore();
this.legendHitBoxes[i].left = cursor.x;
this.legendHitBoxes[i].top = cursor.y;
// Fill the actual label
ctx.fillText(legendItem.text, this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + cursor.x, cursor.y);
if (legendItem.hidden) {
// Strikethrough the text if hidden
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + cursor.x, cursor.y + (this.options.labels.fontSize / 2));
ctx.lineTo(this.options.labels.boxWidth + (this.options.labels.fontSize / 2) + cursor.x + textWidth, cursor.y + (this.options.labels.fontSize / 2));
ctx.stroke();
}
cursor.x += width + (this.options.labels.padding);
}, this);
} else {
}
}
},
// Handle an event
handleEvent: function(e) {
var position = helpers.getRelativePosition(e, this.chart.chart);
if (position.x >= this.left && position.x <= this.right && position.y >= this.top && position.y <= this.bottom) {
// See if we are touching one of the dataset boxes
for (var i = 0; i < this.legendHitBoxes.length; ++i) {
var hitBox = this.legendHitBoxes[i];
if (position.x >= hitBox.left && position.x <= hitBox.left + hitBox.width && position.y >= hitBox.top && position.y <= hitBox.top + hitBox.height) {
// Touching an element
if (this.options.onClick) {
this.options.onClick.call(this, e, this.legendItems[i]);
}
break;
}
}
}
}
});
}).call(this);
-637
Ver Arquivo
@@ -1,637 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.scale = {
display: true,
// grid line settings
gridLines: {
display: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1,
drawOnChartArea: true,
drawTicks: true,
zeroLineWidth: 1,
zeroLineColor: "rgba(0,0,0,0.25)",
offsetGridLines: false,
},
// scale label
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
// actual label
labelString: '',
// display property
display: false,
},
// label settings
ticks: {
beginAtZero: false,
fontSize: 12,
fontStyle: "normal",
fontColor: "#666",
fontFamily: "Helvetica Neue",
maxRotation: 90,
mirror: false,
padding: 10,
reverse: false,
display: true,
autoSkip: true,
autoSkipPadding: 20,
callback: function(value) {
return '' + value;
},
},
};
Chart.Scale = Chart.Element.extend({
// These methods are ordered by lifecyle. Utilities then follow.
// Any function defined here is inherited by all scale types.
// Any function can be extended by the scale type
beforeUpdate: function() {
helpers.callCallback(this.options.beforeUpdate, [this]);
},
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = helpers.extend({
left: 0,
right: 0,
top: 0,
bottom: 0
}, margins);
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Data min/max
this.beforeDataLimits();
this.determineDataLimits();
this.afterDataLimits();
// Ticks
this.beforeBuildTicks();
this.buildTicks();
this.afterBuildTicks();
this.beforeTickToLabelConversion();
this.convertTicksToLabels();
this.afterTickToLabelConversion();
// Tick Rotation
this.beforeCalculateTickRotation();
this.calculateTickRotation();
this.afterCalculateTickRotation();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: function() {
helpers.callCallback(this.options.afterUpdate, [this]);
},
//
beforeSetDimensions: function() {
helpers.callCallback(this.options.beforeSetDimensions, [this]);
},
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
},
afterSetDimensions: function() {
helpers.callCallback(this.options.afterSetDimensions, [this]);
},
// Data limits
beforeDataLimits: function() {
helpers.callCallback(this.options.beforeDataLimits, [this]);
},
determineDataLimits: helpers.noop,
afterDataLimits: function() {
helpers.callCallback(this.options.afterDataLimits, [this]);
},
//
beforeBuildTicks: function() {
helpers.callCallback(this.options.beforeBuildTicks, [this]);
},
buildTicks: helpers.noop,
afterBuildTicks: function() {
helpers.callCallback(this.options.afterBuildTicks, [this]);
},
beforeTickToLabelConversion: function() {
helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);
},
convertTicksToLabels: function() {
// Convert ticks to strings
this.ticks = this.ticks.map(function(numericalTick, index, ticks) {
if (this.options.ticks.userCallback) {
return this.options.ticks.userCallback(numericalTick, index, ticks);
}
return this.options.ticks.callback(numericalTick, index, ticks);
},
this);
},
afterTickToLabelConversion: function() {
helpers.callCallback(this.options.afterTickToLabelConversion, [this]);
},
//
beforeCalculateTickRotation: function() {
helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);
},
calculateTickRotation: function() {
//Get the width of each grid by calculating the difference
//between x offsets between 0 and 1.
var labelFont = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
this.ctx.font = labelFont;
var firstWidth = this.ctx.measureText(this.ticks[0]).width;
var lastWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width;
var firstRotated;
var lastRotated;
this.paddingRight = lastWidth / 2 + 3;
this.paddingLeft = firstWidth / 2 + 3;
this.labelRotation = 0;
if (this.options.display && this.isHorizontal()) {
var originalLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
var cosRotation;
var sinRotation;
this.labelWidth = originalLabelWidth;
// Allow 3 pixels x2 padding either side for label readability
// only the index matters for a dataset scale, but we want a consistent interface between scales
var tickWidth = this.getPixelForTick(1) - this.getPixelForTick(0) - 6;
//Max label rotation can be set or default to 90 - also act as a loop counter
while (this.labelWidth > tickWidth && this.labelRotation < this.options.ticks.maxRotation) {
cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
firstRotated = cosRotation * firstWidth;
lastRotated = cosRotation * lastWidth;
// We're right aligning the text now.
if (firstRotated + this.options.ticks.fontSize / 2 > this.yLabelWidth) {
this.paddingLeft = firstRotated + this.options.ticks.fontSize / 2;
}
this.paddingRight = this.options.ticks.fontSize / 2;
if (sinRotation * originalLabelWidth > this.maxHeight) {
// go back one step
this.labelRotation--;
break;
}
this.labelRotation++;
this.labelWidth = cosRotation * originalLabelWidth;
}
} else {
this.labelWidth = 0;
this.paddingRight = 0;
this.paddingLeft = 0;
}
if (this.margins) {
this.paddingLeft -= this.margins.left;
this.paddingRight -= this.margins.right;
this.paddingLeft = Math.max(this.paddingLeft, 0);
this.paddingRight = Math.max(this.paddingRight, 0);
}
},
afterCalculateTickRotation: function() {
helpers.callCallback(this.options.afterCalculateTickRotation, [this]);
},
//
beforeFit: function() {
helpers.callCallback(this.options.beforeFit, [this]);
},
fit: function() {
this.minSize = {
width: 0,
height: 0,
};
// Width
if (this.isHorizontal()) {
// subtract the margins to line up with the chartArea if we are a full width scale
this.minSize.width = this.isFullWidth() ? this.maxWidth - this.margins.left - this.margins.right : this.maxWidth;
} else {
this.minSize.width = this.options.gridLines.display && this.options.display ? 10 : 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.gridLines.display && this.options.display ? 10 : 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Are we showing a title for the scale?
if (this.options.scaleLabel.display) {
if (this.isHorizontal()) {
this.minSize.height += (this.options.scaleLabel.fontSize * 1.5);
} else {
this.minSize.width += (this.options.scaleLabel.fontSize * 1.5);
}
}
if (this.options.ticks.display && this.options.display) {
// Don't bother fitting the ticks if we are not showing them
var labelFont = helpers.fontString(this.options.ticks.fontSize,
this.options.ticks.fontStyle, this.options.ticks.fontFamily);
if (this.isHorizontal()) {
// A horizontal axis is more constrained by the height.
this.longestLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
// TODO - improve this calculation
var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * this.options.ticks.fontSize;
this.minSize.height = Math.min(this.maxHeight, this.minSize.height + labelHeight);
labelFont = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
this.ctx.font = labelFont;
var firstLabelWidth = this.ctx.measureText(this.ticks[0]).width;
var lastLabelWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width;
// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned which means that the right padding is dominated
// by the font height
var cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
var sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
this.paddingLeft = this.labelRotation !== 0 ? (cosRotation * firstLabelWidth) + 3 : firstLabelWidth / 2 + 3; // add 3 px to move away from canvas edges
this.paddingRight = this.labelRotation !== 0 ? (sinRotation * (this.options.ticks.fontSize / 2)) + 3 : lastLabelWidth / 2 + 3; // when rotated
} else {
// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
var maxLabelWidth = this.maxWidth - this.minSize.width;
var largestTextWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
// Account for padding
if (!this.options.ticks.mirror) {
largestTextWidth += this.options.ticks.padding;
}
if (largestTextWidth < maxLabelWidth) {
// We don't need all the room
this.minSize.width += largestTextWidth;
} else {
// Expand to max size
this.minSize.width = this.maxWidth;
}
this.paddingTop = this.options.ticks.fontSize / 2;
this.paddingBottom = this.options.ticks.fontSize / 2;
}
}
if (this.margins) {
this.paddingLeft -= this.margins.left;
this.paddingTop -= this.margins.top;
this.paddingRight -= this.margins.right;
this.paddingBottom -= this.margins.bottom;
this.paddingLeft = Math.max(this.paddingLeft, 0);
this.paddingTop = Math.max(this.paddingTop, 0);
this.paddingRight = Math.max(this.paddingRight, 0);
this.paddingBottom = Math.max(this.paddingBottom, 0);
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: function() {
helpers.callCallback(this.options.afterFit, [this]);
},
// Shared Methods
isHorizontal: function() {
return this.options.position === "top" || this.options.position === "bottom";
},
isFullWidth: function() {
return (this.options.fullWidth);
},
// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
getRightValue: function getRightValue(rawValue) {
// Null and undefined values first
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)) {
return NaN;
}
// If it is in fact an object, dive in one more level
if (typeof(rawValue) === "object") {
if (rawValue instanceof Date) {
return rawValue;
} else {
return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
}
}
// Value is good, return it
return rawValue;
},
// Used to get the value to display in the tooltip for the data at the given index
// function getLabelForIndex(index, datasetIndex)
getLabelForIndex: helpers.noop,
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: helpers.noop,
// Used for tick location, should
getPixelForTick: function(index, includeOffset) {
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var tickWidth = innerWidth / Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var pixel = (tickWidth * index) + this.paddingLeft;
if (includeOffset) {
pixel += tickWidth / 2;
}
var finalVal = this.left + Math.round(pixel);
finalVal += this.isFullWidth() ? this.margins.left : 0;
return finalVal;
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
return this.top + (index * (innerHeight / (this.ticks.length - 1)));
}
},
// Utility for getting the pixel location of a percentage of scale
getPixelForDecimal: function(decimal/*, includeOffset*/) {
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueOffset = (innerWidth * decimal) + this.paddingLeft;
var finalVal = this.left + Math.round(valueOffset);
finalVal += this.isFullWidth() ? this.margins.left : 0;
return finalVal;
} else {
return this.top + (decimal * this.height);
}
},
// Actualy draw the scale on the canvas
// @param {rectangle} chartArea : the area of the chart to draw full grid lines on
draw: function(chartArea) {
if (this.options.display) {
var setContextLineSettings;
var isRotated = this.labelRotation !== 0;
var skipRatio;
var scaleLabelX;
var scaleLabelY;
var useAutoskipper = this.options.ticks.autoSkip;
// Make sure we draw text in the correct color and font
this.ctx.fillStyle = this.options.ticks.fontColor;
var labelFont = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
var cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
var sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
var longestRotatedLabel = this.longestLabelWidth * cosRotation;
var rotatedLabelHeight = this.options.ticks.fontSize * sinRotation;
if (this.isHorizontal()) {
setContextLineSettings = true;
var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - 10;
var yTickEnd = this.options.position === "bottom" ? this.top + 10 : this.bottom;
skipRatio = false;
if (((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) {
skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
}
if (!useAutoskipper) {
skipRatio = false;
}
helpers.each(this.ticks, function(label, index) {
// Blank ticks
if ((skipRatio > 1 && index % skipRatio > 0) || (label === undefined || label === null)) {
return;
}
var xLineValue = this.getPixelForTick(index); // xvalues for grid lines
var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option)
if (this.options.gridLines.display) {
if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) {
// Draw the first index specially
this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
setContextLineSettings = true; // reset next time
} else if (setContextLineSettings) {
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
setContextLineSettings = false;
}
xLineValue += helpers.aliasPixel(this.ctx.lineWidth);
// Draw the label area
this.ctx.beginPath();
if (this.options.gridLines.drawTicks) {
this.ctx.moveTo(xLineValue, yTickStart);
this.ctx.lineTo(xLineValue, yTickEnd);
}
// Draw the chart area
if (this.options.gridLines.drawOnChartArea) {
this.ctx.moveTo(xLineValue, chartArea.top);
this.ctx.lineTo(xLineValue, chartArea.bottom);
}
// Need to stroke in the loop because we are potentially changing line widths & colours
this.ctx.stroke();
}
if (this.options.ticks.display) {
this.ctx.save();
this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - 10 : this.top + 10);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = labelFont;
this.ctx.textAlign = (isRotated) ? "right" : "center";
this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, this);
if (this.options.scaleLabel.display) {
// Draw the scale label
this.ctx.textAlign = "center";
this.ctx.textBaseline = 'middle';
this.ctx.fillStyle = this.options.scaleLabel.fontColor; // render in correct colour
this.ctx.font = helpers.fontString(this.options.scaleLabel.fontSize, this.options.scaleLabel.fontStyle, this.options.scaleLabel.fontFamily);
scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width
scaleLabelY = this.options.position === 'bottom' ? this.bottom - (this.options.scaleLabel.fontSize / 2) : this.top + (this.options.scaleLabel.fontSize / 2);
this.ctx.fillText(this.options.scaleLabel.labelString, scaleLabelX, scaleLabelY);
}
} else {
setContextLineSettings = true;
var xTickStart = this.options.position === "right" ? this.left : this.right - 5;
var xTickEnd = this.options.position === "right" ? this.left + 5 : this.right;
helpers.each(this.ticks, function(label, index) {
// If the callback returned a null or undefined value, do not draw this line
if (label === undefined || label === null) {
return;
}
var yLineValue = this.getPixelForTick(index); // xvalues for grid lines
if (this.options.gridLines.display) {
if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) {
// Draw the first index specially
this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
setContextLineSettings = true; // reset next time
} else if (setContextLineSettings) {
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
setContextLineSettings = false;
}
yLineValue += helpers.aliasPixel(this.ctx.lineWidth);
// Draw the label area
this.ctx.beginPath();
if (this.options.gridLines.drawTicks) {
this.ctx.moveTo(xTickStart, yLineValue);
this.ctx.lineTo(xTickEnd, yLineValue);
}
// Draw the chart area
if (this.options.gridLines.drawOnChartArea) {
this.ctx.moveTo(chartArea.left, yLineValue);
this.ctx.lineTo(chartArea.right, yLineValue);
}
// Need to stroke in the loop because we are potentially changing line widths & colours
this.ctx.stroke();
}
if (this.options.ticks.display) {
var xLabelValue;
var yLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option)
this.ctx.save();
if (this.options.position === "left") {
if (this.options.ticks.mirror) {
xLabelValue = this.right + this.options.ticks.padding;
this.ctx.textAlign = "left";
} else {
xLabelValue = this.right - this.options.ticks.padding;
this.ctx.textAlign = "right";
}
} else {
// right side
if (this.options.ticks.mirror) {
xLabelValue = this.left - this.options.ticks.padding;
this.ctx.textAlign = "right";
} else {
xLabelValue = this.left + this.options.ticks.padding;
this.ctx.textAlign = "left";
}
}
this.ctx.translate(xLabelValue, yLabelValue);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = labelFont;
this.ctx.textBaseline = "middle";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, this);
if (this.options.scaleLabel.display) {
// Draw the scale label
scaleLabelX = this.options.position === 'left' ? this.left + (this.options.scaleLabel.fontSize / 2) : this.right - (this.options.scaleLabel.fontSize / 2);
scaleLabelY = this.top + ((this.bottom - this.top) / 2);
var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
this.ctx.save();
this.ctx.translate(scaleLabelX, scaleLabelY);
this.ctx.rotate(rotation);
this.ctx.textAlign = "center";
this.ctx.fillStyle = this.options.scaleLabel.fontColor; // render in correct colour
this.ctx.font = helpers.fontString(this.options.scaleLabel.fontSize, this.options.scaleLabel.fontStyle, this.options.scaleLabel.fontFamily);
this.ctx.textBaseline = 'middle';
this.ctx.fillText(this.options.scaleLabel.labelString, 0, 0);
this.ctx.restore();
}
}
}
}
});
}).call(this);
-37
Ver Arquivo
@@ -1,37 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.scaleService = {
// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
// use the new chart options to grab the correct scale
constructors: {},
// Use a registration function so that we can move to an ES6 map when we no longer need to support
// old browsers
// Scale config defaults
defaults: {},
registerScaleType: function(type, scaleConstructor, defaults) {
this.constructors[type] = scaleConstructor;
this.defaults[type] = helpers.clone(defaults);
},
getScaleConstructor: function(type) {
return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
},
getScaleDefaults: function(type) {
// Return the scale defaults merged with the global settings so that we always use the latest ones
return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};
},
addScalesToLayout: function(chartInstance) {
// Adds each scale to the chart.boxes array to be sized accordingly
helpers.each(chartInstance.scales, function(scale) {
Chart.layoutService.addBox(chartInstance, scale);
});
},
};
}).call(this);
-195
Ver Arquivo
@@ -1,195 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.title = {
display: false,
position: 'top',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'bold',
padding: 10,
// actual title
text: '',
};
Chart.Title = Chart.Element.extend({
initialize: function(config) {
helpers.extend(this, config);
this.options = helpers.configMerge(Chart.defaults.global.title, config.options);
// Contains hit boxes for each dataset (in dataset order)
this.legendHitBoxes = [];
},
// These methods are ordered by lifecyle. Utilities then follow.
beforeUpdate: helpers.noop,
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = margins;
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Labels
this.beforeBuildLabels();
this.buildLabels();
this.afterBuildLabels();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: helpers.noop,
//
beforeSetDimensions: helpers.noop,
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
// Reset minSize
this.minSize = {
width: 0,
height: 0,
};
},
afterSetDimensions: helpers.noop,
//
beforeBuildLabels: helpers.noop,
buildLabels: helpers.noop,
afterBuildLabels: helpers.noop,
//
beforeFit: helpers.noop,
fit: function() {
var ctx = this.ctx;
var titleFont = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
// Width
if (this.isHorizontal()) {
this.minSize.width = this.maxWidth; // fill all the width
} else {
this.minSize.width = 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Increase sizes here
if (this.isHorizontal()) {
// Title
if (this.options.display) {
this.minSize.height += this.options.fontSize + (this.options.padding * 2);
}
} else {
// TODO vertical
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: helpers.noop,
// Shared Methods
isHorizontal: function() {
return this.options.position == "top" || this.options.position == "bottom";
},
// Actualy draw the title block on the canvas
draw: function() {
if (this.options.display) {
var ctx = this.ctx;
var titleX, titleY;
// Horizontal
if (this.isHorizontal()) {
// Title
if (this.options.display) {
ctx.textAlign = "center";
ctx.textBaseline = 'middle';
ctx.fillStyle = this.options.fontColor; // render in correct colour
ctx.font = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width
titleY = this.top + ((this.bottom - this.top) / 2); // midpoint of the height
ctx.fillText(this.options.text, titleX, titleY);
}
} else {
// Title
if (this.options.display) {
titleX = this.options.position == 'left' ? this.left + (this.options.fontSize / 2) : this.right - (this.options.fontSize / 2);
titleY = this.top + ((this.bottom - this.top) / 2);
var rotation = this.options.position == 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
ctx.save();
ctx.translate(titleX, titleY);
ctx.rotate(rotation);
ctx.textAlign = "center";
ctx.fillStyle = this.options.fontColor; // render in correct colour
ctx.font = helpers.fontString(this.options.fontSize, this.options.fontStyle, this.options.fontFamily);
ctx.textBaseline = 'middle';
ctx.fillText(this.options.text, 0, 0);
ctx.restore();
}
}
}
}
});
}).call(this);
-584
Ver Arquivo
@@ -1,584 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.tooltips = {
enabled: true,
custom: null,
mode: 'single',
backgroundColor: "rgba(0,0,0,0.8)",
titleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
titleFontSize: 12,
titleFontStyle: "bold",
titleSpacing: 2,
titleMarginBottom: 6,
titleColor: "#fff",
titleAlign: "left",
bodyFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
bodyFontSize: 12,
bodyFontStyle: "normal",
bodySpacing: 2,
bodyColor: "#fff",
bodyAlign: "left",
footerFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
footerFontSize: 12,
footerFontStyle: "bold",
footerSpacing: 2,
footerMarginTop: 6,
footerColor: "#fff",
footerAlign: "left",
yPadding: 6,
xPadding: 6,
caretSize: 5,
cornerRadius: 6,
multiKeyBackground: '#fff',
callbacks: {
// Args are: (tooltipItems, data)
beforeTitle: helpers.noop,
title: function(tooltipItems, data) {
// Pick first xLabel for now
var title = '';
if (tooltipItems.length > 0) {
if (tooltipItems[0].xLabel) {
title = tooltipItems[0].xLabel;
} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {
title = data.labels[tooltipItems[0].index];
}
}
return title;
},
afterTitle: helpers.noop,
// Args are: (tooltipItems, data)
beforeBody: helpers.noop,
// Args are: (tooltipItem, data)
beforeLabel: helpers.noop,
label: function(tooltipItem, data) {
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
return datasetLabel + ': ' + tooltipItem.yLabel;
},
afterLabel: helpers.noop,
// Args are: (tooltipItems, data)
afterBody: helpers.noop,
// Args are: (tooltipItems, data)
beforeFooter: helpers.noop,
footer: helpers.noop,
afterFooter: helpers.noop,
},
};
// Helper to push or concat based on if the 2nd parameter is an array or not
function pushOrConcat(base, toPush) {
if (toPush) {
if (helpers.isArray(toPush)) {
base = base.concat(toPush);
} else {
base.push(toPush);
}
}
return base;
}
Chart.Tooltip = Chart.Element.extend({
initialize: function() {
var options = this._options;
helpers.extend(this, {
_model: {
// Positioning
xPadding: options.tooltips.xPadding,
yPadding: options.tooltips.yPadding,
// Body
bodyColor: options.tooltips.bodyColor,
_bodyFontFamily: options.tooltips.bodyFontFamily,
_bodyFontStyle: options.tooltips.bodyFontStyle,
_bodyAlign: options.tooltips.bodyAlign,
bodyFontSize: options.tooltips.bodyFontSize,
bodySpacing: options.tooltips.bodySpacing,
// Title
titleColor: options.tooltips.titleColor,
_titleFontFamily: options.tooltips.titleFontFamily,
_titleFontStyle: options.tooltips.titleFontStyle,
titleFontSize: options.tooltips.titleFontSize,
_titleAlign: options.tooltips.titleAlign,
titleSpacing: options.tooltips.titleSpacing,
titleMarginBottom: options.tooltips.titleMarginBottom,
// Footer
footerColor: options.tooltips.footerColor,
_footerFontFamily: options.tooltips.footerFontFamily,
_footerFontStyle: options.tooltips.footerFontStyle,
footerFontSize: options.tooltips.footerFontSize,
_footerAlign: options.tooltips.footerAlign,
footerSpacing: options.tooltips.footerSpacing,
footerMarginTop: options.tooltips.footerMarginTop,
// Appearance
caretSize: options.tooltips.caretSize,
cornerRadius: options.tooltips.cornerRadius,
backgroundColor: options.tooltips.backgroundColor,
opacity: 0,
legendColorBackground: options.tooltips.multiKeyBackground,
},
});
},
// Get the title
// Args are: (tooltipItem, data)
getTitle: function() {
var beforeTitle = this._options.tooltips.callbacks.beforeTitle.apply(this, arguments),
title = this._options.tooltips.callbacks.title.apply(this, arguments),
afterTitle = this._options.tooltips.callbacks.afterTitle.apply(this, arguments);
var lines = [];
lines = pushOrConcat(lines, beforeTitle);
lines = pushOrConcat(lines, title);
lines = pushOrConcat(lines, afterTitle);
return lines;
},
// Args are: (tooltipItem, data)
getBeforeBody: function() {
var lines = this._options.tooltips.callbacks.beforeBody.apply(this, arguments);
return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
},
// Args are: (tooltipItem, data)
getBody: function(tooltipItems, data) {
var lines = [];
helpers.each(tooltipItems, function(bodyItem) {
var beforeLabel = this._options.tooltips.callbacks.beforeLabel.call(this, bodyItem, data) || '';
var bodyLabel = this._options.tooltips.callbacks.label.call(this, bodyItem, data) || '';
var afterLabel = this._options.tooltips.callbacks.afterLabel.call(this, bodyItem, data) || '';
lines.push(beforeLabel + bodyLabel + afterLabel);
}, this);
return lines;
},
// Args are: (tooltipItem, data)
getAfterBody: function() {
var lines = this._options.tooltips.callbacks.afterBody.apply(this, arguments);
return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
},
// Get the footer and beforeFooter and afterFooter lines
// Args are: (tooltipItem, data)
getFooter: function() {
var beforeFooter = this._options.tooltips.callbacks.beforeFooter.apply(this, arguments);
var footer = this._options.tooltips.callbacks.footer.apply(this, arguments);
var afterFooter = this._options.tooltips.callbacks.afterFooter.apply(this, arguments);
var lines = [];
lines = pushOrConcat(lines, beforeFooter);
lines = pushOrConcat(lines, footer);
lines = pushOrConcat(lines, afterFooter);
return lines;
},
getAveragePosition: function(elements){
if(!elements.length){
return false;
}
var xPositions = [];
var yPositions = [];
helpers.each(elements, function(el){
if(el) {
var pos = el.tooltipPosition();
xPositions.push(pos.x);
yPositions.push(pos.y);
}
});
var x = 0, y = 0;
for (var i = 0; i < xPositions.length; i++) {
x += xPositions[i];
y += yPositions[i];
}
return {
x: Math.round(x / xPositions.length),
y: Math.round(y / xPositions.length)
};
},
update: function(changed) {
if (this._active.length){
this._model.opacity = 1;
var element = this._active[0],
labelColors = [],
tooltipPosition;
var tooltipItems = [];
if (this._options.tooltips.mode === 'single') {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
tooltipItems.push({
xLabel: element._xScale ? element._xScale.getLabelForIndex(element._index, element._datasetIndex) : '',
yLabel: yScale ? yScale.getLabelForIndex(element._index, element._datasetIndex) : '',
index: element._index,
datasetIndex: element._datasetIndex,
});
tooltipPosition = this.getAveragePosition(this._active);
} else {
helpers.each(this._data.datasets, function(dataset, datasetIndex) {
if (!helpers.isDatasetVisible(dataset)) {
return;
}
var currentElement = dataset.metaData[element._index];
if (currentElement) {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
tooltipItems.push({
xLabel: currentElement._xScale ? currentElement._xScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '',
yLabel: yScale ? yScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '',
index: element._index,
datasetIndex: datasetIndex,
});
}
});
helpers.each(this._active, function(active) {
if (active) {
labelColors.push({
borderColor: active._view.borderColor,
backgroundColor: active._view.backgroundColor
});
}
}, this);
tooltipPosition = this.getAveragePosition(this._active);
tooltipPosition.y = this._active[0]._yScale.getPixelForDecimal(0.5);
}
// Build the Text Lines
helpers.extend(this._model, {
title: this.getTitle(tooltipItems, this._data),
beforeBody: this.getBeforeBody(tooltipItems, this._data),
body: this.getBody(tooltipItems, this._data),
afterBody: this.getAfterBody(tooltipItems, this._data),
footer: this.getFooter(tooltipItems, this._data),
});
helpers.extend(this._model, {
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
labelColors: labelColors,
});
// We need to determine alignment of
var tooltipSize = this.getTooltipSize(this._model);
this.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
helpers.extend(this._model, this.getBackgroundPoint(this._model, tooltipSize));
}
else{
this._model.opacity = 0;
}
if (changed && this._options.tooltips.custom) {
this._options.tooltips.custom.call(this, this._model);
}
return this;
},
getTooltipSize: function getTooltipSize(vm) {
var ctx = this._chart.ctx;
var size = {
height: vm.yPadding * 2, // Tooltip Padding
width: 0
};
var combinedBodyLength = vm.body.length + vm.beforeBody.length + vm.afterBody.length;
size.height += vm.title.length * vm.titleFontSize; // Title Lines
size.height += (vm.title.length - 1) * vm.titleSpacing; // Title Line Spacing
size.height += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin
size.height += combinedBodyLength * vm.bodyFontSize; // Body Lines
size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
size.height += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin
size.height += vm.footer.length * (vm.footerFontSize); // Footer Lines
size.height += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing
// Width
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
helpers.each(vm.title, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
});
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
helpers.each(vm.beforeBody.concat(vm.afterBody), function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
}, this);
helpers.each(vm.body, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0));
}, this);
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(vm.footer, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
});
size.width += 2 * vm.xPadding;
return size;
},
determineAlignment: function determineAlignment(size) {
this._model.xAlign = this._model.yAlign = "center";
if (this._model.y < size.height) {
this._model.yAlign = 'top';
} else if (this._model.y > (this._chart.height - size.height)) {
this._model.yAlign = 'bottom';
}
var lf, rf;
var _this = this;
var midX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
if (this._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 >= (_this._chart.width - (size.width / 2)); };
}
if (lf(this._model.x)) {
this._model.xAlign = 'left';
} else if (rf(this._model.x)) {
this._model.xAlign = 'right';
}
},
getBackgroundPoint: function getBackgroundPoint(vm, size) {
// Background Position
var pt = {
x: vm.x,
y: vm.y
};
if (vm.xAlign === 'right') {
pt.x -= size.width;
} else if (vm.xAlign === 'center') {
pt.x -= (size.width / 2);
}
if (vm.yAlign === 'top') {
pt.y += vm.caretPadding + vm.caretSize;
} else if (vm.yAlign === 'bottom') {
pt.y -= size.height + vm.caretPadding + vm.caretSize;
} else {
pt.y -= (size.height / 2);
}
if (vm.yAlign == 'center') {
if (vm.xAlign === 'left') {
pt.x += vm.caretPadding + vm.caretSize;
} else if (vm.xAlign === 'right') {
pt.x -= vm.caretPadding + vm.caretSize;
}
} else {
if (vm.xAlign === 'left') {
pt.x -= vm.cornerRadius + vm.caretPadding;
} else if (vm.xAlign === 'right') {
pt.x += vm.cornerRadius + vm.caretPadding;
}
}
return pt;
},
drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {
var vm = this._view;
var ctx = this._chart.ctx;
var x1, x2, x3;
var y1, y2, y3;
if (vm.yAlign === 'center') {
// Left or right side
if (vm.xAlign === 'left') {
x1 = tooltipPoint.x;
x2 = x1 - vm.caretSize;
x3 = x1;
} else {
x1 = tooltipPoint.x + size.width;
x2 = x1 + vm.caretSize;
x3 = x1;
}
y2 = tooltipPoint.y + (size.height / 2);
y1 = y2 - vm.caretSize;
y3 = y2 + vm.caretSize;
} else {
if (vm.xAlign === 'left') {
x1 = tooltipPoint.x + vm.cornerRadius;
x2 = x1 + vm.caretSize;
x3 = x2 + vm.caretSize;
} else if (vm.xAlign === 'right') {
x1 = tooltipPoint.x + size.width - vm.cornerRadius;
x2 = x1 - vm.caretSize;
x3 = x2 - vm.caretSize;
} else {
x2 = tooltipPoint.x + (size.width / 2);
x1 = x2 - vm.caretSize;
x3 = x2 + vm.caretSize;
}
if (vm.yAlign === 'top') {
y1 = tooltipPoint.y;
y2 = y1 - vm.caretSize;
y3 = y1;
} else {
y1 = tooltipPoint.y + size.height;
y2 = y1 + vm.caretSize;
y3 = y1;
}
}
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(opacity).rgbString();
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.closePath();
ctx.fill();
},
drawTitle: function drawTitle(pt, vm, ctx, opacity) {
if (vm.title.length) {
ctx.textAlign = vm._titleAlign;
ctx.textBaseline = "top";
ctx.fillStyle = helpers.color(vm.titleColor).alpha(opacity).rgbString();
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
helpers.each(vm.title, function(title, i) {
ctx.fillText(title, pt.x, pt.y);
pt.y += vm.titleFontSize + vm.titleSpacing; // Line Height and spacing
if (i + 1 === vm.title.length) {
pt.y += vm.titleMarginBottom - vm.titleSpacing; // If Last, add margin, remove spacing
}
}, this);
}
},
drawBody: function drawBody(pt, vm, ctx, opacity) {
ctx.textAlign = vm._bodyAlign;
ctx.textBaseline = "top";
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbString();
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
// Before Body
helpers.each(vm.beforeBody, function(beforeBody) {
ctx.fillText(beforeBody, pt.x, pt.y);
pt.y += vm.bodyFontSize + vm.bodySpacing;
});
helpers.each(vm.body, function(body, i) {
// Draw Legend-like boxes if needed
if (this._options.tooltips.mode !== 'single') {
// Fill a white rect so that colours merge nicely if the opacity is < 1
ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
ctx.fillRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
// Border
ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
ctx.strokeRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
// Inner square
ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
ctx.fillRect(pt.x + 1, pt.y + 1, vm.bodyFontSize - 2, vm.bodyFontSize - 2);
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbaString(); // Return fill style for text
}
// Body Line
ctx.fillText(body, pt.x + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0), pt.y);
pt.y += vm.bodyFontSize + vm.bodySpacing;
}, this);
// After Body
helpers.each(vm.afterBody, function(afterBody) {
ctx.fillText(afterBody, pt.x, pt.y);
pt.y += vm.bodyFontSize;
});
pt.y -= vm.bodySpacing; // Remove last body spacing
},
drawFooter: function drawFooter(pt, vm, ctx, opacity) {
if (vm.footer.length) {
pt.y += vm.footerMarginTop;
ctx.textAlign = vm._footerAlign;
ctx.textBaseline = "top";
ctx.fillStyle = helpers.color(vm.footerColor).alpha(opacity).rgbString();
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(vm.footer, function(footer) {
ctx.fillText(footer, pt.x, pt.y);
pt.y += vm.footerFontSize + vm.footerSpacing;
}, this);
}
},
draw: function draw() {
var ctx = this._chart.ctx;
var vm = this._view;
if (vm.opacity === 0) {
return;
}
var caretPadding = vm.caretPadding;
var tooltipSize = this.getTooltipSize(vm);
var pt = {
x: vm.x,
y: vm.y
};
// IE11/Edge does not like very small opacities, so snap to 0
var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
if (this._options.tooltips.enabled) {
// Draw Background
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(opacity).rgbString();
helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
ctx.fill();
// Draw Caret
this.drawCaret(pt, tooltipSize, opacity, caretPadding);
// Draw Title, Body, and Footer
pt.x += vm.xPadding;
pt.y += vm.yPadding;
// Titles
this.drawTitle(pt, vm, ctx, opacity);
// Body
this.drawBody(pt, vm, ctx, opacity);
// Footer
this.drawFooter(pt, vm, ctx, opacity);
}
}
});
}).call(this);
-96
Ver Arquivo
@@ -1,96 +0,0 @@
/*!
* Chart.js
* http://chartjs.org/
* Version: {{ version }}
*
* Copyright 2015 Nick Downie
* Released under the MIT license
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.elements.arc = {
backgroundColor: Chart.defaults.global.defaultColor,
borderColor: "#fff",
borderWidth: 2
};
Chart.elements.Arc = Chart.Element.extend({
inLabelRange: function(mouseX) {
var vm = this._view;
if (vm) {
return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));
} else {
return false;
}
},
inRange: function(chartX, chartY) {
var vm = this._view;
if (vm) {
var pointRelativePosition = helpers.getAngleFromPoint(vm, {
x: chartX,
y: chartY
});
// Put into the range of (-PI/2, 3PI/2]
var startAngle = vm.startAngle < (-0.5 * Math.PI) ? vm.startAngle + (2.0 * Math.PI) : vm.startAngle > (1.5 * Math.PI) ? vm.startAngle - (2.0 * Math.PI) : vm.startAngle;
var endAngle = vm.endAngle < (-0.5 * Math.PI) ? vm.endAngle + (2.0 * Math.PI) : vm.endAngle > (1.5 * Math.PI) ? vm.endAngle - (2.0 * Math.PI) : vm.endAngle;
//Check if within the range of the open/close angle
var betweenAngles = (pointRelativePosition.angle >= startAngle && pointRelativePosition.angle <= endAngle),
withinRadius = (pointRelativePosition.distance >= vm.innerRadius && pointRelativePosition.distance <= vm.outerRadius);
return (betweenAngles && withinRadius);
} else {
return false;
}
},
tooltipPosition: function() {
var vm = this._view;
var centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2),
rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;
return {
x: vm.x + (Math.cos(centreAngle) * rangeFromCentre),
y: vm.y + (Math.sin(centreAngle) * rangeFromCentre)
};
},
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
ctx.beginPath();
ctx.arc(vm.x, vm.y, vm.outerRadius, vm.startAngle, vm.endAngle);
ctx.arc(vm.x, vm.y, vm.innerRadius, vm.endAngle, vm.startAngle, true);
ctx.closePath();
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = vm.borderWidth;
ctx.fillStyle = vm.backgroundColor;
ctx.fill();
ctx.lineJoin = 'bevel';
if (vm.borderWidth) {
ctx.stroke();
}
}
});
}).call(this);
-175
Ver Arquivo
@@ -1,175 +0,0 @@
/*!
* Chart.js
* http://chartjs.org/
* Version: {{ version }}
*
* Copyright 2015 Nick Downie
* Released under the MIT license
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.elements.line = {
tension: 0.4,
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 3,
borderColor: Chart.defaults.global.defaultColor,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
fill: true, // do we fill in the area between the line and its base axis
};
Chart.elements.Line = Chart.Element.extend({
lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {
var ctx = this._chart.ctx;
if (point._view.skip) {
skipHandler.call(this, previousPoint, point, nextPoint);
} else if (previousPoint._view.skip) {
previousSkipHandler.call(this, previousPoint, point, nextPoint);
} else if (point._view.tension === 0) {
ctx.lineTo(point._view.x, point._view.y);
} else {
// Line between points
ctx.bezierCurveTo(
previousPoint._view.controlPointNextX,
previousPoint._view.controlPointNextY,
point._view.controlPointPreviousX,
point._view.controlPointPreviousY,
point._view.x,
point._view.y
);
}
},
draw: function() {
var _this = this;
var vm = this._view;
var ctx = this._chart.ctx;
var first = this._children[0];
var last = this._children[this._children.length - 1];
function loopBackToStart(drawLineToCenter) {
if (!first._view.skip && !last._view.skip) {
// Draw a bezier line from last to first
ctx.bezierCurveTo(
last._view.controlPointNextX,
last._view.controlPointNextY,
first._view.controlPointPreviousX,
first._view.controlPointPreviousY,
first._view.x,
first._view.y
);
} else if (drawLineToCenter) {
// Go to center
ctx.lineTo(_this._view.scaleZero.x, _this._view.scaleZero.y);
}
}
ctx.save();
// If we had points and want to fill this line, do so.
if (this._children.length > 0 && vm.fill) {
// Draw the background first (so the border is always on top)
ctx.beginPath();
helpers.each(this._children, function(point, index) {
var previous = helpers.previousItem(this._children, index);
var next = helpers.nextItem(this._children, index);
// First point moves to it's starting position no matter what
if (index === 0) {
if (this._loop) {
ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);
} else {
ctx.moveTo(point._view.x, vm.scaleZero);
}
if (point._view.skip) {
if (!this._loop) {
ctx.moveTo(next._view.x, this._view.scaleZero);
}
} else {
ctx.lineTo(point._view.x, point._view.y);
}
} else {
this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
if (this._loop) {
// Go to center
ctx.lineTo(this._view.scaleZero.x, this._view.scaleZero.y);
} else {
ctx.lineTo(previousPoint._view.x, this._view.scaleZero);
ctx.moveTo(nextPoint._view.x, this._view.scaleZero);
}
}, function(previousPoint, point) {
// If we skipped the last point, draw a line to ourselves so that the fill is nice
ctx.lineTo(point._view.x, point._view.y);
});
}
}, this);
// For radial scales, loop back around to the first point
if (this._loop) {
loopBackToStart(true);
} else {
//Round off the line by going to the base of the chart, back to the start, then fill.
ctx.lineTo(this._children[this._children.length - 1]._view.x, vm.scaleZero);
ctx.lineTo(this._children[0]._view.x, vm.scaleZero);
}
ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor;
ctx.closePath();
ctx.fill();
}
// Now draw the line between all the points with any borders
ctx.lineCap = vm.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle;
// IE 9 and 10 do not support line dash
if (ctx.setLineDash) {
ctx.setLineDash(vm.borderDash || Chart.defaults.global.elements.line.borderDash);
}
ctx.lineDashOffset = vm.borderDashOffset || Chart.defaults.global.elements.line.borderDashOffset;
ctx.lineJoin = vm.borderJoinStyle || Chart.defaults.global.elements.line.borderJoinStyle;
ctx.lineWidth = vm.borderWidth || Chart.defaults.global.elements.line.borderWidth;
ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor;
ctx.beginPath();
helpers.each(this._children, function(point, index) {
var previous = helpers.previousItem(this._children, index);
var next = helpers.nextItem(this._children, index);
if (index === 0) {
ctx.moveTo(point._view.x, point._view.y);
} else {
this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
ctx.moveTo(nextPoint._view.x, nextPoint._view.y);
}, function(previousPoint, point) {
// If we skipped the last point, move up to our point preventing a line from being drawn
ctx.moveTo(point._view.x, point._view.y);
});
}
}, this);
if (this._loop && this._children.length > 0) {
loopBackToStart();
}
ctx.stroke();
ctx.restore();
},
});
}).call(this);
-89
Ver Arquivo
@@ -1,89 +0,0 @@
/*!
* Chart.js
* http://chartjs.org/
* Version: {{ version }}
*
* Copyright 2015 Nick Downie
* Released under the MIT license
* https://github.com/nnnick/Chart.js/blob/master/LICENSE.md
*/
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.elements.point = {
radius: 3,
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
// Hover
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
};
Chart.elements.Point = Chart.Element.extend({
inRange: function(mouseX, mouseY) {
var vm = this._view;
if (vm) {
var hoverRange = vm.hitRadius + vm.radius;
return ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(hoverRange, 2));
} else {
return false;
}
},
inLabelRange: function(mouseX) {
var vm = this._view;
if (vm) {
return (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hitRadius, 2));
} else {
return false;
}
},
tooltipPosition: function() {
var vm = this._view;
return {
x: vm.x,
y: vm.y,
padding: vm.radius + vm.borderWidth
};
},
draw: function() {
var vm = this._view;
var ctx = this._chart.ctx;
if (vm.skip) {
return;
}
if (vm.radius > 0 || vm.borderWidth > 0) {
ctx.beginPath();
ctx.arc(vm.x, vm.y, vm.radius || Chart.defaults.global.elements.point.radius, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor;
ctx.lineWidth = vm.borderWidth || Chart.defaults.global.elements.point.borderWidth;
ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor;
ctx.fill();
ctx.stroke();
}
}
});
}).call(this);
-90
Ver Arquivo
@@ -1,90 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.elements.rectangle = {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 0,
borderColor: Chart.defaults.global.defaultColor,
};
Chart.elements.Rectangle = Chart.Element.extend({
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
var halfWidth = vm.width / 2,
leftX = vm.x - halfWidth,
rightX = vm.x + halfWidth,
top = vm.base - (vm.base - vm.y),
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) {
leftX += halfStroke;
rightX -= halfStroke;
top += halfStroke;
}
ctx.beginPath();
ctx.fillStyle = vm.backgroundColor;
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = vm.borderWidth;
// It'd be nice to keep this class totally generic to any rectangle
// and simply specify which border to miss out.
ctx.moveTo(leftX, vm.base);
ctx.lineTo(leftX, top);
ctx.lineTo(rightX, top);
ctx.lineTo(rightX, vm.base);
ctx.fill();
if (vm.borderWidth) {
ctx.stroke();
}
},
height: function() {
var vm = this._view;
return vm.base - vm.y;
},
inRange: function(mouseX, mouseY) {
var vm = this._view;
var inRange = false;
if (vm) {
if (vm.y < vm.base) {
inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base);
} else {
inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y);
}
}
return inRange;
},
inLabelRange: function(mouseX) {
var vm = this._view;
if (vm) {
return (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2);
} else {
return false;
}
},
tooltipPosition: function() {
var vm = this._view;
return {
x: vm.x,
y: vm.y
};
},
});
}).call(this);
-50
Ver Arquivo
@@ -1,50 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
// Default config for a category scale
var defaultConfig = {
position: "bottom",
};
var DatasetScale = Chart.Scale.extend({
buildTicks: function(index) {
this.ticks = this.chart.data.labels;
},
getLabelForIndex: function(index, datasetIndex) {
return this.ticks[index];
},
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueWidth = innerWidth / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var widthOffset = (valueWidth * index) + this.paddingLeft;
if (this.options.gridLines.offsetGridLines && includeOffset) {
widthOffset += (valueWidth / 2);
}
return this.left + Math.round(widthOffset);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
var valueHeight = innerHeight / Math.max((this.chart.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var heightOffset = (valueHeight * index) + this.paddingTop;
if (this.options.gridLines.offsetGridLines && includeOffset) {
heightOffset += (valueHeight / 2);
}
return this.top + Math.round(heightOffset);
}
},
});
Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
}).call(this);
-243
Ver Arquivo
@@ -1,243 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
position: "left",
ticks: {
callback: function(tickValue, index, ticks) {
var delta = 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;
}
}
};
var LinearScale = Chart.Scale.extend({
determineDataLimits: function() {
// First Calculate the range
this.min = null;
this.max = null;
if (this.options.stacked) {
var valuesPerType = {};
helpers.each(this.chart.data.datasets, function(dataset) {
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = {
positiveValues: [],
negativeValues: [],
};
}
// Store these per type
var positiveValues = valuesPerType[dataset.type].positiveValues;
var negativeValues = valuesPerType[dataset.type].negativeValues;
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
return;
}
positiveValues[index] = positiveValues[index] || 0;
negativeValues[index] = negativeValues[index] || 0;
if (this.options.relativePoints) {
positiveValues[index] = 100;
} else {
if (value < 0) {
negativeValues[index] += value;
} else {
positiveValues[index] += value;
}
}
}, this);
}
}, this);
helpers.each(valuesPerType, function(valuesForType) {
var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
var minVal = helpers.min(values);
var maxVal = helpers.max(values);
this.min = this.min === null ? minVal : Math.min(this.min, minVal);
this.max = this.max === null ? maxVal : Math.max(this.max, maxVal);
}, this);
} else {
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
return;
}
if (this.min === null) {
this.min = value;
} else if (value < this.min) {
this.min = value;
}
if (this.max === null) {
this.max = value;
} else if (value > this.max) {
this.max = value;
}
}, this);
}
}, this);
}
// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
// do nothing since that would make the chart weird. If the user really wants a weird chart
// axis, they can manually override it
if (this.options.ticks.beginAtZero) {
var minSign = helpers.sign(this.min);
var maxSign = helpers.sign(this.max);
if (minSign < 0 && maxSign < 0) {
// move the top up to 0
this.max = 0;
} else if (minSign > 0 && maxSign > 0) {
// move the botttom down to 0
this.min = 0;
}
}
if (this.options.ticks.min !== undefined) {
this.min = this.options.ticks.min;
} else if (this.options.ticks.suggestedMin !== undefined) {
this.min = Math.min(this.min, this.options.ticks.suggestedMin);
}
if (this.options.ticks.max !== undefined) {
this.max = this.options.ticks.max;
} else if (this.options.ticks.suggestedMax !== undefined) {
this.max = Math.max(this.max, this.options.ticks.suggestedMax);
}
if (this.min === this.max) {
this.min--;
this.max++;
}
},
buildTicks: function() {
// Then calulate the ticks
this.ticks = [];
// 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 maxTicks;
if (this.isHorizontal()) {
maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11,
Math.ceil(this.width / 50));
} else {
// The factor of 2 used to scale the font size has been experimentally determined.
maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11,
Math.ceil(this.height / (2 * this.options.ticks.fontSize)));
}
// Make sure we always have at least 2 ticks
maxTicks = Math.max(2, maxTicks);
// 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 niceRange = helpers.niceNum(this.max - this.min, false);
var spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
var niceMin = Math.floor(this.min / spacing) * spacing;
var niceMax = Math.ceil(this.max / spacing) * spacing;
var numSpaces = Math.ceil((niceMax - niceMin) / spacing);
// Put the values into the ticks array
this.ticks.push(this.options.ticks.min !== undefined ? this.options.ticks.min : niceMin);
for (var j = 1; j < numSpaces; ++j) {
this.ticks.push(niceMin + (j * spacing));
}
this.ticks.push(this.options.ticks.max !== undefined ? this.options.ticks.max : niceMax);
if (this.options.position == "left" || this.options.position == "right") {
// We are in a vertical orientation. The top value is the highest. So reverse the array
this.ticks.reverse();
}
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
this.max = helpers.max(this.ticks);
this.min = helpers.min(this.ticks);
this.ticksAsNumbers = this.ticks.slice();
if (this.options.ticks.reverse) {
this.ticks.reverse();
this.start = this.max;
this.end = this.min;
} else {
this.start = this.min;
this.end = this.max;
}
this.zeroLineIndex = this.ticks.indexOf(0);
},
getLabelForIndex: function(index, datasetIndex) {
return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
},
// Utils
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
// This must be called after fit has been run so that
// this.left, this.top, this.right, and this.bottom have been defined
var rightValue = +this.getRightValue(value);
var pixel;
var range = this.end - this.start;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
pixel = this.left + (innerWidth / range * (rightValue - this.start));
return Math.round(pixel + this.paddingLeft);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
pixel = (this.bottom - this.paddingBottom) - (innerHeight / range * (rightValue - this.start));
return Math.round(pixel);
}
},
getPixelForTick: function(index, includeOffset) {
return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset);
},
});
Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);
}).call(this);
-192
Ver Arquivo
@@ -1,192 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
position: "left",
// label settings
ticks: {
callback: function(value, index, arr) {
var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));
if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === arr.length - 1) {
return value.toExponential();
} else {
return '';
}
}
}
};
var LogarithmicScale = Chart.Scale.extend({
determineDataLimits: function() {
// Calculate Range
this.min = null;
this.max = null;
if (this.options.stacked) {
var valuesPerType = {};
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
if (valuesPerType[dataset.type] === undefined) {
valuesPerType[dataset.type] = [];
}
helpers.each(dataset.data, function(rawValue, index) {
var values = valuesPerType[dataset.type];
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
return;
}
values[index] = values[index] || 0;
if (this.options.relativePoints) {
values[index] = 100;
} else {
// Don't need to split positive and negative since the log scale can't handle a 0 crossing
values[index] += value;
}
}, this);
}
}, this);
helpers.each(valuesPerType, function(valuesForType) {
var minVal = helpers.min(valuesForType);
var maxVal = helpers.max(valuesForType);
this.min = this.min === null ? minVal : Math.min(this.min, minVal);
this.max = this.max === null ? maxVal : Math.max(this.max, maxVal);
}, this);
} else {
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
return;
}
if (this.min === null) {
this.min = value;
} else if (value < this.min) {
this.min = value;
}
if (this.max === null) {
this.max = value;
} else if (value > this.max) {
this.max = value;
}
}, this);
}
}, this);
}
this.min = this.options.ticks.min !== undefined ? this.options.ticks.min : this.min;
this.max = this.options.ticks.max !== undefined ? this.options.ticks.max : this.max;
if (this.min === this.max) {
if (this.min !== 0 && this.min !== null) {
this.min = Math.pow(10, Math.floor(helpers.log10(this.min)) - 1);
this.max = Math.pow(10, Math.floor(helpers.log10(this.max)) + 1);
} else {
this.min = 1;
this.max = 10;
}
}
},
buildTicks: function() {
// Reset the ticks array. Later on, we will draw a grid line at these positions
// The array simply contains the numerical value of the spots where ticks will be
this.tickValues = [];
// 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 = this.options.ticks.min !== undefined ? this.options.ticks.min : Math.pow(10, Math.floor(helpers.log10(this.min)));
while (tickVal < this.max) {
this.tickValues.push(tickVal);
var exp = Math.floor(helpers.log10(tickVal));
var significand = Math.floor(tickVal / Math.pow(10, exp)) + 1;
if (significand === 10) {
significand = 1;
++exp;
}
tickVal = significand * Math.pow(10, exp);
}
var lastTick = this.options.ticks.max !== undefined ? this.options.ticks.max : tickVal;
this.tickValues.push(lastTick);
if (this.options.position == "left" || this.options.position == "right") {
// We are in a vertical orientation. The top value is the highest. So reverse the array
this.tickValues.reverse();
}
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
this.max = helpers.max(this.tickValues);
this.min = helpers.min(this.tickValues);
if (this.options.ticks.reverse) {
this.tickValues.reverse();
this.start = this.max;
this.end = this.min;
} else {
this.start = this.min;
this.end = this.max;
}
this.ticks = this.tickValues.slice();
},
// Get the correct tooltip label
getLabelForIndex: function(index, datasetIndex) {
return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
},
getPixelForTick: function(index, includeOffset) {
return this.getPixelForValue(this.tickValues[index], null, null, includeOffset);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var pixel;
var newVal = +this.getRightValue(value);
var range = helpers.log10(this.end) - helpers.log10(this.start);
if (this.isHorizontal()) {
if (newVal === 0) {
pixel = this.left + this.paddingLeft;
} else {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
pixel = this.left + (innerWidth / range * (helpers.log10(newVal) - helpers.log10(this.start)));
return pixel + this.paddingLeft;
}
} else {
// Bottom - top since pixels increase downard on a screen
if (newVal === 0) {
pixel = this.top + this.paddingTop;
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
return (this.bottom - this.paddingBottom) - (innerHeight / range * (helpers.log10(newVal) - helpers.log10(this.start)));
}
}
},
});
Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
}).call(this);
-409
Ver Arquivo
@@ -1,409 +0,0 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
display: true,
//Boolean - Whether to animate scaling the chart from the centre
animate: true,
lineArc: false,
position: "chartArea",
angleLines: {
display: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1
},
// label settings
ticks: {
//Boolean - Show a backdrop to the scale label
showLabelBackdrop: true,
//String - The colour of the label backdrop
backdropColor: "rgba(255,255,255,0.75)",
//Number - The backdrop padding above & below the label in pixels
backdropPaddingY: 2,
//Number - The backdrop padding to the side of the label in pixels
backdropPaddingX: 2,
},
pointLabels: {
//String - Point label font declaration
fontFamily: "'Arial'",
//String - Point label font weight
fontStyle: "normal",
//Number - Point label font size in pixels
fontSize: 10,
//String - Point label font colour
fontColor: "#666",
},
};
var LinearRadialScale = Chart.Scale.extend({
getValueCount: function() {
return this.chart.data.labels.length;
},
setDimensions: function() {
// Set the unconstrained dimension before label rotation
this.width = this.maxWidth;
this.height = this.maxHeight;
this.xCenter = Math.round(this.width / 2);
this.yCenter = Math.round(this.height / 2);
var minSize = helpers.min([this.height, this.width]);
this.drawingArea = (this.options.display) ? (minSize / 2) - (this.options.ticks.fontSize / 2 + this.options.ticks.backdropPaddingY) : (minSize / 2);
},
determineDataLimits: function() {
this.min = null;
this.max = null;
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset)) {
helpers.each(dataset.data, function(rawValue, index) {
var value = +this.getRightValue(rawValue);
if (isNaN(value)) {
return;
}
if (this.min === null) {
this.min = value;
} else if (value < this.min) {
this.min = value;
}
if (this.max === null) {
this.max = value;
} else if (value > this.max) {
this.max = value;
}
}, this);
}
}, this);
if (this.min === this.max) {
this.min--;
this.max++;
}
// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,
// do nothing since that would make the chart weird. If the user really wants a weird chart
// axis, they can manually override it
if (this.options.ticks.beginAtZero) {
var minSign = helpers.sign(this.min);
var maxSign = helpers.sign(this.max);
if (minSign < 0 && maxSign < 0) {
// move the top up to 0
this.max = 0;
} else if (minSign > 0 && maxSign > 0) {
// move the botttom down to 0
this.min = 0;
}
}
},
buildTicks: function() {
this.ticks = [];
// 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 maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11,
Math.ceil(this.drawingArea / (1.5 * this.options.ticks.fontSize)));
maxTicks = Math.max(2, maxTicks); // Make sure we always have at least 2 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 niceRange = helpers.niceNum(this.max - this.min, false);
var spacing = helpers.niceNum(niceRange / (maxTicks - 1), true);
var niceMin = Math.floor(this.min / spacing) * spacing;
var niceMax = Math.ceil(this.max / spacing) * spacing;
// Put the values into the ticks array
for (var j = niceMin; j <= niceMax; j += spacing) {
this.ticks.push(j);
}
// At this point, we need to update our max and min given the tick values since we have expanded the
// range of the scale
this.max = helpers.max(this.ticks);
this.min = helpers.min(this.ticks);
if (this.options.ticks.reverse) {
this.ticks.reverse();
this.start = this.max;
this.end = this.min;
} else {
this.start = this.min;
this.end = this.max;
}
this.zeroLineIndex = this.ticks.indexOf(0);
},
getLabelForIndex: function(index, datasetIndex) {
return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
},
getCircumference: function() {
return ((Math.PI * 2) / this.getValueCount());
},
fit: function() {
/*
* Right, this is really confusing and there is a lot of maths going on here
* The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9
*
* Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif
*
* Solution:
*
* We assume the radius of the polygon is half the size of the canvas at first
* at each index we check if the text overlaps.
*
* Where it does, we store that angle and that index.
*
* After finding the largest index and angle we calculate how much we need to remove
* from the shape radius to move the point inwards by that x.
*
* We average the left and right distances to get the maximum shape radius that can fit in the box
* along with labels.
*
* Once we have that, we can find the centre point for the chart, by taking the x text protrusion
* on each side, removing that from the size, halving it and adding the left x protrusion width.
*
* This will mean we have a shape fitted to the canvas, as large as it can be with the labels
* and position it in the most space efficient manner
*
* https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif
*/
// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.
// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points
var largestPossibleRadius = helpers.min([(this.height / 2 - this.options.pointLabels.fontSize - 5), this.width / 2]),
pointPosition,
i,
textWidth,
halfTextWidth,
furthestRight = this.width,
furthestRightIndex,
furthestRightAngle,
furthestLeft = 0,
furthestLeftIndex,
furthestLeftAngle,
xProtrusionLeft,
xProtrusionRight,
radiusReductionRight,
radiusReductionLeft,
maxWidthRadius;
this.ctx.font = helpers.fontString(this.options.pointLabels.fontSize, this.options.pointLabels.fontStyle, this.options.pointLabels.fontFamily);
for (i = 0; i < this.getValueCount(); i++) {
// 5px to space the text slightly out - similar to what we do in the draw function.
pointPosition = this.getPointPosition(i, largestPossibleRadius);
textWidth = this.ctx.measureText(this.options.ticks.callback(this.chart.data.labels[i])).width + 5;
if (i === 0 || i === this.getValueCount() / 2) {
// If we're at index zero, or exactly the middle, we're at exactly the top/bottom
// of the radar chart, so text will be aligned centrally, so we'll half it and compare
// w/left and right text sizes
halfTextWidth = textWidth / 2;
if (pointPosition.x + halfTextWidth > furthestRight) {
furthestRight = pointPosition.x + halfTextWidth;
furthestRightIndex = i;
}
if (pointPosition.x - halfTextWidth < furthestLeft) {
furthestLeft = pointPosition.x - halfTextWidth;
furthestLeftIndex = i;
}
} else if (i < this.getValueCount() / 2) {
// Less than half the values means we'll left align the text
if (pointPosition.x + textWidth > furthestRight) {
furthestRight = pointPosition.x + textWidth;
furthestRightIndex = i;
}
} else if (i > this.getValueCount() / 2) {
// More than half the values means we'll right align the text
if (pointPosition.x - textWidth < furthestLeft) {
furthestLeft = pointPosition.x - textWidth;
furthestLeftIndex = i;
}
}
}
xProtrusionLeft = furthestLeft;
xProtrusionRight = Math.ceil(furthestRight - this.width);
furthestRightAngle = this.getIndexAngle(furthestRightIndex);
furthestLeftAngle = this.getIndexAngle(furthestLeftIndex);
radiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI / 2);
radiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI / 2);
// Ensure we actually need to reduce the size of the chart
radiusReductionRight = (helpers.isNumber(radiusReductionRight)) ? radiusReductionRight : 0;
radiusReductionLeft = (helpers.isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;
this.drawingArea = Math.round(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2);
this.setCenterPoint(radiusReductionLeft, radiusReductionRight);
},
setCenterPoint: function(leftMovement, rightMovement) {
var maxRight = this.width - rightMovement - this.drawingArea,
maxLeft = leftMovement + this.drawingArea;
this.xCenter = Math.round(((maxLeft + maxRight) / 2) + this.left);
// Always vertically in the centre as the text height doesn't change
this.yCenter = Math.round((this.height / 2) + this.top);
},
getIndexAngle: function(index) {
var angleMultiplier = (Math.PI * 2) / this.getValueCount();
// Start from the top instead of right, so remove a quarter of the circle
return index * angleMultiplier - (Math.PI / 2);
},
getDistanceFromCenterForValue: function(value) {
if (value === null) {
return 0; // null always in center
}
// Take into account half font size + the yPadding of the top value
var scalingFactor = this.drawingArea / (this.max - this.min);
if (this.options.reverse) {
return (this.max - value) * scalingFactor;
} else {
return (value - this.min) * scalingFactor;
}
},
getPointPosition: function(index, distanceFromCenter) {
var thisAngle = this.getIndexAngle(index);
return {
x: Math.round(Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,
y: Math.round(Math.sin(thisAngle) * distanceFromCenter) + this.yCenter
};
},
getPointPositionForValue: function(index, value) {
return this.getPointPosition(index, this.getDistanceFromCenterForValue(value));
},
draw: function() {
if (this.options.display) {
var ctx = this.ctx;
helpers.each(this.ticks, function(label, index) {
// Don't draw a centre value (if it is minimum)
if (index > 0 || this.options.reverse) {
var yCenterOffset = this.getDistanceFromCenterForValue(this.ticks[index]);
var yHeight = this.yCenter - yCenterOffset;
// Draw circular lines around the scale
if (this.options.gridLines.display) {
ctx.strokeStyle = this.options.gridLines.color;
ctx.lineWidth = this.options.gridLines.lineWidth;
if (this.options.lineArc) {
// Draw circular arcs between the points
ctx.beginPath();
ctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI * 2);
ctx.closePath();
ctx.stroke();
} else {
// Draw straight lines connecting each index
ctx.beginPath();
for (var i = 0; i < this.getValueCount(); i++) {
var pointPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.ticks[index]));
if (i === 0) {
ctx.moveTo(pointPosition.x, pointPosition.y);
} else {
ctx.lineTo(pointPosition.x, pointPosition.y);
}
}
ctx.closePath();
ctx.stroke();
}
}
if (this.options.ticks.display) {
ctx.font = helpers.fontString(this.options.ticks.fontSize, this.options.ticks.fontStyle, this.options.ticks.fontFamily);
if (this.options.ticks.showLabelBackdrop) {
var labelWidth = ctx.measureText(label).width;
ctx.fillStyle = this.options.ticks.backdropColor;
ctx.fillRect(
this.xCenter - labelWidth / 2 - this.options.ticks.backdropPaddingX,
yHeight - this.options.ticks.fontSize / 2 - this.options.ticks.backdropPaddingY,
labelWidth + this.options.ticks.backdropPaddingX * 2,
this.options.ticks.fontSize + this.options.ticks.backdropPaddingY * 2
);
}
ctx.textAlign = 'center';
ctx.textBaseline = "middle";
ctx.fillStyle = this.options.ticks.fontColor;
ctx.fillText(label, this.xCenter, yHeight);
}
}
}, this);
if (!this.options.lineArc) {
ctx.lineWidth = this.options.angleLines.lineWidth;
ctx.strokeStyle = this.options.angleLines.color;
for (var i = this.getValueCount() - 1; i >= 0; i--) {
if (this.options.angleLines.display) {
var outerPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max));
ctx.beginPath();
ctx.moveTo(this.xCenter, this.yCenter);
ctx.lineTo(outerPosition.x, outerPosition.y);
ctx.stroke();
ctx.closePath();
}
// Extra 3px out for some label spacing
var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5);
ctx.font = helpers.fontString(this.options.pointLabels.fontSize, this.options.pointLabels.fontStyle, this.options.pointLabels.fontFamily);
ctx.fillStyle = this.options.pointLabels.fontColor;
var labelsCount = this.chart.data.labels.length,
halfLabelsCount = this.chart.data.labels.length / 2,
quarterLabelsCount = halfLabelsCount / 2,
upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
if (i === 0) {
ctx.textAlign = 'center';
} else if (i === halfLabelsCount) {
ctx.textAlign = 'center';
} else if (i < halfLabelsCount) {
ctx.textAlign = 'left';
} else {
ctx.textAlign = 'right';
}
// Set the correct text baseline based on outer positioning
if (exactQuarter) {
ctx.textBaseline = 'middle';
} else if (upperHalf) {
ctx.textBaseline = 'bottom';
} else {
ctx.textBaseline = 'top';
}
ctx.fillText(this.chart.data.labels[i], pointLabelPosition.x, pointLabelPosition.y);
}
}
}
}
});
Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);
}).call(this);
-281
Ver Arquivo
@@ -1,281 +0,0 @@
(function(moment) {
"use strict";
if (!moment) {
console.warn('Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at http://momentjs.com/');
return;
}
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var time = {
units: [
{
name: 'millisecond',
steps: [1, 2, 5, 10, 20, 50, 100, 250, 500]
}, {
name: 'second',
steps: [1, 2, 5, 10, 30]
}, {
name: 'minute',
steps: [1, 2, 5, 10, 30]
}, {
name: 'hour',
steps: [1, 2, 3, 6, 12]
}, {
name: 'day',
steps: [1, 2, 5]
}, {
name: 'week',
maxStep: 4
}, {
name: 'month',
maxStep: 3
}, {
name: 'quarter',
maxStep: 4,
}, {
name: 'year',
maxStep: false
},
],
};
var defaultConfig = {
position: "bottom",
time: {
format: false, // false == date objects or use pattern string from http://momentjs.com/docs/#/parsing/string-format/
unit: false, // false == automatic or override with week, month, year, etc.
round: false, // none, or override with week, month, year, etc.
displayFormat: false, // DEPRECATED
// defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
displayFormats: {
'millisecond': 'SSS [ms]',
'second': 'h:mm:ss a', // 11:20:01 AM
'minute': 'h:mm:ss a', // 11:20:01 AM
'hour': 'MMM D, hA', // Sept 4, 5PM
'day': 'll', // Sep 4 2015
'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
'month': 'MMM YYYY', // Sept 2015
'quarter': '[Q]Q - YYYY', // Q3
'year': 'YYYY', // 2015
},
},
};
var TimeScale = Chart.Scale.extend({
getLabelMoment: function(datasetIndex, index) {
return this.labelMoments[datasetIndex][index];
},
determineDataLimits: function() {
this.labelMoments = [];
// Only parse these once. If the dataset does not have data as x,y pairs, we will use
// these
var scaleLabelMoments = [];
if (this.chart.data.labels && this.chart.data.labels.length > 0) {
helpers.each(this.chart.data.labels, function(label, index) {
var labelMoment = this.parseTime(label);
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
scaleLabelMoments.push(labelMoment);
}, this);
if (this.options.time.min) {
this.firstTick = this.parseTime(this.options.time.min);
} else {
this.firstTick = moment.min.call(this, scaleLabelMoments);
}
if (this.options.time.max) {
this.lastTick = this.parseTime(this.options.time.max);
} else {
this.lastTick = moment.max.call(this, scaleLabelMoments);
}
} else {
this.firstTick = null;
this.lastTick = null;
}
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
var momentsForDataset = [];
if (typeof dataset.data[0] === 'object') {
helpers.each(dataset.data, function(value, index) {
var labelMoment = this.parseTime(this.getRightValue(value));
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
momentsForDataset.push(labelMoment);
// May have gone outside the scale ranges, make sure we keep the first and last ticks updated
this.firstTick = this.firstTick !== null ? moment.min(this.firstTick, labelMoment) : labelMoment;
this.lastTick = this.lastTick !== null ? moment.max(this.lastTick, labelMoment) : labelMoment;
}, this);
} else {
// We have no labels. Use the ones from the scale
momentsForDataset = scaleLabelMoments;
}
this.labelMoments.push(momentsForDataset);
}, this);
// We will modify these, so clone for later
this.firstTick = (this.firstTick || moment()).clone();
this.lastTick = (this.lastTick || moment()).clone();
},
buildTicks: function(index) {
this.ticks = [];
this.unitScale = 1; // How much we scale the unit by, ie 2 means 2x unit per step
// Set unit override if applicable
if (this.options.time.unit) {
this.tickUnit = this.options.time.unit || 'day';
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true));
} else {
// Determine the smallest needed unit of the time
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var labelCapacity = innerWidth / (this.options.ticks.fontSize + 10);
var buffer = this.options.time.round ? 0 : 2;
// Start as small as possible
this.tickUnit = 'millisecond';
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit, true) + buffer);
this.displayFormat = this.options.time.displayFormats[this.tickUnit];
var unitDefinitionIndex = 0;
var unitDefinition = time.units[unitDefinitionIndex];
// While we aren't ideal and we don't have units left
while (unitDefinitionIndex < time.units.length) {
// Can we scale this unit. If `false` we can scale infinitely
//var canScaleUnit = ;
this.unitScale = 1;
if (helpers.isArray(unitDefinition.steps) && Math.ceil(this.tickRange / labelCapacity) < helpers.max(unitDefinition.steps)) {
// Use one of the prefedined steps
for (var idx = 0; idx < unitDefinition.steps.length; ++idx) {
if (unitDefinition.steps[idx] > Math.ceil(this.tickRange / labelCapacity)) {
this.unitScale = unitDefinition.steps[idx];
break;
}
}
break;
} else if ((unitDefinition.maxStep === false) || (Math.ceil(this.tickRange / labelCapacity) < unitDefinition.maxStep)) {
// We have a max step. Scale this unit
this.unitScale = Math.ceil(this.tickRange / labelCapacity);
break;
} else {
// Move to the next unit up
++unitDefinitionIndex;
unitDefinition = time.units[unitDefinitionIndex];
this.tickUnit = unitDefinition.name;
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
this.displayFormat = this.options.time.displayFormats[unitDefinition.name];
}
}
}
this.firstTick.startOf(this.tickUnit);
this.lastTick.endOf(this.tickUnit);
this.smallestLabelSeparation = this.width;
helpers.each(this.chart.data.datasets, function(dataset, datasetIndex) {
for (var i = 1; i < this.labelMoments[datasetIndex].length; i++) {
this.smallestLabelSeparation = Math.min(this.smallestLabelSeparation, this.labelMoments[datasetIndex][i].diff(this.labelMoments[datasetIndex][i - 1], this.tickUnit, true));
}
}, this);
// Tick displayFormat override
if (this.options.time.displayFormat) {
this.displayFormat = this.options.time.displayFormat;
}
// For every unit in between the first and last moment, create a moment and add it to the ticks tick
for (var i = 0; i <= this.tickRange; ++i) {
if (i % this.unitScale === 0) {
this.ticks.push(this.firstTick.clone().add(i, this.tickUnit));
} else if (i === this.tickRange) {
// Expand out the last one if not an exact multiple
this.tickRange = Math.ceil(this.tickRange / this.unitScale) * this.unitScale;
this.ticks.push(this.firstTick.clone().add(this.tickRange, this.tickUnit));
this.lastTick = this.ticks[this.ticks.length - 1].clone();
break;
}
}
},
// Get tooltip label
getLabelForIndex: function(index, datasetIndex) {
var label = this.chart.data.labels && index < this.chart.data.labels.length ? this.chart.data.labels[index] : '';
if (typeof this.chart.data.datasets[datasetIndex].data[0] === 'object') {
label = this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
}
// Format nicely
if (this.options.time.tooltipFormat) {
label = this.parseTime(label).format(this.options.time.tooltipFormat);
}
return label;
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(function(tick, index, ticks) {
var formattedTick = tick.format(this.displayFormat);
if (this.options.ticks.userCallback) {
return this.options.ticks.userCallback(formattedTick, index, ticks);
} else {
return formattedTick;
}
}, this);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var labelMoment = this.getLabelMoment(datasetIndex, index);
var offset = labelMoment.diff(this.firstTick, this.tickUnit, true);
var decimal = offset / this.tickRange;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueWidth = innerWidth / Math.max(this.ticks.length - 1, 1);
var valueOffset = (innerWidth * decimal) + this.paddingLeft;
return this.left + Math.round(valueOffset);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
var valueHeight = innerHeight / Math.max(this.ticks.length - 1, 1);
var heightOffset = (innerHeight * decimal) + this.paddingTop;
return this.top + Math.round(heightOffset);
}
},
parseTime: function(label) {
// Date objects
if (typeof label.getMonth === 'function' || typeof label == 'number') {
return moment(label);
}
// Moment support
if (label.isValid && label.isValid()) {
return label;
}
// Custom parsing (return an instance of moment)
if (typeof this.options.time.format !== 'string' && this.options.time.format.call) {
return this.options.time.format(label);
}
// Moment format parsing
return moment(label, this.options.time.format);
},
});
Chart.scaleService.registerScaleType("time", TimeScale, defaultConfig);
}).call(this, moment);

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais