Comparar commits

..

676 Commits

Autor SHA1 Mensagem Data
Tanner Linsley 82541248a1 Getting Started.... again. 2015-09-29 16:32:43 -06:00
Tanner Linsley 39340fa412 Update Getting Started and created Scales documentation 2015-09-29 13:29:53 -06:00
Tanner Linsley cd4b6815c8 Dis Build 2015-09-29 10:55:05 -06:00
Tanner Linsley e24406fc9d Ensure tickUnit and displayFormat set before format loop 2015-09-29 10:54:42 -06:00
Tanner Linsley 4c79c5756f Time Scale Samples updated to import moment beforehand 2015-09-28 12:46:25 -06:00
Tanner Linsley 5543041fcd Add Moment.js back into test reps 2015-09-28 12:45:53 -06:00
Tanner Linsley c13d960df5 Built Dist Files (reduced lib to 122kb minified) 2015-09-28 11:30:52 -06:00
Tanner Linsley 5a31c50d4d Built Dist Files 2015-09-28 11:28:52 -06:00
Tanner Linsley 39b15b98e6 Removed moment from build, import color lib first 2015-09-28 11:28:34 -06:00
Tanner Linsley 63a0273591 Remove moment and onecolor as deps 2015-09-28 11:28:05 -06:00
Tanner Linsley 1bdf5edc24 Time Scale now requires and warns for Moment.js dep 2015-09-28 11:27:47 -06:00
etimberg e6d15474df Commit built files after refactor 2015-09-28 07:45:50 -04:00
Evert Timberg d09c25c0d5 Merge pull request #1488 from nnnick/v2.0-dev-refactor
V2.0 dev refactor
2015-09-27 21:50:25 -04:00
Evert Timberg 77faacb467 Removed the line scale override file since functionality no longer directly exists. Updated the core scale drawing with tighter padding & better drawing when on top. Updated tests 2015-09-27 21:34:16 -04:00
Evert Timberg db3b5c1735 Fix broken helper test 2015-09-27 19:40:38 -04:00
Evert Timberg 7a0803cfd7 Fix line controller tests 2015-09-27 19:19:21 -04:00
Evert Timberg 4fd30e0c75 Last bar controller test fixes 2015-09-27 18:29:54 -04:00
Evert Timberg 80b2ffe3ee Fix bar controller unit tests 2015-09-27 18:28:09 -04:00
Evert Timberg bc7d1d39fd Convert the radialLinear scale to derive from Core.scale. Radial linear scale is now fit using the scale service. Added tests for the radialLinear scale. 2015-09-27 11:58:20 -04:00
Evert Timberg be4facdea9 Time scale tests. 2015-09-27 09:38:11 -04:00
Evert Timberg 5156e633ca Category scale tests 2015-09-26 16:52:14 -04:00
Evert Timberg 49a8b191c4 Update logX sample to use correct label callback 2015-09-26 16:50:59 -04:00
Evert Timberg 68f563fba4 Merge branch 'v2.0-dev-refactor' of https://github.com/nnnick/Chart.js into v2.0-dev-refactor 2015-09-25 21:04:57 -04:00
Evert Timberg 3d1e1b1605 Updated core.scale draw code with minor improvements and features that broke during integration (such as mirror option for labels). Updated linear and logarithmic tests. Update config merge to use scaleMerge since it prevents overriding the default entirely. 2015-09-25 21:04:45 -04:00
Tanner Linsley b8d8ff8bae I guess, don't include the offset. Bars now align correctly. 2015-09-24 22:49:43 -06:00
Evert Timberg cf944ae651 Make sure ticks are converted to strings. Handle this in the core. Updated linear scale tests & fixed some minor issues. Only 3 fails now in the linear scale. 2015-09-24 22:08:25 -04:00
Evert Timberg 2e2bbc9d52 Start to clean up the linear scale tests 2015-09-24 18:54:56 -04:00
Evert Timberg f1b704a419 Fix scale fitting to give padding around the scale title & to account for label rotation 2015-09-24 18:53:48 -04:00
Tanner Linsley 505e6d780e Always includeOffset for bar controller 2015-09-24 15:46:10 -06:00
Tanner Linsley 7372987754 Add scaleLabel to core.scale 2015-09-24 15:45:56 -06:00
Tanner Linsley b22f569e4d Merge branch 'v2.0-dev' into v2.0-dev-refactor
Conflicts:
	samples/line-scale-override.html
	samples/line-x-axis-filter.html
	samples/line.html
	src/controllers/controller.bar.js
	src/core/core.controller.js
	src/scales/scale.category.js
2015-09-24 14:34:26 -06:00
Tanner Linsley 1f0ee92992 Polar Area now uses new scale.update method 2015-09-24 13:07:32 -06:00
Tanner Linsley 8cda74e691 Pie.customtooltips is outdated. Removing for now. 2015-09-24 13:05:46 -06:00
Tanner Linsley dc3f58f044 Doughnut.color is outdated. Removing for now. 2015-09-24 13:01:07 -06:00
Tanner Linsley 4c2027aabb Horizontal Log Scale 2015-09-24 12:59:03 -06:00
Tanner Linsley 440703efff Log Scale Working Again 2015-09-24 12:31:18 -06:00
Tanner Linsley d198157fb8 Time Scale working, troubleshooting log scale 2015-09-24 12:07:40 -06:00
Evert Timberg d1067f956c Merge pull request #1485 from BenWoodford/label-patches
Label customisation fixes
2015-09-24 11:07:51 -04:00
Ben Woodford b0679a80ae Fixed label padding not affecting x-axis label 2015-09-24 16:02:58 +01:00
Ben Woodford d7ab51f29b Only rotate label while rotation is < maxRotation
Checking for <= maxRotation results in a labelRotation of 1 if maxRotation is 0, which doesn't make any sense (and also causes the text to be right aligned not centred)
2015-09-24 15:54:10 +01:00
Tanner Linsley ca48caa8b0 checkpoint for the morning check
made some good progress.  Just need some more eyes on it, cuz I’m
literally typing without my glasses on right now.
2015-09-24 02:25:21 -06:00
Tanner Linsley e2a96501b7 Vertical Scales are a bit better now 2015-09-23 23:23:20 -06:00
Tanner Linsley c7107677d2 Stuck on shared vertical scale draw logic
Trying to make all scales share the same draw function for both
horizontal and vertical.  For some reason the vertical linear scale on
line.html has a width that is too small
2015-09-23 21:52:31 -06:00
Tanner Linsley 9b9ebca246 Checkpoint 1, Pew!!!! 2015-09-22 19:31:26 -06:00
Tanner Linsley 36493e042e Merge pull request #1480 from etimberg/fix/retina-scale-issue
Fixes some retina issues introduced into the v2 codeline
2015-09-22 17:28:35 -06:00
Evert Timberg 4a093196b8 Don't increase canvas css size during a retina scale. Reset the canvas style exactly as it was set before during destroy. Ensure coordinates are translated over correctly into model coordinates. Fixed a bug during destroy when unscaling the canvas 2015-09-22 19:22:55 -04:00
Evert Timberg cd0b95d383 Merge pull request #1478 from etimberg/feature/data-change-api
Data change must only happen by changing the data object
2015-09-22 12:10:51 -04:00
Evert Timberg 029aad4f35 Update samples to no longer use old functions and instead modify the data directly 2015-09-21 21:00:58 -04:00
Evert Timberg 4e536c523e Test missed in last check-in 2015-09-21 21:00:09 -04:00
Evert Timberg 416a6ac1bd Remove unneeded functions from core controller. Updated dataset controllers to have a separate function to update the meta data for each dataset 2015-09-21 20:59:53 -04:00
Tanner Linsley 301efac8dd Merge pull request #1477 from etimberg/feature/scale-labels
Scale Labels
2015-09-21 17:52:09 -06:00
Tanner Linsley 8c94ae0441 Ensure bar width at least 1px 2015-09-21 13:17:27 -06:00
Tanner Linsley 01fdd387d9 Merge pull request #1474 from nnnick/v2.0-feature-dynamic-bar-spacing
Bar spacing is now dynamic at small sizes.
2015-09-21 13:08:09 -06:00
Tanner Linsley e3e66d2425 Time scale support 2015-09-21 13:04:41 -06:00
Tanner Linsley 154083b875 Bar spacing is now dynamic at small sizes.
Closes #1468
2015-09-21 12:57:04 -06:00
Tanner Linsley 3ce06ab387 Merge pull request #1473 from nnnick/v2.0-dev-timescale-fix
Time scale now draws all ticks, instead of half of them
2015-09-21 11:55:51 -06:00
Tanner Linsley 2a76ff0037 Time scale now draws all ticks, instead of half of them
Closes #1463
2015-09-21 11:52:17 -06:00
Tanner Linsley 848710b447 Merge pull request #1471 from etimberg/fix/mouse-coordinates
Convert screen coordinates into canvas coordinates when dealing with mouse events
2015-09-21 11:37:21 -06:00
Tanner Linsley d537366f0c Merge pull request #1470 from etimberg/feature/updated_resize_fix
Updated PR to replace #1467
2015-09-21 11:36:43 -06:00
Evert Timberg 2e479e4589 Update tests for new scale labels 2015-09-20 19:41:48 -04:00
Evert Timberg 6ba0fc3e08 Update sample files 2015-09-20 19:25:17 -04:00
Evert Timberg f4cdd20a38 Time scale has a label now 2015-09-20 19:24:46 -04:00
Evert Timberg b7c7f1d6a4 Category scale has labels 2015-09-20 19:18:59 -04:00
Evert Timberg 9fecb37e30 Update tests for new config options 2015-09-20 19:06:34 -04:00
Evert Timberg 2667807c1d Logarithmic scale now has labels 2015-09-20 19:06:09 -04:00
Evert Timberg b1060f20ec Linear scale has labels 2015-09-20 18:59:58 -04:00
Evert Timberg 162aaa993a Convert screen coordinates into canvas coordinates when dealing with mouse events 2015-09-20 17:57:27 -04:00
Evert Timberg 17cec5297d Update charts with default aspect ratio of 1 where it makes sense. If the canvas has no size specified, this will be used 2015-09-20 10:34:40 -04:00
Evert Timberg 8aa6288210 Ensure that radii are always >= 0 for doughnuts and polar area charts 2015-09-20 10:33:36 -04:00
Evert Timberg 8bddbff9aa Prevent a jump in the category scale when the labels need to rotate only when there is no margin yet applied. 2015-09-20 10:32:43 -04:00
Evert Timberg 814c2d7ffa Remove responsive file since it is not necessary 2015-09-20 10:30:43 -04:00
Evert Timberg 39252d4633 Use hidden iframe to detect resize + obey max width when getting maximum size. Updated the bar sample to start off hidden. Use the 'show' button to display the graph 2015-09-20 10:30:12 -04:00
Evert Timberg 7d0a7844ea Merge pull request #1469 from nnnick/revert-1467-feature/resize_problems
Revert "Fix resize problems when charts are initially hidden"
2015-09-19 17:53:35 -04:00
Evert Timberg 9474d72491 Revert "Fix resize problems when charts are initially hidden" 2015-09-19 17:52:58 -04:00
Tanner Linsley 862045e49a Merge pull request #1465 from nnnick/v2.0-dev-time-scale-bars-and-combo
Bar and combo support for time scale
2015-09-18 18:59:58 -06:00
Tanner Linsley efa5ab7ec8 Merge pull request #1467 from etimberg/feature/resize_problems
Fix resize problems when charts are initially hidden
2015-09-18 18:59:39 -06:00
Evert Timberg 97cec8604a Only store the original device context ratio once 2015-09-18 19:22:54 -04:00
Evert Timberg 8d47693448 Make sure that doughnut and polar area inner & outer radius is >= 0 2015-09-18 18:59:55 -04:00
Evert Timberg db5066cd23 Remove core.responsive file. Responsiveness is added during initialization 2015-09-18 18:44:00 -04:00
Evert Timberg 52c1c09e16 Revert "Commit built version of scale algo changes"
This reverts commit a36a3f8c09.
2015-09-18 18:41:45 -04:00
Evert Timberg bcbd9a85e6 Merge remote-tracking branch 'upstream/v2.0-dev' into feature/resize_problems
Conflicts:
	gulpfile.js
2015-09-18 18:38:47 -04:00
Tanner Linsley 677c249b61 Bar and combo support for time scale 2015-09-18 11:31:25 -06:00
Evert Timberg 723c85320f Unit tests for logarithmic scale. Fixed some issues in stacked mode since it's not possible for a 0 crossing to occur with a log scale. 2015-09-17 20:29:41 -04:00
Tanner Linsley 92682abbae Merge pull request #1459 from nnnick/v2.0-dev-feature-time-axis
V2.0 dev feature time axis
2015-09-17 15:54:44 -06:00
Evert Timberg a88d448fc8 Merge pull request #1458 from mennodekker/patch-1
Fixed issue #1163 hover.mode = 'dataset' no longer throws an error
2015-09-17 07:24:15 -04:00
Menno Dekker 5047678799 Tabs to spaces + fixed error 2015-09-17 10:08:42 +02:00
Menno Dekker 5ff2b530b9 Hover on dataset now works just like hover on label
Fixed some errors in de hover on dataset mode, only tested on bar charts
2015-09-17 09:43:02 +02:00
Tanner Linsley 2598446d54 Time Scale Rewrite 2015-09-15 11:40:01 -06:00
Tanner Linsley c479022c20 Merge pull request #1456 from etimberg/feature/logarithmic_scale
Logarithmic scale
2015-09-14 18:58:17 -06:00
Evert Timberg eb657bce36 Hide labels when the user returns null from the userCallback. This is the same as the category scale 2015-09-14 20:34:49 -04:00
Evert Timberg c1f0a39982 Fixes to show all lines but not all labels. Added a variable in the template function to make debugging nicer. 2015-09-14 20:32:23 -04:00
Evert Timberg e0cdfc6d2d Update logarithmic sample. Created a new logarithmic sample using AC circuit simulation data of an RLC filter. 2015-09-14 19:46:28 -04:00
Evert Timberg b172a382f1 Remove dead code in logarithmic scale. Fixed a padding bug that had previously been fixed in the linear scale 2015-09-14 19:45:13 -04:00
Evert Timberg 77f90a85ef Merge remote-tracking branch 'upstream/v2.0-dev' into feature/logarithmic_scale 2015-09-14 18:59:52 -04:00
Evert Timberg e6220f474b Attempting to make resize better 2015-09-14 18:50:52 -04:00
Tanner Linsley 88d30d8c93 Let tooltips use time formatted labels if they exist 2015-09-11 12:20:32 -06:00
Tanner Linsley c2a7e4c251 Time Scale Base 2015-09-10 22:48:48 -06:00
Tanner Linsley fe5ef1584b Add Line chart with time scale sample 2015-09-10 22:48:20 -06:00
Tanner Linsley 8762ae2f28 Add moment.js as dependency 2015-09-10 22:46:51 -06:00
Tanner Linsley 98eea76195 Do not test on gulp watch 2015-09-10 22:46:07 -06:00
Evert Timberg a36a3f8c09 Commit built version of scale algo changes 2015-09-09 20:28:34 -04:00
Evert Timberg 3f75aabbc5 Better scale fitting algorithm to handle when label rotation changes due to the application of margins on the scale 2015-09-05 13:27:06 -04:00
Evert Timberg 6b6c388a1a Helper for resize listener 2015-09-04 22:55:57 -04:00
Evert Timberg 2f38a3894a Get resize listener helper 2015-09-04 22:55:41 -04:00
Evert Timberg 4d51f21831 Merge pull request #1436 from honza889/reverse-radar
Reverse scale on radar / polar area
2015-09-02 17:46:35 -04:00
Jan Kalina ef539bf4a7 Reverse scale on radar/polar area 2015-09-02 23:21:39 +02:00
Evert Timberg 9cc2c18059 Latest built changes 2015-09-01 18:12:37 -04:00
Evert Timberg f78ce21da2 Merge pull request #1430 from etimberg/feature/doughnutLabels
Use the dataset label if available
2015-08-31 21:54:33 -04:00
etimberg eabdbab89e If the element has a label, use that in the tooltip instead of the dataset label. 2015-08-31 21:49:51 -04:00
Evert Timberg f9eb8b141e Merge pull request #1429 from etimberg/feature/unit-test
Linear scale tests
2015-08-31 20:44:27 -04:00
Evert Timberg 54858b921d More linear scale tests 2015-08-31 20:42:29 -04:00
Evert Timberg 02e0f3f856 Check some more data on the linear scale after fitting 2015-08-30 21:50:41 -04:00
Evert Timberg c8d5856216 Start testing the linear scale fit code 2015-08-30 21:49:39 -04:00
Evert Timberg 0813924a7e Merge pull request #1428 from etimberg/feature/unit-test
Core.element unit tests
2015-08-30 20:47:34 -04:00
Evert Timberg 702b9553e7 More helper tests 2015-08-30 20:46:26 -04:00
Evert Timberg bb0a8991df Core element tests 2015-08-30 20:17:24 -04:00
Evert Timberg e681d8cf23 Better debug page reporting of failed tests 2015-08-30 18:23:53 -04:00
Evert Timberg c4da135fe0 Merge pull request #1427 from etimberg/feature/unit-test
Adds unit tests for the doughnut & line controllers + line controller updates
2015-08-30 17:54:12 -04:00
Evert Timberg ce623075e3 Add line controller tests. Fixed an issue when the number of data points changes. When adding the tension to a point, get the same tension as the line if it has been overridden at the dataset level. When setting the hover style of a point, allow setting the radius independently of the regular radius. Use the hoverRadius property in point.custom or the dataset.pointHoverRadius. Allow setting the border width independently at the dataset level. Use dataset.pointHoverBorderWidth. This can be an array or a number. 2015-08-30 17:42:42 -04:00
Evert Timberg 8e9de00529 Doughnut controller tests 2015-08-30 14:56:48 -04:00
Evert Timberg 8f97939f25 Merge pull request #1426 from etimberg/feature/unit-test
Tests for the bar controller + bug fixes
2015-08-30 10:44:42 -04:00
Evert Timberg fcad4de670 Finish up bar controller tests 2015-08-30 10:42:00 -04:00
Evert Timberg 471618d287 Initial bar controller tests 2015-08-29 22:27:40 -04:00
Evert Timberg accb5ed654 Merge pull request #1425 from etimberg/feature/unit-test
Unit tests for elements
2015-08-29 14:19:01 -04:00
Evert Timberg eadfbbee6f Initial line element tests. Did not test the skipNull functionality since it seems to be broken. 2015-08-29 14:16:37 -04:00
Evert Timberg 17c075eb0e Arc element tests 2015-08-29 12:31:44 -04:00
Evert Timberg 26684b6371 Rectangle element tests 2015-08-29 08:53:42 -04:00
Evert Timberg f9a9e6bfb7 Do mock context properties better 2015-08-28 23:20:01 -04:00
Evert Timberg c09414cc40 First set of tests for point. Started on a mockContext object for testing. Still need to handle property setting better (fillStyle, strokeStyle, etc) 2015-08-28 23:09:58 -04:00
Evert Timberg 371bc8913f Start writing tests for core.helpers. Fix a number of small bugs found during testing 2015-08-28 22:32:56 -04:00
Tanner Linsley 1185208bf9 Merge pull request #1424 from etimberg/feature/unit-test
Add coverage metrics for unit tests
2015-08-28 17:13:08 -06:00
Evert Timberg 7fed38f1ab Merge remote-tracking branch 'upstream/v2.0-dev' into feature/unit-test
Conflicts:
	gulpfile.js
2015-08-28 19:09:39 -04:00
Evert Timberg 2a49e226f9 Merge pull request #1423 from nnnick/v2.0-dev-unit-test-via-travis
Organize Gulpfile, Integrate unit tests with Travis
2015-08-28 19:05:56 -04:00
Evert Timberg 92f1c65c1c Install coverage metrics. Use gulp coverage to generate coverage reports 2015-08-28 19:02:37 -04:00
Tanner Linsley edf95175a7 Organize Gulpfile, Integrate unit tests with Travis 2015-08-28 16:58:23 -06:00
Evert Timberg 9c1a0cbc16 This should run the unit tests from the CI system 2015-08-28 18:52:46 -04:00
Tanner Linsley bc3948ce59 Merge pull request #1408 from etimberg/feature/unit-test
Initial unit test framework + linear scale test starting point
2015-08-28 16:26:10 -06:00
Tanner Linsley bade753fe3 Don't account for paddingLeft until after rotated 2015-08-28 15:12:35 -06:00
Evert Timberg e6dc2fd6ab Initial scale tests 2015-08-23 17:17:46 -04:00
Evert Timberg b4b3bf60b8 Remove wrong addition of padding 2015-08-23 17:17:21 -04:00
Evert Timberg f636a78977 Watch mode runs tests. 2015-08-23 15:55:10 -04:00
Evert Timberg c1cca356df Initial test setup 2015-08-23 14:58:19 -04:00
Evert Timberg 8164418dc8 Merge pull request #1407 from etimberg/fix/category-filter-lines
Allow hiding grid lines using the filter function in the category scale
2015-08-23 13:24:58 -04:00
Evert Timberg 04d1f0f710 Category scale filter function will hide the grid line if null or undefined returned. 2015-08-23 13:20:43 -04:00
Evert Timberg 28b3a90723 Merge pull request #1406 from etimberg/fix/combo-bar-width
Count the number of bars when determining the bar width
2015-08-22 17:00:50 -04:00
Evert Timberg 02abc46d5e Count the number of bars when determining the bar width 2015-08-22 16:56:02 -04:00
Evert Timberg dc810096d4 Merge pull request #1404 from etimberg/fix/setLineDash
Only setLineDash if available
2015-08-22 16:17:02 -04:00
Evert Timberg 86ecca1c38 If setLineDash is not available, do not set it. 2015-08-22 16:13:19 -04:00
Evert Timberg fe427d67af Merge pull request #1403 from etimberg/fix/labelArea
Fixes #1393
2015-08-22 14:36:00 -04:00
Evert Timberg de413294ca Category scale now takes a smaller size if no labels are being displayed.
Updated linear scale code to use proper bottom padding. This is important when not displaying x axis labels
2015-08-22 14:30:30 -04:00
Evert Timberg fce1c42db3 Merge pull request #1380 from etimberg/fix/template-caching
Fixes template caching issues
2015-08-22 13:50:33 -04:00
Evert Timberg 3dd2ee7968 Merge branch 'v2.0-dev' of https://github.com/nnnick/Chart.js into fix/template-caching 2015-08-15 10:57:13 -04:00
Evert Timberg 24a78e772c Proper template string caching 2015-08-15 10:56:55 -04:00
Evert Timberg dd62944b79 Fix bracket placement 2015-08-15 10:54:34 -04:00
Evert Timberg 7f345f051f Merge pull request #1374 from fastrde/v2.0-dev
Fix for #1373
2015-08-14 19:50:15 -04:00
Fabian Strachanski 94c1ec4b84 Fix for #1373 2015-08-13 10:50:56 +02:00
Evert Timberg eb833723cd initial logarithmic scale 2015-08-08 18:34:19 -04:00
Evert Timberg 88896abe48 During a mousemove event only re-render the chart instead of updating it. Updating uses more memory & causes flicker in the axes. 2015-08-08 18:12:01 -04:00
Evert Timberg 87ac933c10 Linear scale has proper padding in both vertical and horizontal orientations. Should prevent labels from getting cut off even when axes are not displayed. 2015-08-08 11:52:20 -04:00
Evert Timberg 9dfa9e8e66 Fix the outerRadius calculation with respect to the border width. Previously the border width was divided by 2 twice rather than once. 2015-08-08 10:14:37 -04:00
Evert Timberg 32f4f1e54a Merge pull request #1367 from achichenin/patch-1
Update 00-Getting-Started.md
2015-08-08 08:46:01 -04:00
Evert Timberg 6f28711196 Merge pull request #1365 from pratyushmittal/v2.0-dev
Added documentation for maxRotation of labels
2015-08-08 08:45:13 -04:00
achichenin 1cdc046566 Update 00-Getting-Started.md
tiny typo fix
2015-08-08 15:15:57 +03:00
Pratyush Mittal ca0ece37e6 Added documentation for maxRotation of labels 2015-08-08 14:07:24 +05:30
Tanner Linsley f5b44acc38 onAnimationComplete for zero-frame transitions 2015-08-07 13:39:09 -06:00
Evert Timberg 3f24389f36 Merge pull request #1357 from bakura10/mirror-linear-scale
Add support for mirror option on labels
2015-08-05 18:00:47 -04:00
Michaël Gallego 0c6f37fff7 Add support for mirror option 2015-08-05 17:40:44 +02:00
Tanner Linsley 31c5e45bd4 Build 2015-08-04 11:25:04 -06:00
Tanner Linsley f3706b0755 chart.update(0) now draws instantly instead of not at all 2015-08-04 11:24:27 -06:00
Tanner Linsley 26c210db33 More Accurate animation frame dropper 2015-08-03 17:17:49 -06:00
Evert Timberg f3303ce3fa Merge pull request #1354 from nnnick/v2.0-dev-feature-auto-skip-labels
Auto-skip crowded axis-labels
2015-08-03 15:37:08 -04:00
Tanner Linsley 452ef8b6e7 No Logs 2015-08-03 13:06:53 -06:00
Tanner Linsley 68b22562d9 DatasetWidth now incorporates chartPaddingLeft 2015-08-03 13:06:40 -06:00
Tanner Linsley d3ffc7aec1 Auto Skip Labels Attempt 1 2015-07-06 22:28:05 -04:00
Evert Timberg f7dbb9d07f Merge branch 'v2.0-dev' of https://github.com/nnnick/Chart.js into v2.0-dev 2015-07-05 14:56:54 -04:00
Evert Timberg f3eb6f4a43 Built legend version 2015-07-05 14:56:35 -04:00
Evert Timberg 925e305184 Doughnut legends (only makes sense for first dataset). 2015-07-05 14:56:22 -04:00
Evert Timberg 84aba3f6d3 Polar area legends 2015-07-05 14:48:04 -04:00
Evert Timberg 0caa2a79ae Legends for Line, Bar & Radar charts. 2015-07-05 14:47:56 -04:00
Evert Timberg dfd48debe5 Remove log call from polar area draw. 2015-07-05 14:36:27 -04:00
Evert Timberg 3475e72730 Merge pull request #1278 from tuttnauer/patch-2
Hover missing in parameter name
2015-07-05 08:01:31 -04:00
Guy dc58699ee7 Hover missing in parameter name
In the 1st dataset, the second time "pointBorderWidth" appeared it was under a comment referring to hover so I corrected it to be "pointHoverBorderWidth".  Also in the 2nd dataset. Needs to be tested.
2015-07-05 12:32:03 +03:00
Evert Timberg 2baad552f1 Built files to include dataset scale changes 2015-07-04 19:17:01 -04:00
Evert Timberg 06a2c52b26 Update scale docs. 2015-06-22 19:47:51 -04:00
Evert Timberg 97e6ff00d2 Merge pull request #1242 from etimberg/fix/documentation
Updated some docs + minor improvement to category scale
2015-06-22 19:06:48 -04:00
Evert Timberg 255bdc700e Line chart doc updates 2015-06-22 19:05:50 -04:00
Evert Timberg 6110352df8 Add userCallback to category scale + demo file 2015-06-22 19:03:01 -04:00
Evert Timberg 880ae3a474 Update getting started docs 2015-06-22 18:46:12 -04:00
Tanner Linsley 9368c6079d Gulp build 2015-06-22 13:11:19 -06:00
Tanner Linsley bc8526efe7 Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev 2015-06-22 13:10:52 -06:00
Tanner Linsley 25fd84490b Support for custom tooltips again 2015-06-22 13:10:49 -06:00
Derek Perkins 1c9e90178c Merge pull request #1232 from etimberg/feature/line-stroke
More user editable properties for line elements
2015-06-20 09:07:48 -06:00
Evert Timberg 82de2f1351 Can now change more properties for line drawing. Updated the sample file to demo 2015-06-20 09:47:35 -04:00
Evert Timberg 48be4edbdd Category scale label rotation improvements 2015-06-19 20:24:14 -04:00
Evert Timberg 46af76a8ed addData is now supported by the doughnut chart + updated the sample to match. 2015-06-19 19:51:28 -04:00
Evert Timberg 2dd49f0c92 Fix a missing this in the scale generateTicks method when manually overriding. Added a sample to test this. 2015-06-19 19:13:31 -04:00
Tanner Linsley 539af61e1f Proper stacking order for stacked area charts 2015-06-19 14:23:05 -06:00
Tanner Linsley 85e928b426 Lazy Update and Render option
Usage: `.update(animationDuration, [bool])`
Tooltip animations are now "lazy” by default, meaning they can be
interrupted and pivoted by other animations. All others internal
updates are by nature non-interruptible, so hovering over a chart
during a regular `update()` cycle will pivot the tooltip correctly.
2015-06-19 13:29:36 -06:00
Tanner Linsley 5f6e2a0af3 Gulp build 2015-06-19 12:36:35 -06:00
Tanner Linsley 190cfcd1dc Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev 2015-06-19 12:36:27 -06:00
Tanner Linsley 8cecd5935e Tooltip Title width now accurately measured 2015-06-19 12:36:22 -06:00
Evert Timberg 891655b3ce Polar area charts now support addData and removeData. Fixed an issue with the animateRotate and animateScale options for polar area charts. 2015-06-18 18:51:00 -04:00
Evert Timberg 73af6a31b6 add support for addData and removeData to the radar chart. Needed to update the radialLinear scale so that the number of values is not cached. 2015-06-18 18:28:45 -04:00
Evert Timberg a3a2f8ea09 Line chart addData and removeData implementations + sample file updates 2015-06-18 18:04:28 -04:00
Tanner Linsley 8769b658b1 Gulp Build 2015-06-18 12:49:19 -06:00
Tanner Linsley 4e30531907 Allow custom skip property to points 2015-06-18 12:49:09 -06:00
Evert Timberg 7796c4e87d Add and remove data for bar charts 2015-06-17 22:03:24 -04:00
Tanner Linsley 061566ee27 Fix Label custom tooltips 2015-06-17 15:14:26 -06:00
Tanner Linsley cc2fb73e87 Build 2015-06-17 15:10:57 -06:00
Tanner Linsley 79f8ce0e97 Fixed Custom Tooltips 2015-06-17 15:10:45 -06:00
Tanner Linsley 75b7553683 Merge pull request #1221 from etimberg/feature/add-data
addDataset functionality
2015-06-16 20:28:10 -06:00
Evert Timberg 271d37f572 Update radar sample + use the same colour functions in all samples 2015-06-16 22:21:40 -04:00
Evert Timberg c9c1853c57 Update pie sample file to support add and remove datasets 2015-06-16 22:16:28 -04:00
Evert Timberg fd7a4e9bd7 Update doughnut sample to support adding and removing datasets 2015-06-16 22:12:59 -04:00
Evert Timberg f2298aed77 Update bar sample to handle adding and removing datasets 2015-06-16 22:05:20 -04:00
Evert Timberg e7850a796e Update line sample to test adding and removing datasets 2015-06-16 22:05:06 -04:00
Evert Timberg 19a30f5090 Update controllers to handle adding new datasets 2015-06-16 22:04:52 -04:00
Evert Timberg 23e02d621f Merge pull request #1220 from etimberg/feature/themes
Create interfaces similar to the old interfaces.
2015-06-16 19:30:02 -04:00
Evert Timberg 056b9550d0 Create interfaces similar to the old interfaces. Ensure that scales always have IDs before controllers are built. 2015-06-16 19:20:26 -04:00
Tanner Linsley 8d1f280771 Even better responsive sizing 2015-06-16 13:19:01 -06:00
Tanner Linsley 63530ba66d Better responsive sizing 2015-06-16 13:06:34 -06:00
Tanner Linsley 088b4fcc55 Fixed: scale.linear range min==max resulted in no scale 2015-06-16 12:04:52 -06:00
Tanner Linsley e3ffbb155f Deprecate animationLoop function 2015-06-16 11:57:35 -06:00
Tanner Linsley 48b8a3a2c5 Fixed issue where arc.inRange was sometimes over π threshold 2015-06-16 11:46:50 -06:00
Tanner Linsley 34f8bc99c6 Better demo for combo 2015-06-16 11:37:14 -06:00
Tanner Linsley a5e4b38252 Draw controllers in reverse (for proper line stacking) 2015-06-16 11:37:07 -06:00
Tanner Linsley 6065e8c801 helpers.each is now reversible 2015-06-16 11:31:15 -06:00
Tanner Linsley cd5a8d1a50 Fix getMaximumHeight function to use helpers 2015-06-16 11:24:25 -06:00
Tanner Linsley 37b13265c9 Build 2015-06-16 11:22:28 -06:00
Derek Perkins 0d5f282349 Merge pull request #1219 from etimberg/feature/controllers
Controller Driven Charts
2015-06-16 10:50:31 -06:00
Tanner Linsley db981807bb Polar Area Draws, but has scale resizing issues 2015-06-16 00:39:04 -06:00
Tanner Linsley 1f302f09bb Fixed polar-area sample 2015-06-16 00:20:46 -06:00
Tanner Linsley c0ccae1031 No logging 2015-06-16 00:20:22 -06:00
Tanner Linsley 9023057906 Old doughnuts are no good. 2015-06-16 00:20:06 -06:00
Tanner Linsley 2d5eb6d57e Radar chart and radialLinear scale 2015-06-16 00:17:26 -06:00
Tanner Linsley 42648d0a83 Build radial scale details inside itself 2015-06-15 23:59:04 -06:00
Tanner Linsley 4c749e78b2 Single scale again. 2015-06-15 23:58:31 -06:00
Tanner Linsley ef1acfa0e8 Build single scales in core 2015-06-15 23:54:25 -06:00
Tanner Linsley 5759f419c0 Pie used new doughnut controller 2015-06-15 22:47:20 -06:00
Tanner Linsley 8b3424bd09 Responsive used proper "each" from helpers 2015-06-15 22:44:06 -06:00
Tanner Linsley 76e060cf97 Better getElementAtEvent function 2015-06-15 22:43:45 -06:00
Tanner Linsley 2aa489643a Doughnut/Pie accurate radii 2015-06-15 22:43:24 -06:00
Tanner Linsley 36de623401 Merge remote-tracking branch 'origin/feature/controllers' into feature/controllers 2015-06-15 19:14:26 -06:00
Tanner Linsley 74f161b548 Core improvements, arc & doughnut partially working 2015-06-15 19:14:11 -06:00
Evert Timberg fa1b0db453 Apply correct hover styles 2015-06-15 19:34:40 -04:00
Evert Timberg 22c40fe752 Fix 2 bar samples 2015-06-15 19:34:29 -04:00
Evert Timberg d3538a1fbd use inLabelRange when tooltips are in label mode 2015-06-15 19:21:13 -04:00
Evert Timberg b21061c164 Remove hover styles 2015-06-15 19:10:47 -04:00
Evert Timberg 8e3d3c2c22 Fix animations 2015-06-15 18:54:46 -04:00
Tanner Linsley 9f9237905a Line now draws 2015-06-15 16:19:56 -06:00
Tanner Linsley 872c9d5ebb Hover macros, type defaults, and cleanup 2015-06-15 16:18:56 -06:00
Evert Timberg 15d9a044c6 Merge pull request #1215 from etimberg/fix/scalereverse
Linear scale is reversible
2015-06-15 18:02:17 -04:00
Evert Timberg 051ef8178e Merge pull request #1 from etimberg/feature/controllers-tanner
Chart controller, Dataset Controllers, Hybrid Charts
2015-06-15 17:32:19 -04:00
Evert Timberg 76d2a782fc Linear scale is reversible 2015-06-15 17:31:29 -04:00
Tanner Linsley 257bdb2dbb Hybrid Line and Bar chart - Line Now drawing 2015-06-15 15:27:56 -06:00
Tanner Linsley b0ece8b516 New controllers, bar drawing (with errors) 2015-06-15 14:36:02 -06:00
Tanner Linsley aaa2484e1b Controller function organization 2015-06-14 19:42:39 -06:00
Tanner Linsley 43f2c015f3 Charts become config blocks (themes, if you will :) 2015-06-14 19:30:02 -06:00
Tanner Linsley d811812356 Little tweaks 2015-06-14 19:26:44 -06:00
Tanner Linsley d73dae09e7 No hardcoded chart type methods 2015-06-14 19:15:10 -06:00
Tanner Linsley 4047440acc Git thinks the core file is new now haha 2015-06-14 18:10:00 -06:00
Tanner Linsley 3f9afb1f31 More core file separation, and no duplicate copyrights 2015-06-14 18:09:45 -06:00
Evert Timberg 81c66c8d85 Fix duplicate property 2015-06-14 17:05:46 -04:00
Evert Timberg 0fa2ac4ea0 Bar chart now uses the rectangular canvas & element controllers. 2015-06-14 15:26:34 -04:00
Evert Timberg 886c99623f Drop the base class in favour of an expanded canvas controller. Renamed 'chart' to 'chartInstance' in the controllers 2015-06-14 13:37:37 -04:00
Evert Timberg 68ae02263b Fix the broken scatter chart. Introduced the concept of a canvas controller that goes along with the element controller. 2015-06-14 13:00:09 -04:00
Evert Timberg 9751e8f5b1 Created a generic base class to be used by rectangular charts. Modified Chart.Type.extend to put the parent's prototype in __super__. Moved more code into the controller and renamed the controller to RectangularElementController. 2015-06-14 10:35:59 -04:00
Evert Timberg 89574b61c5 Prototype controller + some of line chart converted 2015-06-13 20:40:35 -04:00
Evert Timberg 253158cf1c Merge pull request #1208 from etimberg/feature/v2.0-scale-refactor
Radial scale improvements
2015-06-13 17:51:17 -04:00
Evert Timberg 8c34bdbcd7 Clean up of radial linear scale. Radar chart update function improvements 2015-06-13 17:45:59 -04:00
Evert Timberg ecd3b58b28 Fix typo in linear scale. 2015-06-13 14:47:13 -04:00
Evert Timberg 41bac830c5 Merge pull request #1207 from etimberg/feature/v2.0-scale-refactor
Move more scale configs into the scale defaults.
2015-06-13 14:30:18 -04:00
Evert Timberg 47b25d1c6d Move linearRadial default config to be a property of the scale. 2015-06-13 14:16:01 -04:00
Evert Timberg 109de75c6a Create linear scale default settings. Cleaned up unnecessary settings from bar, line, and scatter default configs. Removed unnecessary config options from the affected sample files 2015-06-13 13:57:55 -04:00
Evert Timberg 42856ec16a Merge pull request #1206 from etimberg/feature/v2.0-scale-refactor
Category scale now has defaults.
2015-06-13 13:33:05 -04:00
Evert Timberg faa43d51a9 Category scale now has defaults. Updated the bar & line charts to use this new default. 2015-06-13 13:25:41 -04:00
Evert Timberg 3e4fce58fa Clone handles arrays better 2015-06-13 13:22:28 -04:00
Evert Timberg b0bddce017 Remove some unused scale code 2015-06-13 11:45:30 -04:00
Evert Timberg b5c69984e3 Change spaces to tabs throughout 2015-06-13 10:15:21 -04:00
Evert Timberg a8375d0459 Merge pull request #1205 from etimberg/feature/v2.0-scale-refactor
Move things into the radialLinear scale
2015-06-13 10:01:06 -04:00
Evert Timberg 1f16b349d2 Merge Chart.scales into Chart.scaleService to be consistent 2015-06-13 09:55:43 -04:00
Evert Timberg 30019dfddd Move some of the radial linear scale functions into the radialLinear scale 2015-06-13 09:51:28 -04:00
Evert Timberg 61eea7f4a1 Merge pull request #1204 from etimberg/feature/v2.0-scale-refactor
Scatter chart derives from line chart
2015-06-13 09:06:05 -04:00
Evert Timberg 6582e2ff06 Handle nesting better in the clone method so that we don't wipe out the line defaults when the scatter chart extends 2015-06-13 08:59:54 -04:00
Evert Timberg 8cfe21f6aa Scatter chart now extends the line chart. 2015-06-13 08:46:49 -04:00
Evert Timberg 6815fc451f Merge remote-tracking branch 'upstream/v2.0-dev' into feature/v2.0-scale-refactor 2015-06-13 08:35:34 -04:00
Tanner Linsley 31643ee598 Support jQuery' or native canvas element as chart context 2015-06-13 02:41:15 -06:00
Tanner Linsley 1a3bb25f5c Reverse that :) 2015-06-13 02:13:38 -06:00
Tanner Linsley 181a61f16a Do not update involuntarily on resize. Only render. 2015-06-13 02:08:55 -06:00
Tanner Linsley 763bde9ed1 chart.bar - remove tooltip on mouseout 2015-06-13 00:45:43 -06:00
Tanner Linsley 0486db1e74 Category Scale display false fixes 2015-06-13 00:30:42 -06:00
Evert Timberg 6185f156ea Make the line and scatter charts almost identical. Next step is to merge them 2015-06-12 22:35:48 -04:00
Evert Timberg d37e65c58c Convert line chart to tabs from spaces 2015-06-12 22:07:07 -04:00
Evert Timberg 43efda72d4 Merge pull request #1202 from etimberg/feature/v2.0-scale-refactor
Push some of the scatter scale information down to the linear scale.
2015-06-12 21:54:03 -04:00
Evert Timberg e55c0d4945 Push some of the scatter scale information down to the linear scale. 2015-06-12 21:46:47 -04:00
Evert Timberg a518833f96 Merge pull request #1201 from etimberg/feature/v2.0-scale-refactor
Move stacked options into scales. Can be configured independently for each axis
2015-06-12 21:22:06 -04:00
Evert Timberg 49fe78643a Removed unused options from the bar and line charts 2015-06-12 21:16:23 -04:00
Evert Timberg d2ef4c9831 Move more data into the linear scale.This simplifies buildScale for line and bar charts 2015-06-12 21:15:15 -04:00
Evert Timberg ec7b87d69c Move some functions into the category scale. This cleans up the bar chart interface & allows for waterfall charts by settings stacked to false on the category axis but stacked to true on the y axis 2015-06-12 20:50:26 -04:00
Evert Timberg 1e01e29f88 Bar stacked sample 2015-06-12 19:10:11 -04:00
Tanner Linsley e9f206606d Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev 2015-06-12 16:39:43 -06:00
Evert Timberg c5e4912319 Rename 'scaleType' property to 'type; throughout samples & code 2015-06-12 18:24:51 -04:00
Tanner Linsley 63b7b18b17 Category Scale fixed 2015-06-12 16:18:20 -06:00
Tanner Linsley cfc008686b File structure fixes and gulp watch working again 2015-06-12 16:15:33 -06:00
Tanner Linsley e1237feb97 File structure for extensibility 2015-06-12 16:08:27 -06:00
Tanner Linsley cf88ec8333 File structure fixes, Radar Chart tooltip fixes 2015-06-12 15:37:38 -06:00
Tanner Linsley bba2dda59a No Logging 2015-06-12 15:28:50 -06:00
Tanner Linsley e2601f71e3 Hidden Scales Fixes 2015-06-12 15:28:30 -06:00
Tanner Linsley 195c794e5d File structure fixes 2015-06-12 14:48:20 -06:00
Tanner Linsley 5732e0d72a More maintainable file structure 2015-06-12 14:00:48 -06:00
Tanner Linsley 187163763e Line element custom override support 2015-06-11 10:04:08 -06:00
Tanner Linsley 15a32f4c78 Gulp build 2015-06-11 09:48:17 -06:00
Tanner Linsley a76640c409 Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev 2015-06-11 01:06:07 -06:00
Tanner Linsley 11773a5825 Hover states, Scale padding, and mouse out fixes 2015-06-11 01:05:44 -06:00
Evert Timberg 65de784be1 Merge pull request #1193 from etimberg/fix/scale-small-number-display
By default use toLocaleString() when generating labels for the axes. …
2015-06-10 20:14:26 -04:00
Evert Timberg 55cf07926c By default use toLocaleString() when generating labels for the axes. This prevents misformatted numbers due to doubles. It also makes large numbers nicer with commas by default. 2015-06-10 20:08:12 -04:00
Evert Timberg bd39534c2f Merge pull request #1187 from etimberg/fix/config-merge-clone
Fix an error when merging null config values
2015-06-09 20:36:44 -04:00
Evert Timberg 9dc63f0349 Merge pull request #1186 from etimberg/fix/log10
Use a polyfill when Math.log10 does not exist
2015-06-09 20:36:23 -04:00
Evert Timberg edd93f27ce Merge pull request #1180 from etimberg/fix/scale-zero-point
Use the correct base for linear scales
2015-06-09 20:36:15 -04:00
Evert Timberg 97a2232fbf Forgot that typeof null === 'object'
Added a check for this condition so that merge works correctly
2015-06-09 18:43:33 -04:00
Evert Timberg 29743e1d63 Use a polyfill when Math.log10 does not exist 2015-06-09 18:24:43 -04:00
Evert Timberg 2bddccaaf0 Use the correct base for linear scales. This gives the correct fill for lines and animations start at the correct point 2015-06-08 19:03:47 -04:00
Tanner Linsley 8f5d702a86 chart.update(animationDuration) support 2015-06-08 15:57:47 -06:00
Tanner Linsley 24d32e9321 Gulp build 2015-06-08 13:14:05 -06:00
Tanner Linsley 679fa4e72e Clone in configMerge 2015-06-08 13:12:20 -06:00
Evert Timberg 9b4ebc3a05 Merge branch 'etimberg-fix/polar-area-angle-fix' into v2.0-dev 2015-06-07 09:48:31 -04:00
Evert Timberg 7d4ead51f7 Merge branch 'fix/polar-area-angle-fix' of https://github.com/etimberg/Chart.js into etimberg-fix/polar-area-angle-fix
Conflicts:
	src/Chart.Core.js
2015-06-07 09:48:05 -04:00
Evert Timberg bcd834c084 Merge pull request #1169 from etimberg/fix/skip-data-type
Only skip when the data is null, not when it is not a number
2015-06-07 09:38:17 -04:00
Tanner Linsley 593a1eacc8 Merge pull request #1172 from etimberg/fix/scale-fit-updates
Scale fit updates
2015-06-06 13:13:24 -06:00
Evert Timberg d05d29aa66 Make the angle calculations more robust. Also ensure that angles in polar area charts are calculated similarly to angles in doughnut / pie charts 2015-06-06 11:06:40 -04:00
Evert Timberg 4a3a9f1a21 Change the scale fitting code from 2 pass fit to a 2.5 pass fit. The fit function is now passed a margin object that contains the margins on the left, top, right, and bottom of the scale. This is useful to know if you can draw outside of the width. This is used by the dataset scale so that extra padding is only added for long labels if absolutely required. If there is unused space underneath the vertical axes, that space is used first. 2015-06-06 09:27:03 -04:00
Evert Timberg a89ede0d72 Bring linear axis labels closer to the tick marks when in a horizontal configuration. Reduced excess whitespace. 2015-06-06 08:21:16 -04:00
Evert Timberg 65ec618a48 Some improvements to the linear scale. Made the tick marks smaller (5px vs 10px) and tightened up the drawing. Removed the use of maxWidth in ctx.fillText since that is not supported in Safari 2015-06-06 08:12:13 -04:00
Evert Timberg e63d5a3367 Only skip when the data is null, not when it is not a number 2015-06-05 18:03:35 -04:00
Tanner Linsley 5b5463b6f9 Merge pull request #1164 from etimberg/fix/angle-calculation
Fix the angle calculation for slice detection
2015-06-04 16:39:59 -06:00
Tanner Linsley 205163641f Doughnut/Pie Fixes 2015-06-04 16:39:05 -06:00
Evert Timberg 09eae7ff28 Fix angle calculation in determining which arcs are underneath the event point 2015-06-04 18:31:44 -04:00
Tanner Linsley d46a174080 Gulp Build 2015-06-03 19:45:14 -06:00
Tanner Linsley 0c91bb96e0 Merge pull request #1159 from etimberg/feature/v2.0dev-nestedConfig
Nested configs + major code refactors
2015-06-03 19:42:37 -06:00
Evert Timberg 9e9f436454 Bar config cleanup + some initial docs 2015-06-03 20:55:17 -04:00
Evert Timberg cbd2fef80f Merge branch 'feature/v2.0dev-nestedConfig' of https://github.com/etimberg/Chart.js into feature/v2.0dev-nestedConfig 2015-06-03 20:49:37 -04:00
Evert Timberg 996e471171 Missed some commas 2015-06-03 20:49:22 -04:00
Tanner Linsley 70f7dd4c7d Default global responsive 2015-06-03 18:47:14 -06:00
Evert Timberg 9c106aa8ff Some more line options 2015-06-03 20:46:35 -04:00
Evert Timberg 7dcee4b40e Additional fixes to line chart docs 2015-06-03 20:33:50 -04:00
Evert Timberg f12d1bcb56 Cleaned up line docs a bit and remove unnecessary options 2015-06-03 20:25:43 -04:00
Evert Timberg b9ab70f21b Cleaned up global config + documentation of global config options 2015-06-03 19:54:34 -04:00
Evert Timberg c2d6e4c31f Reset elements for polar area chart 2015-06-03 19:24:29 -04:00
Evert Timberg a6c712323f Reset elements for donut charts 2015-06-03 19:16:42 -04:00
Evert Timberg b93306788b Merge branch 'feature/v2.0dev-nestedConfig' of https://github.com/etimberg/Chart.js into feature/v2.0dev-nestedConfig 2015-06-03 18:36:08 -04:00
Evert Timberg 2a62e0e04d Reset elements for bar charts. Bar multi axis demo also shows different colours for each bar. 2015-06-03 18:35:42 -04:00
Tanner Linsley 8e5d8b8861 Doughnut and polar hovering/clicking 2015-06-03 16:31:25 -06:00
Tanner Linsley 8b0b6194b2 No playground 2015-06-03 15:25:28 -06:00
Tanner Linsley 675a9f827e Version bump 2.0.0-alpha 2015-06-03 15:25:18 -06:00
Tanner Linsley 235247eb12 example fixes 2015-06-03 15:18:42 -06:00
Tanner Linsley b3b5896329 Polar Area 2015-06-03 14:45:40 -06:00
Tanner Linsley ecb1cde3fc Fix 2015-06-03 14:17:10 -06:00
Tanner Linsley 9be48a73ea Pie Chart 2015-06-03 14:14:23 -06:00
Tanner Linsley 7e791e02f2 Radar Chart skipNull & bezier fixes 2015-06-03 12:05:04 -06:00
Evert Timberg 06d55e3501 Get closer to having radar charts work. Some issues with the line & point drawing code. 2015-06-03 08:02:21 -04:00
Evert Timberg 37cfbdb802 Fix an issue with bar charts that are not stacked 2015-06-03 07:57:50 -04:00
Evert Timberg 8d1a857e75 Scatter tooltips 2015-06-02 20:50:36 -04:00
Evert Timberg 42e2c237d4 Bind events in scatter chart 2015-06-02 20:48:26 -04:00
Evert Timberg b22e1e3e9c Update scatter chart. Still need to get tooltips working 2015-06-02 20:44:24 -04:00
Evert Timberg 635ec58616 Merge branch 'feature/v2.0dev-nestedConfig' of https://github.com/etimberg/Chart.js into feature/v2.0dev-nestedConfig 2015-06-02 20:07:07 -04:00
Evert Timberg f44dd06826 Better animations when chart is first initialized. 2015-06-02 20:06:50 -04:00
Tanner Linsley 02d7442e4f !bar borderWidth 2015-06-02 17:29:17 -06:00
Tanner Linsley 4ded634d75 no logging 2015-06-02 17:13:47 -06:00
Evert Timberg 80a25af502 Merge branch 'feature/v2.0dev-nestedConfig' of https://github.com/etimberg/Chart.js into feature/v2.0dev-nestedConfig 2015-06-02 18:55:41 -04:00
Evert Timberg 9b2d2efc7a Animation on refresh 2015-06-02 18:54:18 -04:00
Tanner Linsley 6b0e609935 Bar Chart Stacked nestedConfig 2015-06-02 16:48:39 -06:00
Tanner Linsley 74d3890ba9 no legend yet... :( 2015-06-02 15:14:51 -06:00
Tanner Linsley df4d2d2594 Stroked tooltip colors 2015-06-02 15:14:06 -06:00
Tanner Linsley b7dc2339f4 line: skipNull functionality 2015-06-02 13:42:09 -06:00
Evert Timberg edbb235668 Tooltip titles now work in the line chart. Getting ever closer to being done 2015-05-31 20:16:04 -04:00
Evert Timberg 92776ce0ac Animations & tool tips show. The title is not correct yet. 2015-05-31 16:55:17 -04:00
Evert Timberg e48c7f168b Add back line fill option. This is set on a per dataset basis, but there is an override in the config. Demo this in the line sample. 2015-05-31 10:24:53 -04:00
Evert Timberg 8a550852da Check in work from floobits with minor changes to fix some errors 2015-05-31 09:47:10 -04:00
Tanner Linsley 6af94298ec Radar Chart 2015-05-27 10:28:00 -06:00
Tanner Linsley 1163efbcca Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev
Conflicts:
	src/Chart.PolarArea.js
2015-05-26 22:06:20 -06:00
Tanner Linsley 3a32144d89 Polar Area deep data 2015-05-26 22:02:41 -06:00
Evert Timberg e3519f5bd4 More nested config stuff. Not sure what all of the options in the line config do, but left them in. Ensured that tooltips work. 2015-05-26 21:16:18 -04:00
Evert Timberg 7d8b1712a7 Convert bar chart to use nested config. Noticed that the segmentShowStroke option wasn't used at all. 2015-05-26 19:30:34 -04:00
Evert Timberg 54b51038ca Updated bar chart to use new nested config for bars. Removed unused relativeBars option. barBorderWidth was not used, but seems useful so we will keep it until later refactoring. 2015-05-26 19:11:05 -04:00
Evert Timberg e774a893da Use new animation options in the animation service. 2015-05-26 18:54:36 -04:00
Tanner Linsley b03a057a76 Nested globals 2015-05-26 16:52:16 -06:00
Tanner Linsley 48dd1cf024 Merge pull request #1132 from etimberg/feature/v2.0dev-xy
Scale rewrite for v2.0
2015-05-26 16:26:52 -06:00
Evert Timberg a2d477ac5e Moved radial scale into Chat.Scale.js. Registered as "radialLinear" which will allow radialLogarithmic, etc in the future. Updated the polar area and radar charts to use the new scale config. The scales draw, but the points do not. This is no different than the current v2.0 branch 2015-05-24 14:33:12 -04:00
Evert Timberg 1352dfeb0f Fix the y scales that were missed in the previous check in 2015-05-23 21:49:01 -04:00
Evert Timberg d4e7765a50 Clean up some unused config options. Renamed 'show' to 'display' for scales since that was clearer and maintains backwards compatibility. 2015-05-23 21:44:50 -04:00
Evert Timberg 73b579c962 Remove old linear scale 2015-05-23 21:21:40 -04:00
Evert Timberg b67afcd727 Bar chart converted to new scale system. Added bar chart multi axis sample. 2015-05-23 18:26:34 -04:00
Evert Timberg a10e245e5a Use correct tooltip events in each chart 2015-05-23 18:15:57 -04:00
Evert Timberg 181e866175 Fix line chart multi axis sample title 2015-05-23 17:50:27 -04:00
Evert Timberg d998c803d3 Move line chart over to use new scale config. This adds support for multiple y axes. Added an example demonstrating this. 2015-05-23 15:19:30 -04:00
Evert Timberg a559ab85cd Ensure consistency in the helpers.toRadians name 2015-05-23 15:18:33 -04:00
Evert Timberg c66edc9169 dataset axis to be used in the line chart and the bar chart 2015-05-23 15:18:08 -04:00
Evert Timberg b7606c7a8d Rename onHover to events to match the line chart 2015-05-23 15:15:04 -04:00
Evert Timberg 12e2ace039 Merge remote-tracking branch 'upstream/v2.0-dev' into feature/v2.0dev-xy
Conflicts:
	src/Chart.Core.js

Fixed the sample files & chart type initialize methods so that this.data does not get set to undefined.
2015-05-20 09:03:22 -04:00
Evert Timberg ed4b9945f8 Initial dataset scale class 2015-05-20 08:33:26 -04:00
Tanner Linsley 951e714e77 Playground and big changes 2015-05-20 00:03:45 -07:00
Evert Timberg 008bb1aab3 Set new tooltip templates for the scatter chart 2015-05-19 20:33:39 -04:00
Evert Timberg 4cc24d475a Clean up the scale service. It's now more of a helper function for fitting the scales. Since each chart needed to know it's scales, there wasn't much point in registering them into the service. When we support overlapping charts, we can do something fancier 2015-05-19 18:22:05 -04:00
etimberg 4b8c9bc30d Fix a drawing bug when drawTicks is false. 2015-05-18 20:59:21 -04:00
etimberg 978ed1bc1e Created a multi axis sample file. Added an option to draw ticks for the axes. This is useful when in a multi axis scenario so that the axis that does not draw grid lines does not have weird lines. 2015-05-18 20:39:59 -04:00
etimberg 676765e808 Initial config merge. Handles special cases for objects and arrays and merges smarter than simply replacing the default object. Tested by overriding the vertical axis 0 point colour. Also implemented dataset axis binding. If nothing is specified, the dataset is bound to the first x and y axis. 2015-05-18 14:19:34 -04:00
Evert Timberg f2065265c8 Fix an error in the scale service that prevented the chart from filling the canvas fully. 2015-05-18 10:27:39 -04:00
Evert Timberg a6e2eec9e0 Linear scale drawing improvements. Ensured that the scatter plot configuration has a different line colour for the 0 axis 2015-05-18 09:39:01 -04:00
Evert Timberg 2e383da0d8 Handle the beginAtZero option for a linear scale. Added a helper for Math.sign 2015-05-18 08:51:13 -04:00
Evert Timberg e30a9d2a94 The scatter example page now has negative numbers in both directions 2015-05-18 08:44:06 -04:00
Evert Timberg 492292e94b Remove x label rotation code since we dynamically adjust the number of labels to show and as such do not need to rotate 2015-05-18 08:43:38 -04:00
Evert Timberg 454f519b6d Fix jshint warnings 2015-05-18 08:27:18 -04:00
Evert Timberg 56d53e3ad4 Ensure that you always have at least 2 ticks on the linear axis 2015-05-17 13:29:17 -04:00
Evert Timberg 67b3d32218 Initial implementation of a scatter chart. Uses a new style of config from the other charts. For now, the config is not changeable. 2015-05-17 13:20:37 -04:00
Evert Timberg d7ad5b6340 Add a scatter chart sample 2015-05-17 13:19:37 -04:00
Evert Timberg db1365c8ce Initial check in of the scale service and the scale constructor registration. An initial implementation of a linear scale that can be drawn in both horizontal and vertical orientations. 2015-05-16 19:40:52 -04:00
Evert Timberg b5b0081108 Some helper functions needed for better scales. 2015-05-16 19:38:31 -04:00
Tanner Linsley fff81c455d Tooltip Position, Active Element Position, Tooltip animation follow 2015-05-15 23:07:21 -06:00
Tanner Linsley ad972a0c5c Pie cleanup. 2015-05-15 22:45:17 -06:00
Tanner Linsley 872c92cd4b Doughnut/Pie Chart refactor 2015-05-15 22:34:08 -06:00
Tanner Linsley 1d8d19d404 Prettified, and half way through doughut 2015-05-15 20:54:01 -06:00
Tanner Linsley ed6f234205 Bar chart pivot fix 2015-05-15 17:14:09 -06:00
Tanner Linsley 09c11440dd inGroupRange function for bar charts label mode 2015-05-15 17:07:41 -06:00
Tanner Linsley e58421a08a Line Chart label hoverMode & tooltips 2015-05-15 17:03:51 -06:00
Tanner Linsley fb580a6e48 lineChart single hoverMode tooltips, fallbackColor global 2015-05-15 16:40:01 -06:00
Tanner Linsley f79ebdaa88 Stable Bar Chart, DRY core functions 2015-05-15 00:04:42 -06:00
Tanner Linsley b432a3d6db labelMode tooltips and hover events 2015-05-14 23:18:47 -06:00
Tanner Linsley ef4c46f2be labelMode Tooltips almost there! 2015-05-14 17:25:56 -06:00
Tanner Linsley 69b1239aa1 Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev 2015-05-12 17:24:09 -06:00
Tanner Linsley 4ef57315da Getting into 'label' hoverMode tooltips 2015-05-12 17:22:47 -06:00
Evert Timberg d26f37236d Update package.json for color lib location 2015-05-12 18:01:28 -04:00
Tanner Linsley 63e115e7a8 hoverMode: "single" tooltips 2015-05-12 15:47:24 -06:00
Tanner Linsley 9f98334d6f Mid-code commit 2015-05-12 15:42:20 -06:00
Tanner Linsley 15f724f146 Rough Tooltips for 'single' hoverMode 2015-05-12 12:55:48 -06:00
Tanner Linsley afb22d15ae Better events 2015-05-12 10:35:55 -06:00
etimberg e709b13e77 Merge branch 'etimberg-fix/bar_chart_negative_values' into v2.0-dev
Merge in the changes to allow bar charts to support negative values.
2015-05-12 08:01:22 -04:00
etimberg 460399f651 Merge branch 'fix/bar_chart_negative_values' of https://github.com/etimberg/Chart.js into etimberg-fix/bar_chart_negative_values
# Conflicts:
#	samples/bar.html
#	src/Chart.Bar.js
#	src/Chart.Core.js
2015-05-12 08:00:14 -04:00
Tanner Linsley 132272d140 Revert build files
This reverts built files
2015-05-12 01:18:37 -06:00
Tanner Linsley 9e4d90e110 Color Animation, Color Autopilot 2015-05-12 01:13:16 -06:00
Tanner Linsley df91739b77 hoverMode, onHover, key fixes 2015-05-11 19:43:17 -06:00
Tanner Linsley d3f7071983 Merge pull request #1114 from etimberg/feature/get_bar_at_event
Create a getBarAtEvent function that returns the single bar that was clicked on
2015-05-11 19:27:52 -06:00
etimberg d287a01b44 Make sure that the _start item is cleaned up during save. 2015-05-11 21:22:37 -04:00
Derek Perkins 0eadc86d24 Added 2.0 alpha notes 2015-05-11 19:00:04 -06:00
Derek Perkins c7b117631b Merge pull request #1113 from tannerlinsley/deep-data
Deep data
2015-05-11 18:53:28 -06:00
Tanner Linsley 0e29cfdfda Bar attempt #5 2015-05-11 18:12:44 -06:00
Tanner Linsley cf07df07d6 Bar Attempt # 4 2015-05-08 16:20:21 -06:00
Evert Timberg 4e3dd8ae3f Merge pull request #1066 from tannerlinsley/add-stacked-area
Add StackedArea chart type to community extensions
2015-05-06 20:31:27 -04:00
Tanner Linsley 4b34bbadf9 Merge pull request #1098 from WouterSioen/fix-typo
Fix typo
2015-05-05 16:01:30 -06:00
Evert Timberg cc57b9e581 Merge pull request #1098 from WouterSioen/fix-typo
Fix typo
2015-05-05 14:39:35 -04:00
Wouter Sioen aad966820e Fix a typo: segment vs segement
Fix typo in PolarArea

Update 04-Polar-Area-Chart.md
2015-05-05 16:31:00 +02:00
William Entriken 5443886ec3 Merge pull request #1068 from nnnick/animation-refactory
Animation refactory
2015-05-04 15:55:59 -04:00
William Entriken a8063de6b8 Merge pull request #856 from tannerlinsley/editable-chart-config
Data now editable right from chart config
2015-05-04 15:28:03 -04:00
Evert Timberg e13ada2b43 Ensure that the bar draws to the correct spot 2015-05-02 15:03:40 -04:00
Evert Timberg 62b29282fd Fix a minor bug 2015-05-02 14:59:33 -04:00
Evert Timberg 2814c8e44c Remove Math.sign 2015-05-02 14:56:16 -04:00
William Entriken 7f513b87ee Merge pull request #952 from msmiley/patch-1
add datasetLabel for multiTooltip on dynamically-added points
2015-04-24 16:32:24 -04:00
William Entriken a3d4bc0bfe Merge pull request #851 from jtblin/master
Fix #507 - calculate container width and heigh without padding
2015-04-24 10:28:29 -04:00
Evert Timberg e67d198e69 Create a getBarAtEvent function that returns the single bar that was clicked on 2015-04-18 09:56:40 -04:00
Evert Timberg b5692c8534 Merge pull request #1069 from mackuba/fix_endpoint
Prevent taking vertical space for X labels more than once
2015-04-17 06:33:42 -04:00
Kuba Suder 2e311896ad prevent taking vertical space for x labels more than once
calculateXLabelRotation() subtracts space needed for x labels from
this.endPoint, but if this block is called more than once then the space
is subtracted more than once and the chart gets smaller and smaller with
every iteration
2015-04-16 22:23:17 +02:00
Tanner Linsley 8cc5be1212 Revert changes to build 2015-04-16 13:57:27 -06:00
William Entriken b0a780822a Merge pull request #1025 from pijey/feature/offsetgridlines-linechart
Add offsetGridLines option to Line charts
2015-04-16 15:27:43 -04:00
William Entriken a932442d26 Merge branch 'chasd00-piechart-redraw-after-zero-segment-values' 2015-04-16 15:17:36 -04:00
William Entriken 889c9de779 Merge #756 Fixes #661 2015-04-16 15:17:28 -04:00
Tanner Linsley e69aa04918 Add StackedArea chart type to community extensions 2015-04-16 00:50:08 -06:00
Nick Downie c7f52f516c Derped HTML attributes. 2015-04-13 16:35:14 +01:00
Nick Downie 8c641d21d8 Merge pull request #1062 from dima117/patch-1
Update 06-Advanced.md
2015-04-13 16:32:41 +01:00
dima117 9605409838 Update 06-Advanced.md
https://github.com/nnnick/Chart.js/issues/1060
2015-04-13 15:39:44 +03:00
Evert Timberg 604d6bd4e3 Merge pull request #677 from rylanhalteman/fix-yLabel-padding
add 10 to yLabelWidth on set, rather than on use
2015-04-12 08:06:23 -04:00
Tanner Linsley 14f4fae786 Only start digest on first request. Cleanup 2015-04-12 00:05:31 -06:00
Evert Timberg c476db0dd7 Use findNextWhere correctly. 2015-04-11 23:05:05 -04:00
Evert Timberg 0a5f92a854 Remove the minAnimationSteps option since we did not end up needing it. 2015-04-11 21:11:49 -04:00
Evert Timberg b1cbf04f25 Remove the unused lastTimeRun from the animation service 2015-04-11 20:47:35 -04:00
Tanner Linsley 70b8bf106c Always execute last frame 2015-04-11 18:42:11 -06:00
Tanner Linsley 99bf85e913 Merge remote-tracking branch 'origin/animation-refactory' into animation-refactory
Conflicts:
	src/Chart.Core.js
2015-04-11 18:37:01 -06:00
Tanner Linsley e0c208be58 Frame Dropper 2015-04-11 18:34:06 -06:00
Evert Timberg 26eca23706 Implement cancel animation frame in the animation service 2015-04-11 20:17:46 -04:00
Evert Timberg 98253fea5d Fix some bugs in the animation stuff 2015-04-11 20:08:17 -04:00
Evert Timberg 9a13dd78fc Fix a typo 2015-04-11 19:42:54 -04:00
Evert Timberg 3e59438646 Integrate animation service with chart 2015-04-11 19:33:20 -04:00
Tanner Linsley 7a6f2b4f06 Src changes... derrrr 2015-04-11 17:30:06 -06:00
Tanner Linsley a417dd00c5 Merge pull request #1058 from tannerlinsley/animation-refactory
Chart.AnimationService
2015-04-11 17:23:59 -06:00
Tanner Linsley eee5af5924 Chart.AnimationService 2015-04-11 17:19:29 -06:00
Evert Timberg d3579334b2 Add an option to control the minimum number of animation steps. 2015-04-11 19:17:30 -04:00
Evert Timberg 0b8fd966ff Chart animations will now use the animation service provided in Chart.animationService. 2015-04-11 19:02:50 -04:00
Evert Timberg 972bc5636d Merge pull request #711 from cmweiss/master
Default color for Doughnut/Pie
2015-04-09 11:25:45 -04:00
Evert Timberg 44ed661e3b Merge pull request #1036 from dima117/master
helpers.generateLabels throws exception #1035
2015-04-01 18:04:12 -04:00
dima117 4009dbd6a0 helpers.generateLabels throws "labelTemplateString is not defined" exception #1035 2015-03-31 22:06:41 +03:00
pijey 2677360f4b Add offsetGridLines option to Line charts 2015-03-25 11:51:56 +01:00
Evert Timberg e461788b2b Merge pull request #1022 from GitGal/master
Added possible animation effects to getting started guide
2015-03-24 19:17:06 -04:00
GitGal f7ed97a33e Update 00-Getting-Started.md
Move Possible effects list above animationEasing
2015-03-24 18:17:41 +01:00
gitgal fc0434b3da add all possible easing animations to 00-Getting-Started.md 2015-03-24 18:07:35 +01:00
Nick Downie 1408c68205 Merge pull request #1005 from zymiboxpay/master
fix custom build bug
2015-03-18 11:38:15 +00:00
zymiboxpay 53bc8e769f fix custom build bug 2015-03-18 16:26:17 +08:00
Evert Timberg b5f73e2087 Merge pull request #1002 from nnnick/fix/issue927
fixes #927
2015-03-17 10:59:49 -04:00
William Entriken cb113c6452 fixes #927 2015-03-17 10:12:01 -04:00
William Entriken 8e5f1d9667 Merge pull request #575 from msrocka/master
fix #570: getDecimalPlaces throws error
2015-03-17 09:28:54 -04:00
William Entriken 47d23601b1 Fix CodeClimate issues 2015-03-16 19:14:36 -04:00
William Entriken 212d513746 Merge pull request #999 from mbrevda/unattachedElement
Properly size unattached canvas
2015-03-16 10:22:39 -04:00
Moshe Brevda 3e6883bdc0 Use default canvas size if one cannot be intelligently procured 2015-03-16 13:58:09 +02:00
Evert Timberg ae7552a916 Draw bar chart negative values down from the 0 point of the scale. If all values are negative, draw down from the top. Updated the sample file to allow for negative bars. 2015-03-15 16:04:55 -04:00
Nick Downie 930b16a0af Versioned release files 2015-03-10 11:04:30 +00:00
Nick Downie 78d9627e4d Bump bower/package versions 2015-03-10 11:03:30 +00:00
Nick Downie 785f0b64b7 Merge pull request #983 from nnnick/release/v1.0.2
Release 1.0.2
2015-03-09 18:41:53 +00:00
Nick Downie d2b73bdc5b Release 1.0.2 2015-03-09 18:37:37 +00:00
Nick Downie 4b120ccbe9 Merge pull request #982 from nnnick/fix/automatic-chart-size-src
Target src files from #142
2015-03-09 17:20:29 +00:00
Nick Downie 1fd52e702c Merge pull request #981 from nnnick/fix/cancel-anim-frame
Ensure cancelAnimFrame has no function context
2015-03-09 17:16:15 +00:00
Nick Downie de564326b0 Target src files from #142 2015-03-09 17:14:09 +00:00
Nick Downie 154ce016cc Ensure cancelAnimFrame has no function context 2015-03-09 17:05:20 +00:00
Evert Timberg 5d8df20b0d Merge pull request #962 from steaks/removeUnecessaryComment
Removed an unnecessary comment
2015-03-02 11:39:28 -05:00
Steven Wexler 24248120a9 Removed an unnecessary comment 2015-03-01 20:31:44 -05:00
Jake 019e985c8f Merge pull request #898 from etimberg/fix/line_chart_single_label
Fix a divide by 0 error when there is only 1 label
2015-02-24 15:00:53 -05:00
Mike Smiley ff493738a2 add datasetLabel for multiTooltip on dynamically-added points 2015-02-24 14:19:01 -05:00
Nick Downie 5ea265983e Merge pull request #931 from jtibble/master
Removed trailing comma
2015-02-11 00:09:58 +00:00
John Tibble c09cac1cdd Removed trailing comma
Automated scan at my place of employment caught this trailing comma
2015-02-10 16:13:03 -05:00
William Entriken afd2631728 Merge pull request #917 from nnnick/fix-915
Fixes #915
2015-02-04 11:51:14 -05:00
William Entriken 4b09072c2a Fixes #915 2015-02-03 14:09:17 -05:00
William Entriken b865fd317a Fixes #901 2015-02-02 16:56:43 -05:00
Christopher Weiss bb6237a15e Accidentally left in Array.prototype.map. 2015-01-30 11:12:08 -05:00
Christopher Weiss b8b7c85c5e Using helper.each instead of Array.prototype.map 2015-01-30 11:01:44 -05:00
Jake 5ec66308e4 Update .travis.yml 2015-01-29 21:43:02 -05:00
William Entriken 9c6a7397b5 Merge pull request #867 from bendxn/master
Doughnut charts handling negative values
2015-01-29 16:54:45 -05:00
Evert Timberg 87b7f8070a Merge pull request #889 from bjornarg/cancelanimframe-fix
Fix issue with "Illegal invocation" in cancelAnimFrame.
2015-01-28 17:55:47 -05:00
Jake 2d28075cde ADD GH PR guidelines 2015-01-28 14:22:28 -05:00
Evert Timberg 2e0211320b Fix a divide by 0 error when there is only 1 label 2015-01-27 18:31:03 -05:00
William Entriken 8244dd1271 Merge pull request #551 from mparramont/patch-1
Fix global config multiTooltipTemplate comment
2015-01-27 14:04:10 -05:00
William Entriken 654e02763f Merge pull request #553 from johnheroy/master
Documentation: change lineColor to strokeColor for the first 3 example charts
2015-01-27 14:03:13 -05:00
William Entriken 0c1c9824b2 Merge pull request #694 from spmjs/master
Add spm support
2015-01-27 13:48:47 -05:00
William Entriken 63b14dde15 Clean up PR process 2015-01-27 13:35:30 -05:00
Bjørnar Grip Fjær 6f6f80e6d7 Fix issue with "Illegal invocation" in cancelAnimFrame. 2015-01-27 19:14:00 +01:00
Ben Dixon 13396c72b3 Merge remote-tracking branch 'upstream/master' 2015-01-26 18:49:17 -06:00
Evert Timberg a5550cef6b Merge pull request #142 from JonRowe/automatically_size_chart
Automatically size charts based upon the canvas size.
2015-01-26 18:55:49 -05:00
Christopher Weiss 0f49be56a4 Update 05-Pie-Doughnut-Chart.md 2015-01-26 16:33:24 -05:00
Christopher Weiss b9776736d4 Removed custom hue(), using hsl() 2015-01-26 16:28:11 -05:00
Jon Rowe 9ab36291a9 force calculated width/heights back to context, for firefox compatibility 2015-01-26 20:15:04 +11:00
Jon Rowe 657e53c117 make charts dependent on calculated width 2015-01-26 20:15:04 +11:00
Evert Timberg dc2ebab883 Merge pull request #890 from jakesyl/master
Update CONTRIBUTING.md
2015-01-25 21:29:22 -05:00
Jake 82571710c6 Update CONTRIBUTING.md 2015-01-25 20:48:33 -05:00
William Entriken 06adbb0c54 Merge pull request #703 from etimberg/fix/polar_area_update
Ensure that scales for polar area graphs are regenerated on updates.
2015-01-23 15:15:58 -05:00
Ben Dixon d051dfe47f handling negative values in doughnut charts 2015-01-15 13:40:08 -06:00
Ben Dixon 06b02e9c33 Revert "doughnut charts handling negative values"
This reverts commit 8b3a98f242.
2015-01-15 13:38:20 -06:00
Ben Dixon 8b3a98f242 doughnut charts handling negative values 2015-01-15 13:31:54 -06:00
Tanner Linsley 026611110a Updated Samples
Samples now include a “Randomize Data” button which utilizes the latest
changes.
2015-01-08 10:13:14 -07:00
William Entriken 092b011f9b formatting 2015-01-08 09:40:54 -05:00
William Entriken 8a027f49a4 typo 2015-01-08 09:39:49 -05:00
Tanner Linsley 359e94151c Data editable from chart config 2015-01-07 21:45:50 -07:00
Nick Downie 02f858b264 1.0.1 release builds 2015-01-07 22:49:33 +00:00
Nick Downie bdb49e6396 Merge pull request #611 from fntneves/feature/toggle-grid-lines
Add option to toggle grid vertical/horizontal lines
2015-01-07 22:44:59 +00:00
Nick Downie 05dbcd3a72 Merge pull request #840 from tannerlinsley/master
External Tooltips, Documentation and Samples
2015-01-07 22:44:02 +00:00
Tanner Linsley 64de3eb711 externalTooltips now labeled customTooltips 2015-01-06 22:53:30 -07:00
Evert Timberg 854cebc59c Merge pull request #855 from nnnick/fix/reset-canvas
Restore original canvas context when destroying
2015-01-06 19:17:01 -05:00
Nick Downie 74c9ef50c2 Space between status badges 2015-01-07 00:07:06 +00:00
Nick Downie 85f3755f9a Restore original canvas context when destroying 2015-01-06 23:44:51 +00:00
Jake 7aa867cf24 Merge pull request #850 from jakesyl/master
Increment Copyright Year
2015-01-04 17:14:15 -05:00
Jake 5d4e7cebea Update Chart.Core.js 2015-01-04 17:12:58 -05:00
William Entriken ed3e47f560 Merge pull request #846 from nnnick/fix/ci-builds
Fix Travis builds
2015-01-03 23:00:53 -05:00
Nick Downie d48979526f Merge pull request #842 from nnnick/fix/contributing-guidelines
Rewrite contributing guidelines
2015-01-03 17:26:21 +00:00
Nick Downie 329ad3cdce Remove checking .min file in CI 2015-01-03 17:19:28 +00:00
Nick Downie 84e859b6c5 Remove email notifications 2015-01-03 15:49:58 +00:00
Nick Downie 81d4f97abc Remove unnecessary semicolons 2015-01-03 15:40:47 +00:00
Nick Downie 2e4bb1899f Fix mixed whitespace 2015-01-03 15:40:33 +00:00
Nick Downie c9878b8434 Add Stack Overflow tag link to README 2015-01-03 15:30:58 +00:00
Jake 453310a338 Merge pull request #844 from jakesyl/master
move build status next to code climate button
2015-01-02 22:57:33 -05:00
Jake 9af5d0c9d6 move build status next to code climate 2015-01-02 22:56:58 -05:00
Nick Downie 7626dcf14e Link to contributing guide from readme 2015-01-01 23:49:10 +00:00
Nick Downie b4df89fcd1 Bump copyright year in license 2015-01-01 23:46:02 +00:00
Nick Downie 8c41c5c1b7 Rewrite contributing guidelines 2015-01-01 23:45:52 +00:00
William Entriken cfc4599a30 Add Travis CI support 2015-01-01 12:57:21 -05:00
Tanner Linsley 8c1e9588a1 External Tooltips, Documentation, and Samples 2014-12-30 13:05:11 -07:00
Jake 70c3672963 Merge pull request #841 from jakesyl/codeclimate
Move Code Climate Badge
2014-12-30 14:25:23 -05:00
Jake f4a5f67f7c Move Code Climate Badge 2014-12-30 14:24:55 -05:00
Jake 80e972c351 Delete dev instruction
@nnnick will rewrite this
2014-12-30 14:03:40 -05:00
Jake d320ce6eaf Merge pull request #750 from CAYdenberg/nnnick
Added link to CAYdenberg/Chart.js
2014-12-29 17:21:59 -05:00
Jake 7e97aa3300 Update CONTRIBUTING.md 2014-12-29 16:18:44 -05:00
Jake 102c069d74 Update CONTRIBUTING.md 2014-12-29 15:56:52 -05:00
Jake d8353c2b9a Update CONTRIBUTING.md 2014-12-29 15:55:17 -05:00
Nick Downie 932908532c Merge pull request #650 from fulldecent/patch-2
[CONTROVERSIAL] Update scope: new chart types are off topic
2014-12-29 20:42:54 +00:00
William Entriken 718dcd1a2b Merge pull request #5 from fulldecent/origin/patch-2
Origin/patch 2
2014-12-29 15:41:39 -05:00
William Entriken f81d6f45e1 Update readme about where to put new chart types 2014-12-29 15:40:09 -05:00
William Entriken 8522d4e60e Update to have new chart types in external repos 2014-12-29 15:38:03 -05:00
Jake 211850add2 Merge pull request #810 from Winnetou/patch-1
Minor typos
2014-12-29 15:12:33 -05:00
Derek Perkins aa96a3f33a Merge pull request #834 from jakesyl/patch-1
Add Code Climate Integration
2014-12-29 13:09:43 -07:00
Jake ac05a62000 Add Code Climate Integration 2014-12-28 22:18:55 -05:00
Mieszko f18b7ebd57 Minor typos 2014-12-09 11:11:49 +01:00
chad a7712e8c71 prevent divide by zero error when calculating a circumference 2014-11-13 11:36:13 -06:00
Casey Ydenberg 71bf3c8ee5 Added link to CAYdenberg/Chart.js 2014-11-11 15:11:30 -07:00
Jerome Touffe-Blin 1900c3b0f3 Fix #507 - calculate container width and heigh without padding 2014-10-25 13:21:52 +11:00
Christopher Weiss 73faf3413b Update Chart.Doughnut.js 2014-10-21 13:32:45 -04:00
Christopher Weiss fdc9be3e23 Correction in algorithm. 2014-10-21 13:28:45 -04:00
Christopher Weiss 7e21cb4e04 Pointed to core and doughnut. 2014-10-21 10:19:58 -04:00
Christopher Weiss 8984e8c2c4 Create doughnut.color.html
To test the new version of doughnut.
2014-10-21 10:16:30 -04:00
Christopher Weiss 686ea49953 Hue uses switch & fixed other problems. 2014-10-21 10:08:54 -04:00
Christopher Weiss ae9eaa95c7 hue() complete but undebugged. 2014-10-20 22:18:50 -04:00
Christopher Weiss e21147cbb9 Prototype for hue() & default fillColor to use it. 2014-10-20 21:49:41 -04:00
Evert Timberg 98c1ac439d Ensure that scales for polar area graphs are regenerated on updates. 2014-10-19 20:04:21 -04:00
chencheng 337511110c Add spm support 2014-10-15 17:28:50 +08:00
Rylan Halteman 5ab5e8400a add 10 to yLabelWidth on set, rather than on use 2014-10-08 11:36:39 -04:00
William Entriken 7eabb70130 Add strict language to README. 2014-10-01 12:18:47 -04:00
William Entriken ae65fde3e9 [CONTROVERSIAL] Update scope: new chart types are off topic 2014-09-26 12:37:51 -04:00
John Heroy 27a121c6b2 Change 'strokeColor' to 'fillColor' on 02-Bar-Chart.md 2014-09-25 09:49:20 -07:00
Nick Downie 1cfa42bc24 Merge pull request #627 from fulldecent/patch-2
Separate CONTRIBUTING.md, see https://github.com/blog/1184-contributing-...
2014-09-17 15:04:30 +01:00
William Entriken 401ff95867 move contributing to CONTRIBUTING.md, helps with NEW ISSUES 2014-09-15 12:16:31 -04:00
William Entriken ccc85c80d1 Separate CONTRIBUTING.md, see https://github.com/blog/1184-contributing-guidelines 2014-09-15 12:15:34 -04:00
Nick Downie 61b525a645 Merge pull request #606 from fulldecent/patch-1
Use canonical docs url
2014-09-10 16:32:57 +01:00
Francisco Neves a406fdae58 Update docs for toggle Horizontal/Vertical Lines feature 2014-09-08 17:49:19 +01:00
Francisco Neves a3daf1ca24 Add option to toggle grid vertical/horizontal lines 2014-09-08 16:10:45 +01:00
William Entriken 2ef91b1c78 Use canonical docs url 2014-09-04 13:48:37 -04:00
msrocka 5282c63ec3 fix #570: getDecimalPlaces throws error 2014-08-25 13:29:22 +02:00
Nick Downie 0a59a3c4df Merge pull request #560 from chandruxp/master
Fix for Almond AMD
2014-08-20 22:47:21 +01:00
chandruxp 47cf4f4814 Fix for Almond AMD 2014-08-20 15:20:46 -04:00
John Heroy e6cbd9dc7f Change lineColor to strokeColor in legendTemplate for Line, Bar, and Radar charts 2014-08-19 22:42:39 +08:00
Miguel Parramon f825a31ce4 Fix global config multiTooltipTemplate comment 2014-08-19 13:19:37 +02:00
chandruxp 53c4cd5ce1 Fix for Almond AMD 2014-08-18 18:52:50 -04:00
Nick Downie 8b840ce56b Pre-release version bump to beta.4 2014-08-17 23:21:11 +01:00
Nick Downie 7eec283d70 Merge pull request #435 from nnnick/fix/sparse-datasets
Resolve issues with sparse datasets & solve bezier capping to scale bounds
2014-08-17 23:18:42 +01:00
Nick Downie 10a9ef46cb Add in extra bezier debug point 2014-08-17 23:14:30 +01:00
Nick Downie 179d80a93b Cap bezier handles inside the scale 2014-08-17 22:32:36 +01:00
Nick Downie 48f10196f6 Use null checking for which points to draw/bezier 2014-08-03 19:20:31 +01:00
Nick Downie bd25b5c7fd New methods for array finding 2014-08-03 19:19:54 +01:00
Nick Downie 09c0f3308c Whitespace cleanup 2014-08-03 16:39:04 +01:00
Nick Downie 30777e4a87 Merge branch 'master' into fix/sparse-datasets
Conflicts:
	Chart.min.js
2014-08-03 16:05:34 +01:00
Nick Downie 14e72759ee Merge pull request #331 from kara/patch-1
Update copyright year in license to 2014
2014-07-27 23:27:32 +01:00
Nick Downie d47e600f1a Docs note on maintain aspect ratio option 2014-07-27 23:12:03 +01:00
Nick Downie 5bd10297fb Update built output 2014-07-27 23:03:32 +01:00
Nick Downie 55a115179e Fix reference error when tagging a release 2014-07-27 23:02:30 +01:00
Nick Downie 92e73bd28a Merge pull request #490 from nnnick/feature/version-bump
Create a task to bump + write version numbers
2014-07-27 22:59:14 +01:00
Nick Downie ebc955f562 Merge pull request #431 from Mardaneus86/patch-1
Missing draw method in Writing new chart types
2014-07-27 22:58:55 +01:00
Nick Downie 5683c11ebd Merge pull request #438 from Miosss/templateEnchanceme
Alternative scale templating. Passing function as template.
2014-07-27 22:58:06 +01:00
Nick Downie 61467e107f Merge pull request #443 from andyburke/aspectratios
Allow for responsive chart to take up its entire container.
2014-07-27 22:57:29 +01:00
Nick Downie adf6f3abb2 Create a task to bump + write version numbers
Also run `gulp release` to tag the latest release.
2014-07-27 21:41:49 +01:00
Nick Downie 22c50b0aba Merge pull request #460 from ooflorent/fix/npm-package
Add main in package.json
2014-07-17 10:02:01 +01:00
Florent Cailhol edb245b649 Add main file 2014-07-17 09:42:16 +02:00
Andy Burke 16cf465575 Add a small amount to docs. 2014-07-10 17:47:02 -07:00
Andy Burke 997a216b50 Allow for responsive charts to take up entire container by setting responsive: true and maintainAspectRatio: false. 2014-07-10 17:45:17 -07:00
Miosss d193951dc5 Alternative templating, cleanup.
Just added brackets.
2014-07-10 13:13:38 +02:00
Miosss c37c58ad39 Alternative scale templating. Passing function as template.
Allows to choose template mechanism - processing function or original micro templating.
2014-07-09 14:57:08 +02:00
Nick Downie 529d582f03 Built output 2014-07-08 23:13:29 +01:00
Nick Downie aa7975e4f7 Allow radar charts sparse data 2014-07-08 22:59:50 +01:00
Nick Downie fdfa9912e8 Refactor logic into shared Element method 2014-07-08 22:44:55 +01:00
Nick Downie 2f59921f7a Make a start on sparse data for line charts 2014-07-08 22:40:32 +01:00
Nick Downie e25fd5e37c Create null value bars, and hide if not numeric 2014-07-08 22:27:39 +01:00
Nick Downie 5d0171e8ed Check MultiTooltip elements are numeric 2014-07-08 22:19:36 +01:00
Nick Downie 55fc0cfd49 Change package.json name to lowercase 2014-07-08 21:45:56 +01:00
Tim Klingeleers cdfdc3c3e2 Missing draw method in Writing new chart types
Added the draw method to "Writing new chart types". If you use the template without the draw method, you get an undefined error because Chart.Type.prototype.render calls this.draw() on line 808 in Chart.Core.js.
2014-07-08 13:15:23 +02:00
Nick Downie ef5081184f Community chart types / extensions list 2014-07-06 22:59:57 +01:00
Nick Downie 02e535cdad Update bower & package.json with version bump
Forget this literally every time…
2014-07-02 21:51:31 +01:00
Nick Downie 3e1b120cbe Build latest output files for new version 2014-07-02 21:42:10 +01:00
Nick Downie 95844701bd Mention not committing built files in README.md 2014-07-02 21:39:44 +01:00
Nick Downie 403b6751ab Change case of README file 2014-07-02 21:38:14 +01:00
Nick Downie 2b81ac832a Merge pull request #415 from nnnick/fix/radar-chart-scale-updates
Reflow the Radar before updating to update scale
2014-07-02 21:36:51 +01:00
Nick Downie 3f9e5ab7a2 Merge pull request #414 from nnnick/feature/dataset-label-tooltip
Add datasetLabel to elements for tooltip templates
2014-07-02 21:36:39 +01:00
Nick Downie 23deaa9307 Merge pull request #413 from nnnick/fix/sparse-dataset-tooltip
Prevent spare datasets from breaking MultiTooltips
2014-07-02 21:36:28 +01:00
Nick Downie 2183d09b58 Merge pull request #409 from BrettBukowski/commonjs
Add support for CommonJS module definition
2014-07-02 21:36:17 +01:00
Nick Downie ea9d144c71 Reflow the Radar before updating to update scale 2014-07-02 21:28:59 +01:00
Nick Downie 7a23131366 Add datasetLabel to elements for tooltip templates 2014-07-02 21:27:03 +01:00
Nick Downie d7632efe65 Prevent spare datasets from breaking MultiTooltips 2014-07-02 21:09:04 +01:00
Brett Bukowski 477e09f1d4 Add support for CommonJS module definition 2014-07-01 15:39:28 -06:00
Nick Downie 641fc02212 1.0.1-beta Update for bower/package.json 2014-07-01 11:02:28 +01:00
Nick Downie a55fdaad57 Merge pull request #402 from nnnick/fix/point-dot-option
Fix option for pointDot not being obeyed
2014-06-30 22:12:27 +01:00
Nick Downie d006558e69 Merge pull request #392 from jbrooksuk/doc-update
Make javascript JavaScript and Github GitHub
2014-06-30 22:02:33 +01:00
Nick Downie 29ae3200a7 Default display of chart point to true 2014-06-30 21:54:24 +01:00
Nick Downie 38d1b87e1c Adhere to pointDot option in config
- Added `display` property on Point classes, to determine whether the
draw sequence should run or not.
2014-06-30 20:24:47 +01:00
James Brooks e139ab8596 Make javascript JavaScript and Github GitHub 2014-06-30 11:50:35 +01:00
Nick Downie 28dd492460 Extending chart types docs typo error 2014-06-30 10:04:01 +01:00
Nick Downie f13f99b7d7 Merge pull request #388 from nnnick/v1-dev
Version 1.0.0-beta release
2014-06-29 19:18:23 +01:00
Nick Downie 8533c27031 Update readme 2014-06-29 18:37:39 +01:00
Nick Downie 0e5f4ec32f Bump bower version 2014-06-29 18:37:29 +01:00
Nick Downie e24efd23a2 Add build sequence + dev dependencies 2014-06-29 18:37:07 +01:00
Nick Downie 10227f852b Add src & built library files 2014-06-29 18:36:25 +01:00
Nick Downie 94f22b656e Add in new chart samples 2014-06-29 18:36:04 +01:00
Nick Downie dc6d5bc934 Add new docs as markdown files 2014-06-29 18:35:49 +01:00
Nick Downie a04082dba1 Remove site from repo 2014-06-29 17:38:59 +01:00
Nick Downie be2f31a351 Change to bower.json 2014-06-29 17:35:35 +01:00
Nick Downie 7d240eee9d Update ignored files 2014-06-29 17:34:56 +01:00
Kara 0a6c892766 Update copyright year in license to include 2014 2014-03-09 16:30:27 -07:00
Kara 51032692f3 Update copyright year in license to 2014 2014-03-09 16:19:18 -07:00
101 arquivos alterados com 22705 adições e 8129 exclusões
+9
Ver Arquivo
@@ -1,2 +1,11 @@
.DS_Store
node_modules/*
custom/*
docs/index.md
bower_components/
coverage/*
+13
Ver Arquivo
@@ -0,0 +1,13 @@
language: node_js
node_js:
- "0.11"
- "0.10"
before_script:
- npm install
script:
- gulp test
notifications:
slack: chartjs:pcfCZR6ugg5TEcaLtmIfQYuA
+55
Ver Arquivo
@@ -0,0 +1,55 @@
Contributing to Chart.js
========================
Contributions to Chart.js are welcome and encouraged, but please have a look through the guidelines in this document before raising an issue, or writing code for the project.
Using issues
------------
The [issue tracker](https://github.com/nnnick/Chart.js/issues) is the preferred channel for reporting bugs, requesting new features and submitting pull requests.
If you're suggesting a new chart type, please take a look at [writing new chart types](https://github.com/nnnick/Chart.js/blob/master/docs/06-Advanced.md#writing-new-chart-types) in the documentation, and some of the [community extensions](https://github.com/nnnick/Chart.js/blob/master/docs/06-Advanced.md#community-extensions) that have been created already.
To keep the library lightweight for everyone, it's unlikely we'll add many more chart types to the core of Chart.js, but issues are a good medium to design and spec out how new chart types could work and look.
Please do not use issues for support requests. For help using Chart.js, please take a look at the [`chartjs`](http://stackoverflow.com/questions/tagged/chartjs) tag on Stack Overflow.
Reporting bugs
--------------
Well structured, detailed bug reports are hugely valuable for the project.
Guidlines for reporting bugs:
- Check the issue search to see if it has already been reported
- Isolate the problem to a simple test case
- Provide a demonstration of the problem on [JS Bin](http://jsbin.com) or similar
Please provide any additional details associated with the bug, if it's browser or screen density specific, or only happens with a certain configuration or data.
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.
Guidlines:
- Please create an issue first:
- For bugs, we can discuss the fixing approach
- For enhancements, we can discuss if it is within the project scope and avoid duplicate effort
- Please make changes to the files in [`/src`](https://github.com/nnnick/Chart.js/tree/master/src), not `Chart.js` or `Chart.min.js` in the repo root directory, this avoids merge conflicts
- Tabs for indentation, not spaces please
- 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
-------------
- 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.
License
-------
By contributing your code, you agree to license your contribution under the [MIT license](https://github.com/nnnick/Chart.js/blob/master/LICENSE.md).
externo Arquivo executável → Arquivo normal
+5776 -1372
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+39 -39
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
Copyright (c) 2013 Nick Downie
Copyright (c) 2013-2015 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:
+21
Ver Arquivo
@@ -0,0 +1,21 @@
# 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)
# Version 2.0 is in early alpha. We are changing the internal data model to reduce copying, increase performance and expose a more flexible API.
*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)
## 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
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.
For support using Chart.js, please post questions with the [`chartjs` tag on Stack Overflow](http://stackoverflow.com/questions/tagged/chartjs).
## License
Chart.js is available under the [MIT license](http://opensource.org/licenses/MIT).
+13
Ver Arquivo
@@ -0,0 +1,13 @@
{
"name": "Chart.js",
"version": "2.0.0-alpha",
"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"
}
}
-11
Ver Arquivo
@@ -1,11 +0,0 @@
{
"name": "Chart.js",
"version": "0.2.0",
"description": "Simple HTML5 Charts using the canvas element",
"keywords": ["charts"],
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"main": ["Chart.min.js"],
"dependencies": {
}
}
+191
Ver Arquivo
@@ -0,0 +1,191 @@
---
title: Getting started
anchor: getting-started
---
###Include Chart.js
First we need to include the Chart.js library on the page. The library occupies a global variable of `Chart`.
```html
<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.
```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
// 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:
```bash
bower install Chart.js --save
```
```bash
npm install Chart.js --save
```
https://cdnjs.com/libraries/chart.js
###Creating a chart
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.
```html
<canvas id="myChart" width="400" height="400"></canvas>
```
```javascript
// Any of the following formats may be used
var ctx = document.getElementById("myChart");
var ctx = document.getElementById("myChart").getContext("2d");
var ctx = $("myChart");
```
Once you have the element or context, you're ready to instantiate a pre-defined chart-type or create your own!
The following example instantiates a the pre-defined Polar Area chart type with a config object of data and options.
```javascript
var myNewChart = Chart.PolarArea(ctx, {
data: data,
options: options
});
```
To create a scatter chart, which is a special configuration of a line chart, we use the following.
```javascript
var myScatterChart = Chart.Scatter(ctx, {
data: data,
options: options
});
```
Alternatively, we can use the more advanced API to create simple or advanced chart types. In the example below, we are creating a line chart.
```javascript
var myChart = new Chart(ctx, {
type: 'line', // built in types are 'line', 'bar', 'radar', 'polarArea', 'doughnut', 'scatter'
data: data,
options: options
});
```
###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.
```javascript
Chart.defaults.global = {
responsive: true,
responsiveAnimationDuration: 0,
maintainAspectRatio: true,
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"],
hover: {
onHover: null,
mode: 'single',
animationDuration: 400,
},
onClick: null,
defaultColor: 'rgba(0,0,0,0.1)',
// Element defaults defined in element extensions
elements: {},
// Legend template string
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i = 0; i < data.datasets.length; i++){%><li><span style=\"background-color:<%=data.datasets[i].backgroundColor%>\"><%if(data.datasets[i].label){%><%=data.datasets[i].label%><%}%></span></li><%}%></ul>",
animation: {
duration: 1000,
easing: "easeOutQuart",
onProgress: function() {},
onComplete: function() {},
},
tooltips:{
enabled: true,
custom: null,
backgroundColor: "rgba(0,0,0,0.8)",
fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
fontSize: 10,
fontStyle: "normal",
fontColor: "#fff",
titleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
titleFontSize: 12,
titleFontStyle: "bold",
titleFontColor: "#fff",
yPadding: 6,
xPadding: 6,
caretSize: 8,
cornerRadius: 6,
xOffset: 10,
template: [
'<% if(label){ %>',
'<%=label %>: ',
'<% } %>',
'<%=value %>',
].join(''),
multiTemplate: [
'<%if (datasetLabel){ %>',
'<%=datasetLabel %>: ',
'<% } %>',
'<%=value %>'
].join(''),
multiKeyBackground: '#fff',
},
elements: {
arc: {
backgroundColor: Chart.defaults.global.defaultColor,
borderColor: "#fff",
borderWidth: 2
},
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
skipNull: true,
drawNull: false,
},
point: {
radius: 3,
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
// Hover
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
},
rectangle: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 0,
borderColor: Chart.defaults.global.defaultColor,
}
}
}
```
If for example, you wanted all charts created to be responsive, and resize when the browser window does, the following setting can be changed:
```javascript
Chart.defaults.global.responsive = true;
```
Now, every time we create a chart, `options.responsive` will be `true`.
+227
Ver Arquivo
@@ -0,0 +1,227 @@
---
title: Getting started
anchor: getting-started
---
###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 labels
Every scale extends a core scale class with the following options:
```javascript
Chart.defaults.scale = {
display: true,
// grid line settings
gridLines: {
show: 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
show: false,
},
// label settings
ticks: {
beginAtZero: false,
fontSize: 12,
fontStyle: "normal",
fontColor: "#666",
fontFamily: "Helvetica Neue",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%=value%>",
userCallback: false,
},
};
```
The `userCallback` 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",
}
```
#### 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: {
template: "<%var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));if (remain === 1 || remain === 2 || remain === 5) {%><%=value.toExponential()%><%} else {%><%= null %><%}%>",
}
}
```
#### 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,
// string - By default, is set to the detected (or manually overridden) time unit's `display` property (see supported time measurements). To override, use a pattern string from http://momentjs.com/docs/#/displaying/format/
displayFormat: false
},
}
```
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: {
show: 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",
},
}
```
+212
Ver Arquivo
@@ -0,0 +1,212 @@
---
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,
// 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.
```javascript
{
// Boolean - if true, line stack on top of each other along the y axis
stacked: false,
hover: {
// String - We use a label hover mode since the x axis displays data by the index in the dataset
mode: "label"
},
scales: {
// Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options
xAxes: [{
// String - type of scale. Built in types are 'category' and 'linear'
type: 'category',
// String - id of the axis so that data can bind to it
id: "x-axis-1", // need an ID so datasets can reference the scale
}],
// Defines all of the y axes used in the chart.
// By default, the line chart uses a linear scale along the y axis
yAxes: [{
type: 'linear',
// String - ID of the axis for data binding
id: "y-axis-1",
}],
}
};
```
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: [{
show: 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
#### .getElementsAtEvent( event )
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.
#### .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
```
+283
Ver Arquivo
@@ -0,0 +1,283 @@
---
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: 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.
```javascript
{
// Boolean - if true, bars stack on top of each other
stacked: false,
hover: {
// String - We use a label hover mode since the x axis displays data by the index in the dataset
mode: "label"
},
scales: {
// 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.
xAxes: [{
// String - type of axis to use. Should not be changed from 'dataset'.
scaleType: "dataset", // scatter should not use a dataset axis
// Boolean - if true, show the scale
display: true,
// String - position of the scale. possible options are "top" and "bottom" for dataset scales
position: "bottom",
// String - id of the axis so that data can bind to it
id: "x-axis-1", // need an ID so datasets can reference the scale
// grid line settings
gridLines: {
// Boolean - if true, show the grid lines
show: true,
// String - color of the grid lines
color: "rgba(0, 0, 0, 0.05)",
// Number - width of the grid lines
lineWidth: 1,
// Boolean - if true draw lines on the chart area
drawOnChartArea: true,
// Boolean - if true draw ticks in the axis area
drawTicks: true,
// Number - width of the grid line for the first index (index 0)
zeroLineWidth: 1,
// String - color of the grid line for the first index
zeroLineColor: "rgba(0,0,0,0.25)",
// Boolean - if true, offset labels from grid lines
offsetGridLines: false,
},
// label settings
labels: {
// Boolean - if true show labels
show: true,
// String - template string for labels
template: "<%=value%>",
// Number - label font size
fontSize: 12,
// String - label font style
fontStyle: "normal",
// String - label font color
fontColor: "#666",
// String - label font family
fontFamily: "Helvetica Neue",
},
}],
yAxes: [{
// String - type of axis. 'linear' is the default but extensions may provide other types such as logarithmic
scaleType: "linear",
// Boolean - if true, show the scale
display: true,
// String - position of axis. Vertical axes can have either "left" or "right"
position: "left",
// ID of the axis for data binding
id: "y-axis-1",
// grid line settings
gridLines: {
// Boolean - if true, show the grid lines
show: true,
// String - color of the grid lines
color: "rgba(0, 0, 0, 0.05)",
// Number - width of the grid lines
lineWidth: 1,
// Boolean - if true draw lines on the chart area
drawOnChartArea: true,
// Boolean - if true draw ticks in the axis area
drawTicks: true,
// Number - width of the grid line representing a numerical value of 0
zeroLineWidth: 1,
// String - color of the grid line representing a numerical value of 0
zeroLineColor: "rgba(0,0,0,0.25)",
},
// Boolean - if true ensures that the scale always has a 0 point
beginAtZero: false,
// Object - if specified, allows the user to override the step generation algorithm.
// Contains the following values
// start: // number to start at
// stepWidth: // size of step
// steps: // number of steps
override: null,
// label settings
labels: {
// Boolean - if true show labels
show: true,
// String - template string for labels
template: "<%=value%>",
// Function - if specified this is passed the tick value, index, and the array of all tick values. Returns a string that is used as the label for that value
userCallback: null,
// Number - label font size
fontSize: 12,
// String - label font style
fontStyle: "normal",
// String - label font color
fontColor: "#666",
// String - label font family
fontFamily: "Helvetica Neue",
},
}],
},
};
```
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: data,
options: {
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
```
+177
Ver Arquivo
@@ -0,0 +1,177 @@
---
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,
//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%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></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%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></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.
```
+158
Ver Arquivo
@@ -0,0 +1,158 @@
---
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%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></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.
```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.
```
+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 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 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 seperated list of types as an argument to build a custom version of Chart.js with only specified chart types.
Here we will create a version of Chart.js with only Line, Radar and Bar charts included:
```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.
+42
Ver Arquivo
@@ -0,0 +1,42 @@
---
title: Notes
anchor: notes
---
### Browser support
Browser support for the canvas element is available in all modern & major mobile browsers <a href="http://caniuse.com/canvas" target="_blank">(caniuse.com/canvas)</a>.
For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at <a href="https://code.google.com/p/explorercanvas/" target="_blank">https://code.google.com/p/explorercanvas/</a>. It falls back to Internet explorer's format VML when canvas support is not available. Example use:
```html
<head>
<!--[if lte IE 8]>
<script src="excanvas.js"></script>
<![endif]-->
</head>
```
Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE.
Some important points to note in my experience using ExplorerCanvas as a fallback.
- Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas.
- New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent <a href="http://modernizr.com/" target="_blank">Modernizr</a> to do this.
- When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values.
### Bugs & issues
Please report these on the GitHub page - at <a href="https://github.com/nnnick/Chart.js" target="_blank">github.com/nnnick/Chart.js</a>. If you could include a link to a simple <a href="http://jsbin.com/" target="_blank">jsbin</a> or similar to demonstrate the issue, that'd be really helpful.
### Contributing
New contributions to the library are welcome, just a couple of guidelines:
- Tabs for indentation, not spaces please.
- Please ensure you're changing the individual files in `/src`, not the concatenated output in the `Chart.js` file in the root of the repo.
- Please check that your code will pass `jshint` code standards, `gulp jshint` will run this for you.
- Please keep pull requests concise, and document new functionality in the relevant `.md` file.
- Consider whether your changes are useful for all users, or if creating a Chart.js extension would be more appropriate.
### License
Chart.js is open source and available under the <a href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>.
-1443
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-766
Ver Arquivo
@@ -1,766 +0,0 @@
<!doctype html>
<html>
<head>
<title>Chart.js Documentation</title>
<link href="styles.css" rel="stylesheet">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="prettify.js"></script>
<script src="Chart.js"></script>
<script type="text/javascript" src="//use.typekit.net/puc1imu.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
</head>
<body>
<div class="redBorder"></div>
<div class="greenBorder"></div>
<div class="yellowBorder"></div>
<div id="wrapper">
<nav>
<dl>
</dl>
</nav>
<div id="contentWrapper">
<h1 id="mainHeader">Chart.js Documentation</h1>
<h2 id="introText">Everything you need to know to create great looking charts using Chart.js</h2>
<article id="gettingStarted">
<h1>Getting started</h1>
<h2>Include Chart.js</h2>
<p>First we need to include the Chart.js library on the page. The library occupies a global variable of <code>Chart</code>.</p>
<pre data-type="html"><code>&lt;script src=&quot;Chart.js&quot;&gt;&lt;/script&gt;</code></pre>
<h2>Creating a chart</h2>
<p>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.</p>
<pre data-type="html"><code>&lt;canvas id=&quot;myChart&quot; width=&quot;400&quot; height=&quot;400&quot;&gt;&lt;/canvas&gt;</code></pre>
<pre data-type="javascript"><code>//Get the context of the canvas element we want to select
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).PolarArea(data);</code></pre>
<p>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 <code>getContext("2d")</code> method on that.</p>
<pre data-type="javascript"><code>//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);</code></pre>
<p>After we've instantiated the Chart class on the canvas we want to draw on, Chart.js will handle the scaling for retina displays.</p>
<p>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.</p>
<pre data-type="javascript"><code>new Chart(ctx).PolarArea(data,options);</code></pre>
<p>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 options you pass in with the default options for that chart type.</p>
</article>
<article id="lineChart">
<h1>Line chart</h1>
<h2>Introduction</h2>
<p>A line chart is a way of plotting data points on a line.</p>
<p>Often, it is used to show trend data, and the comparison of two data sets.</p>
<h2>Example usage</h2>
<canvas id="line" data-type="Line" width="600" height="400"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).Line(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="line">var data = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}</code></pre>
<p>The line chart requires an array of labels for each of the data points. This is show on the X axis.</p>
<p>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.</p>
<h2>Chart options</h2>
<pre data-type="javascript"><code>Line.defaults = {
//Boolean - If we show the scale above the chart data
scaleOverlay : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : false,
//** 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,
//String - Colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth : 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels : true,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'Arial'",
//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 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 the line is curved between points
bezierCurve : true,
//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,
//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,
//Boolean - Whether to animate the chart
animation : true,
//Number - Number of animation steps
animationSteps : 60,
//String - Animation easing effect
animationEasing : "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete : null
}</code></pre>
</article>
<article id="barChart">
<h1>Bar chart</h1>
<h2>Introduction</h2>
<p>A bar chart is a way of showing data as bars.</p>
<p>It is sometimes used to show trend data, and the comparison of multiple data sets side by side.</p>
<h2>Example usage</h2>
<canvas id="bar" data-type="Bar" width="600" height="400"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).Bar(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="bar">var data = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [28,48,40,19,96,27,100]
}
]
}</code></pre>
<p>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.</p>
<p>We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.</p>
<h2>Chart options</h2>
<pre data-type="javascript"><code>Bar.defaults = {
//Boolean - If we show the scale above the chart data
scaleOverlay : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : false,
//** 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,
//String - Colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth : 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels : true,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'Arial'",
//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 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 - 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,
//Boolean - Whether to animate the chart
animation : true,
//Number - Number of animation steps
animationSteps : 60,
//String - Animation easing effect
animationEasing : "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete : null
}</code></pre>
</article>
<article id="radarChart">
<h1>Radar chart</h1>
<h2>Introduction</h2>
<p>A radar chart is a way of showing multiple data points and the variation between them.</p>
<p>They are often useful for comparing the points of two or more different data sets</p>
<h2>Example usage</h2>
<canvas id="radar" data-type="Radar" width="400" height="400"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).Radar(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="radar">var data = {
labels : ["Eating","Drinking","Sleeping","Designing","Coding","Partying","Running"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}</code></pre>
<p>For a radar chart, usually you will want to show a label on each point of the chart, so we include an array of strings that we show around each point in the chart. If you do not want this, you can either not include the array of labels, or choose to hide them in the chart options.</p>
<p>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.</p>
<h2>Chart options</h2>
<pre data-type="javascript"><code>Radar.defaults = {
//Boolean - If we show the scale above the chart data
scaleOverlay : false,
//Boolean - If we want to override with a hard coded scale
scaleOverride : false,
//** 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 centre starting value
scaleStartValue : null,
//Boolean - Whether to show lines for each scale point
scaleShowLine : true,
//String - Colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the scale line
scaleLineWidth : 1,
//Boolean - Whether to show labels on the scale
scaleShowLabels : false,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'Arial'",
//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 - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
//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 - Whether we show the angle lines out of the radar
angleShowLineOut : true,
//String - Colour of the angle line
angleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the angle line
angleLineWidth : 1,
//String - Point label font declaration
pointLabelFontFamily : "'Arial'",
//String - Point label font weight
pointLabelFontStyle : "normal",
//Number - Point label font size in pixels
pointLabelFontSize : 12,
//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,
//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,
//Boolean - Whether to animate the chart
animation : true,
//Number - Number of animation steps
animationSteps : 60,
//String - Animation easing effect
animationEasing : "easeOutQuart",
//Function - Fires when the animation is complete
onAnimationComplete : null
}</code></pre>
</article>
<article id="polarAreaChart">
<h1>Polar area chart</h1>
<h2>Introduction</h2>
<p>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.</p>
<p>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.</p>
<h2>Example usage</h2>
<canvas id="polarArea" data-type="PolarArea" width="300" height="300"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).PolarArea(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="polarArea">var data = [
{
value : 30,
color: "#D97041"
},
{
value : 90,
color: "#C7604C"
},
{
value : 24,
color: "#21323D"
},
{
value : 58,
color: "#9D9B7F"
},
{
value : 82,
color: "#7D4F6D"
},
{
value : 8,
color: "#584A5E"
}
]</code></pre>
<p>As you can see, for the chart data you pass in an array of objects, with a value and a colour. The <code>value</code> attribute should be a number, while the <code>color</code> attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.</p>
<h2>Chart options</h2>
<p>These are the default chart options. By passing in an object with any of these attributes, Chart.js will merge these objects and the graph accordingly. Explanations of each option are commented in the code below.</p>
<pre data-type="javascript"><code>PolarArea.defaults = {
//Boolean - Whether we show the scale above or below the chart segments
scaleOverlay : true,
//Boolean - If we want to override with a hard coded scale
scaleOverride : false,
//** 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 centre starting value
scaleStartValue : null,
//Boolean - Show line for each value in the scale
scaleShowLine : true,
//String - The colour of the scale line
scaleLineColor : "rgba(0,0,0,.1)",
//Number - The width of the line - in pixels
scaleLineWidth : 1,
//Boolean - whether we should show text labels
scaleShowLabels : true,
//Interpolated JS string - can access value
scaleLabel : "<%=value%>",
//String - Scale label font declaration for the scale label
scaleFontFamily : "'Arial'",
//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 - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
//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 - Stroke a line around each segment in the chart
segmentShowStroke : true,
//String - The colour of the stroke on each segement.
segmentStrokeColor : "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth : 2,
//Boolean - Whether to animate the chart or not
animation : true,
//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,
//Function - This will fire when the animation of the chart is complete.
onAnimationComplete : null
}</code></pre>
</article>
<article id="pieChart">
<h1>Pie chart</h1>
<h2>Introduction</h2>
<p>Pie charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows a the proportional value of each piece of data.</p>
<p>They are excellent at showing the relational proportions between data.</p>
<h2>Example usage</h2>
<canvas id="pie" data-type="Pie" width="400" height="400"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).Pie(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="pie">var data = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
]</code></pre>
<p>For a pie chart, you must pass in an array of objects with a <code>value</code> and a <code>color</code> property. The <code>value</code> attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The <code>color</code> attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.</p>
<h2>Chart options</h2>
<p>These are the default options for the Pie chart. Pass in an object with any of these attributes to override them.
<pre data-type="javascript"><code>Pie.defaults = {
//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,
//Boolean - Whether we should animate the chart
animation : true,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : "easeOutBounce",
//Boolean - Whether we animate the rotation of the Pie
animateRotate : true,
//Boolean - Whether we animate scaling the Pie from the centre
animateScale : false,
//Function - Will fire on animation completion.
onAnimationComplete : null
}</code></pre>
</article>
<article id="doughnutChart">
<h1>Doughnut chart</h1>
<h2>Introduction</h2>
<p>Doughnut charts are similar to pie charts, however they have the centre cut out, and are therefore shaped more like a doughnut than a pie!</p>
<p>They are aso excellent at showing the relational proportions between data.</p>
<h2>Example usage</h2>
<canvas id="doughnut" data-type="Doughnut" width="400" height="400"></canvas>
<pre data-type="javascript"><code>new Chart(ctx).Doughnut(data,options);</code></pre>
<h2>Data structure</h2>
<pre data-type="javascript"><code data-for="doughnut">var data = [
{
value: 30,
color:"#F7464A"
},
{
value : 50,
color : "#E2EAE9"
},
{
value : 100,
color : "#D4CCC5"
},
{
value : 40,
color : "#949FB1"
},
{
value : 120,
color : "#4D5360"
}
]</code></pre>
<p>For a doughnut chart, you must pass in an array of objects with a <code>value</code> and a <code>color</code> property. The <code>value</code> attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The <code>color</code> attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.</p>
<h2>Chart options</h2>
<p>These are the default options for the doughnut chart. Pass in an object with any of these attributes to override them.
<pre data-type="javascript"><code>Doughnut.defaults = {
//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,
//Boolean - Whether we should animate the chart
animation : true,
//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,
//Function - Will fire on animation completion.
onAnimationComplete : null
}</code></pre>
</article>
<article id="generalIssues">
<h1>General issues</h1>
<h2>Chart interactivity</h2>
<p>If you are looking to add interaction as a layer to charts, Chart.js is <strong>not the library for you</strong>. A better option would be using SVG, as this will let you attach event listeners to any of the elements in the chart, as these are all DOM nodes.</p>
<p>Chart.js uses the canvas element, which is a single DOM node, similar in characteristics to a static image. This does mean that it has a wider scope for compatibility, and less memory implications than SVG based charting solutions. The canvas element also allows for saving the contents as a base 64 string, allowing saving the chart as an image. </p>
<p>In SVG, all of the lines, data points and everything you see is a DOM node. As a result of this, complex charts with a lot of intricacies, or many charts on the page will often see dips in performance when scrolling or generating the chart, especially when there are multiple on the page. SVG also has relatively poor mobile support, with Android not supporting SVG at all before version 3.0, and iOS before 5.0. (<a href="http://caniuse.com/svg-html5" target="_blank">caniuse.com/svg-html5</a>).</p>
<h2>Browser support</h2>
<p>Browser support for the canvas element is available in all modern & major mobile browsers (<a href="http://caniuse.com/canvas" target="_blank">caniuse.com/canvas</a>).</p>
<p>For IE8 & below, I would recommend using the polyfill ExplorerCanvas - available at <a href="https://code.google.com/p/explorercanvas/" target="_blank">https://code.google.com/p/explorercanvas/</a>. It falls back to Internet explorer's format VML when canvas support is not available. Example use:</p>
<pre data-type="html"><code>&lt;head&gt;
&lt;!--[if lte IE 8]&gt;
&lt;script src=&quot;excanvas.js&quot;&gt;&lt;/script&gt;
&lt;![endif]--&gt;
&lt;/head&gt;</code></pre>
<p>Usually I would recommend feature detection to choose whether or not to load a polyfill, rather than IE conditional comments, however in this case, VML is a Microsoft proprietary format, so it will only work in IE.</p>
<p>Some important points to note in my experience using ExplorerCanvas as a fallback.</p>
<ul>
<li>Initialise charts on load rather than DOMContentReady when using the library, as sometimes a race condition will occur, and it will result in an error when trying to get the 2d context of a canvas.</li>
<li>New VML DOM elements are being created for each animation frame and there is no hardware acceleration. As a result animation is usually slow and jerky, with flashing text. It is a good idea to dynamically turn off animation based on canvas support. I recommend using the excellent <a href="http://modernizr.com/" targer="_blank">Modernizr</a> to do this.</li>
<li>When declaring fonts, the library explorercanvas requires the font name to be in single quotes inside the string. For example, instead of your scaleFontFamily property being simply "Arial", explorercanvas support, use "'Arial'" instead. Chart.js does this for default values.</li>
</ul>
<h2>Bugs &amp; issues</h2>
<p>Please report these on the Github page - at <a href="https://github.com/nnnick/Chart.js" target="_blank">github.com/nnnick/Chart.js</a>.</p>
<p>New contributions to the library are welcome.</p>
<h2>License</h2>
<p>Chart.js is open source and available under the <a href="http://opensource.org/licenses/MIT" target="_blank">MIT license</a>.</p>
</article>
</div>
</div>
</body>
<script>
$(document).ready(function(){
var $nav = $("nav dl");
$("article").each(function(){
var $el = $(this);
var $h1 = $el.find("h1");
var sectionTitle = $h1.html();
var articleId = $el.attr("id");
var $dt = $("<dt><a href=\"#"+articleId +"\">"+sectionTitle+"</a></dt>");
$dt.find("a").on("click",function(e){
e.preventDefault();
$('html,body').animate({scrollTop: $h1.offset().top},400);
});
$nav.append($dt);
var $subtitles = $el.find("h2");
$subtitles.each(function(){
var $h2 = $(this);
var title = $h2.text();
var newID = articleId + "-" +camelCase(title);
$h2.attr("id",newID);
var $dd = $("<dd><a href=\"#" +newID + "\">" + title + "</a></dd>");
$dd.find("a").on("click",function(e){
e.preventDefault();
$('html,body').animate({scrollTop: $h2.offset().top},400);
})
$nav.append($dd);
});
var $articles = $el.find("article");
});
$("canvas").each(function(){
var $canvas = $(this);
var ctx = this.getContext("2d");
eval($("code[data-for='" + $canvas.attr("id") + "']").text());
var evalString = "new Chart(ctx)." + $canvas.data("type") + "(data);";
eval(evalString);
});
prettyPrint();
function camelCase(str){
var splitString = str.split(" ");
var returnedCamel = splitString[0].toLowerCase();
for (var i=1; i<splitString.length; i++){
returnedCamel += splitString[i].charAt(0).toUpperCase() + splitString[i].substring(1).toLowerCase();
}
return returnedCamel;
}
});
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-28909194-3']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</html>
-38
Ver Arquivo
@@ -1,38 +0,0 @@
/* Pretty printing styles. Used with prettify.js. */
/* Vim sunburst theme by David Leibovic */
pre .str, code .str { color: #65B042; } /* string - green */
pre .kwd, code .kwd { color: #E28964; } /* keyword - dark pink */
pre .com, code .com { color: #AEAEAE; font-style: italic; } /* comment - gray */
pre .typ, code .typ { color: #89bdff; } /* type - light blue */
pre .lit, code .lit { color: #3387CC; } /* literal - blue */
pre .pun, code .pun { color: #fff; } /* punctuation - white */
pre .pln, code .pln { color: #fff; } /* plaintext - white */
pre .tag, code .tag { color: #89bdff; } /* html/xml tag - light blue */
pre .atn, code .atn { color: #bdb76b; } /* html/xml attribute name - khaki */
pre .atv, code .atv { color: #65B042; } /* html/xml attribute value - green */
pre .dec, code .dec { color: #3387CC; } /* decimal - blue */
pre.prettyprint, code.prettyprint {
background-color: #000;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
-o-border-radius: 8px;
-ms-border-radius: 8px;
-khtml-border-radius: 8px;
border-radius: 8px;
}
pre.prettyprint {
width: 95%;
margin: 1em auto;
padding: 1em;
white-space: pre-wrap;
}
/* Specify class=linenums on a pre to get line numbering */
ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */
li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
/* Alternate shading for lines */
li.L1,li.L3,li.L5,li.L7,li.L9 { }
-28
Ver Arquivo
@@ -1,28 +0,0 @@
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;var k=k.match(g),f,b;if(b=
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}p<h.length?setTimeout(m,
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
-33
Ver Arquivo
@@ -1,33 +0,0 @@
/* Pretty printing styles. Used with prettify.js. */
/* Vim sunburst theme by David Leibovic */
pre .str{ color: #65B042; } /* string - green */
pre .kwd{ color: #E28964; } /* keyword - dark pink */
pre .com{ color: #AEAEAE; font-style: italic; } /* comment - gray */
pre .typ{ color: #89bdff; } /* type - light blue */
pre .lit{ color: #3387CC; } /* literal - blue */
pre .pun{ color: #fff; } /* punctuation - white */
pre .pln{ color: #fff; } /* plaintext - white */
pre .tag{ color: #89bdff; } /* html/xml tag - light blue */
pre .atn{ color: #bdb76b; } /* html/xml attribute name - khaki */
pre .atv{ color: #65B042; } /* html/xml attribute value - green */
pre .dec{ color: #3387CC; } /* decimal - blue */
/* Specify class=linenums on a pre to get line numbering */
ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */
li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
/* Alternate shading for lines */
li.L1,li.L3,li.L5,li.L7,li.L9 { }
@media print {
pre .str{ color: #060; }
pre .kwd{ color: #006; font-weight: bold; }
pre .com{ color: #600; font-style: italic; }
pre .typ{ color: #404; font-weight: bold; }
pre .lit{ color: #044; }
pre .pun{ color: #440; }
pre .pln{ color: #000; }
pre .tag{ color: #006; font-weight: bold; }
pre .atn{ color: #404; }
pre .atv{ color: #060; }
}
-263
Ver Arquivo
@@ -1,263 +0,0 @@
/* Pretty printing styles. Used with prettify.js. */
/* Vim sunburst theme by David Leibovic */
pre .str {
color: #65B042;
}
/* string - green */
pre .kwd {
color: #E28964;
}
/* keyword - dark pink */
pre .com {
color: #AEAEAE;
font-style: italic;
}
/* comment - gray */
pre .typ {
color: #89bdff;
}
/* type - light blue */
pre .lit {
color: #3387CC;
}
/* literal - blue */
pre .pun {
color: #fff;
}
/* punctuation - white */
pre .pln {
color: #fff;
}
/* plaintext - white */
pre .tag {
color: #89bdff;
}
/* html/xml tag - light blue */
pre .atn {
color: #bdb76b;
}
/* html/xml attribute name - khaki */
pre .atv {
color: #65B042;
}
/* html/xml attribute value - green */
pre .dec {
color: #3387CC;
}
/* decimal - blue */
/* Specify class=linenums on a pre to get line numbering */
ol.linenums {
margin-top: 0;
margin-bottom: 0;
color: #AEAEAE;
}
/* IE indents via margin-left */
li.L0,
li.L1,
li.L2,
li.L3,
li.L5,
li.L6,
li.L7,
li.L8 {
list-style-type: none;
}
/* Alternate shading for lines */
@media print {
pre .str {
color: #060;
}
pre .kwd {
color: #006;
font-weight: bold;
}
pre .com {
color: #600;
font-style: italic;
}
pre .typ {
color: #404;
font-weight: bold;
}
pre .lit {
color: #044;
}
pre .pun {
color: #440;
}
pre .pln {
color: #000;
}
pre .tag {
color: #006;
font-weight: bold;
}
pre .atn {
color: #404;
}
pre .atv {
color: #060;
}
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
color: inherit;
text-rendering: optimizeLegibility;
}
body {
color: #282b36;
min-width: 768px;
}
.redBorder,
.greenBorder,
.yellowBorder {
border-top: 8px solid #282b36;
width: 33.33%;
float: left;
height: 16px;
position: relative;
z-index: 50;
}
.redBorder {
background-color: #f33e6f;
}
.greenBorder {
background-color: #46bfbd;
}
.yellowBorder {
background-color: #fdb45c;
}
h1 {
font-family: "proxima-nova";
font-weight: 600;
font-size: 32px;
}
h2 {
font-family: "proxima-nova";
font-weight: 600;
font-size: 22px;
line-height: 40px;
}
#mainHeader {
font-size: 55px;
}
#introText {
font-weight: 400;
margin-top: 20px;
font-size: 26px;
line-height: 40px;
margin-bottom: 40px;
}
#wrapper {
margin: 0 auto;
position: relative;
min-width: 768px;
}
#wrapper nav {
width: 20%;
padding-right: 20px;
position: fixed;
height: 100%;
overflow-y: scroll;
top: 0;
z-index: 0;
padding: 40px 20px;
font-family: "proxima-nova";
background-color: #ebebeb;
}
#wrapper nav dl {
color: #767c8d;
}
#wrapper nav dl dt {
list-style: none;
margin-top: 10px;
margin-bottom: 5px;
}
#wrapper nav dl dt a {
display: block;
padding: 2px 0;
border-bottom: 1px solid rgba(118, 124, 141, 0.2);
text-decoration: none;
}
#wrapper nav dl dd {
margin-bottom: 5px;
padding-left: 5px;
}
#wrapper nav dl dd:before {
content: "- ";
}
#wrapper nav dl dd a {
text-decoration: none;
font-size: 12px;
border-bottom: 1px solid transparent;
}
#wrapper nav dl a {
-webkit-transition: all 200ms ease-in-out;
-moz-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
-ms-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
}
#wrapper nav dl a:hover {
color: #2d91ea;
border-bottom-color: #2d91ea;
}
#wrapper #contentWrapper {
width: 80%;
max-width: 1080px;
margin-left: 20%;
padding: 0px 40px;
padding-top: 72px;
}
article {
border-top: 1px solid #ebebeb;
padding: 40px 0;
}
article h2 {
margin-top: 20px;
}
p,
ul li {
font-family: "proxima-nova";
line-height: 20px;
font-size: 16px;
margin-top: 10px;
color: #767c8d;
}
p a,
ul li a {
text-decoration: none;
border-bottom: 1px solid #2d91ea;
color: #2d91ea;
}
canvas {
margin-top: 20px;
}
pre {
background-color: #292b36;
padding: 10px;
border-radius: 5px;
position: relative;
-webkit-font-smoothing: antialiased;
margin: 40px 0 20px 0;
}
pre code {
display: block;
}
pre:before {
content: attr(data-type);
position: absolute;
font-size: 12px;
top: -30px;
left: 0;
font-family: "proxima-nova";
font-weight: 400;
display: inline-block;
padding: 2px 5px;
border-radius: 5px;
background-color: #ebebeb;
}
-185
Ver Arquivo
@@ -1,185 +0,0 @@
@import "prettify";
@codeBackground : #292B36;
@primaryFont : "proxima-nova";
@textColour : #282B36;
@secondaryTextColour : #767c8d;
@borderPaleColour : #EBEBEB;
@pageBorderColour : @textColour;
@red : #F33E6F;
@green : #46BFBD;
@yellow : #FDB45C;
@blue : #2D91EA;
*{
padding:0;
margin:0;
box-sizing:border-box;
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
color:inherit;
text-rendering: optimizeLegibility;
}
body{
color: @textColour;
min-width: 768px;
}
.redBorder,.greenBorder,.yellowBorder{
border-top: 8px solid @pageBorderColour;
width: 33.33%;
float: left;
height: 16px;
position: relative;
z-index:50;
}
.redBorder{
background-color: @red;
}
.greenBorder{
background-color: @green;
}
.yellowBorder{
background-color: @yellow;
}
h1{
font-family: @primaryFont;
font-weight: 600;
font-size: 32px;
}
h2{
font-family: @primaryFont;
font-weight: 600;
font-size: 22px;
line-height: 40px;
}
#mainHeader{
font-size: 55px;
}
#introText{
font-weight: 400;
margin-top: 20px;
font-size: 26px;
line-height: 40px;
margin-bottom: 40px;
}
#wrapper{
margin: 0 auto;
position: relative;
min-width: 768px;
nav{
width: 20%;
padding-right: 20px;
position: fixed;
height: 100%;
overflow-y: scroll;
top: 0;
z-index: 0;
padding: 40px 20px;
font-family: @primaryFont;
background-color: @borderPaleColour;
dl{
color: @secondaryTextColour;
dt{
list-style: none;
margin-top: 10px;
margin-bottom: 5px;
a{
display: block;
padding: 2px 0;
border-bottom: 1px solid fade(@secondaryTextColour,20%);
text-decoration: none;
}
}
dd{
margin-bottom: 5px;
padding-left: 5px;
&:before{
content: "- ";
}
a{
text-decoration:none;
font-size: 12px;
border-bottom: 1px solid transparent;
}
}
a{
-webkit-transition: all 200ms ease-in-out;
-moz-transition: all 200ms ease-in-out;
-o-transition: all 200ms ease-in-out;
-ms-transition: all 200ms ease-in-out;
transition: all 200ms ease-in-out;
&:hover{
color: @blue;
border-bottom-color:@blue;
}
}
}
}
#contentWrapper{
width: 80%;
max-width: 1080px;
margin-left: 20%;
padding: 0px 40px;
padding-top: 72px;
}
}
article{
border-top: 1px solid @borderPaleColour;
padding: 40px 0;
h2{
margin-top: 20px;
}
}
p,ul li{
font-family: @primaryFont;
line-height: 20px;
font-size: 16px;
margin-top: 10px;
color: @secondaryTextColour;
a{
text-decoration: none;
border-bottom: 1px solid @blue;
color: @blue;
}
}
canvas{
margin-top: 20px;
}
pre{
background-color: @codeBackground;
padding: 10px;
border-radius: 5px;
position: relative;
-webkit-font-smoothing: antialiased;
margin: 40px 0 20px 0;
code{
display: block;
}
&:before{
content: attr(data-type);
position: absolute;
font-size: 12px;
top: -30px;
left: 0;
font-family: @primaryFont;
font-weight: 400;
display: inline-block;
padding: 2px 5px;
border-radius: 5px;
background-color: @borderPaleColour;
}
}
p{
}
+201
Ver Arquivo
@@ -0,0 +1,201 @@
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
util = require('gulp-util'),
jshint = require('gulp-jshint'),
size = require('gulp-size'),
connect = require('gulp-connect'),
replace = require('gulp-replace'),
htmlv = require('gulp-html-validator'),
inquirer = require('inquirer'),
semver = require('semver'),
exec = require('child_process').exec,
fs = require('fs'),
package = require('./package.json'),
bower = require('./bower.json'),
karma = require('gulp-karma');
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
*/
var srcFiles = [
'./node_modules/color/dist/color.min.js',
'./src/core/core.js',
'./src/core/core.helpers.js',
'./src/core/core.chart.js',
'./src/core/core.element.js',
'./src/core/**',
'./src/controllers/**',
'./src/scales/**',
'./src/elements/**',
'./src/charts/**',
];
var testFiles = [
'./node_modules/moment/min/moment.min.js',
'./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),
outputDir = (isCustom) ? 'custom' : '.';
return gulp.src(srcFiles)
.pipe(concat('Chart.js'))
.pipe(replace('{{ version }}', package.version))
.pipe(gulp.dest(outputDir))
.pipe(uglify({
preserveComments: 'some'
}))
.pipe(concat('Chart.min.js'))
.pipe(gulp.dest(outputDir));
}
/*
* Usage : gulp bump
* Prompts: Version increment to bump
* Output: - New version number written into package.json & bower.json
*/
function bumpTask(complete) {
util.log('Current version:', util.colors.cyan(package.version));
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType) {
return versionType + ' (v' + semver.inc(package.version, versionType) + ')';
});
inquirer.prompt({
type: 'list',
name: 'version',
message: 'What version update would you like?',
choices: choices
}, function(res) {
var increment = res.version.split(' ')[0],
newVersion = semver.inc(package.version, increment);
// Set the new versions into the bower/package object
package.version = newVersion;
bower.version = newVersion;
// Write these to their own files, then build the output
fs.writeFileSync('package.json', JSON.stringify(package, null, 2));
fs.writeFileSync('bower.json', JSON.stringify(bower, null, 2));
complete();
});
}
function releaseTask() {
exec('git tag -a v' + package.version);
}
function jshintTask() {
return gulp.src(srcDir + '*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
}
function validHTMLTask() {
return gulp.src('samples/*.html')
.pipe(htmlv());
}
function unittestTask() {
var files = srcFiles.slice();
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.conf.js',
action: 'run'
}));
}
function unittestWatchTask() {
var files = srcFiles.slice();
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.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.coverage.conf.js',
action: 'run'
}));
}
function librarySizeTask() {
return gulp.src('Chart.min.js')
.pipe(size({
gzip: true
}));
}
function moduleSizesTask() {
return gulp.src(srcDir + '*.js')
.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']);
}
function serverTask() {
connect.server({
port: 8000
});
}
// Convenience task for opening the project straight from the command line
function _openTask() {
exec('open http://localhost:8000');
exec('subl .');
}
+7
Ver Arquivo
@@ -0,0 +1,7 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox'],
frameworks: ['jasmine'],
reporters: ['progress', 'html'],
});
};
+18
Ver Arquivo
@@ -0,0 +1,18 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox'],
coverageReporter: {
type: 'html',
dir: 'coverage/'
},
frameworks: ['jasmine'],
preprocessors: {
'src/**/*.js': ['coverage']
},
reporters: ['progress', 'coverage'],
});
};
+42
Ver Arquivo
@@ -0,0 +1,42 @@
{
"name": "chart.js",
"homepage": "http://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "2.0.0-alpha",
"main": "Chart.js",
"repository": {
"type": "git",
"url": "https://github.com/nnnick/Chart.js.git"
},
"dependences": {},
"devDependencies": {
"color": "git://github.com/chartjs/color",
"gulp": "3.5.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-util": "~2.2.x",
"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"
},
"spm": {
"main": "Chart.js"
},
"dependencies": {
"moment": "^2.10.6"
}
}
-52
Ver Arquivo
@@ -1,52 +0,0 @@
Chart.js
=======
*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)
Quick FYI
-------
I'm currently working on a big refactor of the library into a more object oriented structure.
It'll have an extendable class structure for adding community developed chart types. By opening up components into Chart.js into extendable classes, it'll allow for much easier community driven library extensions rather than tacking on new features as required. The refactor will also feature a generisized version of the interaction layer introduced by Regaddi in his tooltips branch - https://github.com/nnnick/Chart.js/pull/51. On top of this, it'll include utility methods on each chart object, for updating, clearing and redrawing charts etc.
I haven't quite got the bandwidth right now to be juggling both issues/requests in master while redesigning all of the core code in Chart.js. By focusing on the refactor, it'll get done WAY quicker.
Extensibility will absolutely be at the core of the refactor, allowing for the development of complex extension modules, but also keeping a lightweight set of core code.
Hang tight - it'll be worth it.
PS. If you're interested in reviewing some code or trying out writing extensions, shoot me an email.
###Update - 8th September
Just a quick update on the refactor.
Just wanted to let you guys know it's making really good progress, and it'll be well worth the wait.
The new version is being broken up into Chart type modules, with each of the current 6 chart types using documented and extendable classes and helper methods from the Chart.js core. This means the community will be able to build new chart types using existing components, or extend existing types to do something a bit different.
By splitting the different charts into modules will mean the ability to use AMD if appropriate, but I'll also be writing a simple web interface for concatenating chart types into a minified production ready custom build.
The syntax for creating charts **will not change**, so the upgrade should be a drop in replacement, but give you the ability to have a whole new level of interactivity and animated data updates.
Right now I've wrote 80% of the core, and refactored the Doughnut and Pie charts, and I'm a good way through the Line and Bar charts. I hope to have the new version ready to release with some new docs late September/early October.
I know PR and issues are racking up in the repo, and I'll do my best to sort them ASAP, but I think this update is really important for creating flexibility and extensibility to cater for these new features in an elegant way, rather than introducing scope creep into an architecture that wasn't designed to deliver this extra functionality.
Big thanks for all the support - it's been totally overwhelming.
###Another Quick Update - 16th October
First of all - my apologies, early October has drifted away from me and we're moving towards late October. This last month has been really unexpectedly busy, and I've had a lot of stuff going on, so I haven't quite managed to find as much time to work on Chart.js as I'd hoped.
In terms of an updated ETA, I'm really aiming for a pre-November release, and I'll be having some late nights and a few days off to try my best to make this happen.
Again, really appreciate the support and cheers for your patience for the new version.
Documentation
-------
You can find documentation at [chartjs.org/docs](http://www.chartjs.org/docs).
License
-------
Chart.js was taken down on the 19th March. It is now back online for good and IS available under MIT license.
Chart.js is available under the [MIT license] (http://opensource.org/licenses/MIT).
+91
Ver Arquivo
@@ -0,0 +1,91 @@
<!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>
+70
Ver Arquivo
@@ -0,0 +1,70 @@
<!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: {
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>
+137 -32
Ver Arquivo
@@ -1,39 +1,144 @@
<!doctype html>
<html>
<head>
<title>Bar Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
</head>
<body>
<canvas id="canvas" height="450" width="600"></canvas>
<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>
<script>
<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)';
};
var barChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [28,48,40,19,96,27,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()]
}, {
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()]
}]
};
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,
}
});
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>
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Bar(barChartData);
</script>
</body>
</html>
+69
Ver Arquivo
@@ -0,0 +1,69 @@
<!doctype html>
<html>
<head>
<title>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: [{
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()]
}, ]
};
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>
+191
Ver Arquivo
@@ -0,0 +1,191 @@
<!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 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 newDate = function(days) {
var date = new Date();
return date.setDate(date.getDate() + days);
};
var newTimestamp = function(days) {
return Date.now() - days * 100000;
};
var config = {
type: 'bar',
data: {
//labels: [newTimestamp(0), newTimestamp(1), newTimestamp(2), newTimestamp(3), newTimestamp(4), newTimestamp(5), newTimestamp(6)], // unix timestamps
// labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
labels: ["01/01/2015 20:00", "01/02/2015 20:00", "01/03/2015 22:00", "01/05/2015 23:00", "01/07/2015 03:00", "01/08/2015 10:00", "01/10/2015"], // Hours
// labels: ["01/01/2015", "01/02/2015", "01/03/2015", "01/06/2015", "01/15/2015", "01/17/2015", "01/30/2015"], // Days
// labels: ["12/25/2014", "01/08/2015", "01/15/2015", "01/22/2015", "01/29/2015", "02/05/2015", "02/12/2015"], // Weeks
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: 'MM/DD/YYYY HH:mm',
// round: 'day'
}
}, ],
yAxes: [{
display: true
}]
},
elements: {
line: {
tension: 0.3
}
},
}
};
$.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>
+179 -39
Ver Arquivo
@@ -1,46 +1,186 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
</head>
<body>
<canvas id="canvas" height="450" width="450"></canvas>
<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>
<script>
<body>
<div id="canvas-holder" style="width:50%">
<canvas id="chart-area" width="500" height="500" />
</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 doughnutData = [
{
value: 30,
color:"#F7464A"
},
{
value : 50,
color : "#46BFBD"
},
{
value : 100,
color : "#FDB45C"
},
{
value : 40,
color : "#949FB1"
},
{
value : 120,
color : "#4D5360"
}
];
var config = {
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
}
};
function updateLegend() {
$legendContainer = $('#legendContainer');
$legendContainer.empty();
$legendContainer.append(window.myDoughnut.generateLegend());
}
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = Chart.Doughnut(ctx, config);
console.log(window.myDoughnut);
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: [],
};
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>
var myDoughnut = new Chart(document.getElementById("canvas").getContext("2d")).Doughnut(doughnutData);
</script>
</body>
</html>
+150
Ver Arquivo
@@ -0,0 +1,150 @@
<!doctype html>
<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>
#canvas-holder1 {
width: 300px;
margin: 20px auto;
}
#canvas-holder2 {
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);
}
.chartjs-tooltip-key {
display: inline-block;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<div id="canvas-holder1">
<canvas id="chart1" width="300" height="30" />
</div>
<script>
Chart.defaults.global.pointHitDetectionRadius = 1;
var customTooltips = function(tooltip) {
console.log(tooltip._view);
// 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._view.opacity) {
tooltipEl.css({
opacity: 0
});
$('.chartjs-wrap canvas')
.each(function(index, el) {
$(el).css('cursor', 'default');
});
return;
}
$(tooltip._chart.canvas).css('cursor', 'pointer');
// Set caret Position
tooltipEl.removeClass('above below no-transform');
if (tooltip._view.yAlign) {
tooltipEl.addClass(tooltip._view.yAlign);
} else {
tooltipEl.addClass('no-transform');
}
// Set Text
if (tooltip._view.text) {
tooltipEl.html(tooltip._view.text);
} else if (tooltip._view.labels) {
var innerHtml = '<div class="title">' + tooltip._view.title + '</div>';
for (var i = 0; i < tooltip._view.labels.length; i++) {
innerHtml += [
'<div class="section">',
' <span class="key" style="background-color:' + tooltip._view.legendColors[i].fill + '"></span>',
' <span class="value">' + tooltip._view.labels[i] + '</span>',
'</div>'
].join('');
}
tooltipEl.html(innerHtml);
}
// Find Y Location on page
var top = 0;
if (tooltip._view.yAlign) {
if (tooltip._view.yAlign == 'above') {
top = tooltip._view.y - tooltip._view.caretHeight - tooltip._view.caretPadding;
} else {
top = tooltip._view.y + tooltip._view.caretHeight + tooltip._view.caretPadding;
}
}
var offset = $(tooltip._chart.canvas).offset();
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
width: tooltip._view.width ? (tooltip._view.width + 'px') : 'auto',
left: offset.left + tooltip._view.x + 'px',
top: offset.top + top + 'px',
fontFamily: tooltip._view._fontFamily,
fontSize: tooltip._view.fontSize,
fontStyle: tooltip._view._fontStyle,
padding: tooltip._view.yPadding + 'px ' + tooltip._view.xPadding + 'px',
});
};
var randomScalingFactor = function() {
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()]
}]
};
window.onload = function() {
var chartEl = document.getElementById("chart1");
window.myLine = new Chart(chartEl, {
type: 'line',
data: lineChartData,
options: {
tooltips: {
enabled: false,
custom: customTooltips
}
}
});
};
</script>
</body>
</html>
+166
Ver Arquivo
@@ -0,0 +1,166 @@
<!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: {
show: true,
labelString: 'x axis'
}
}],
yAxes: [{
display: true,
type: 'logarithmic',
scaleLabel: {
show: 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
@@ -0,0 +1,92 @@
<!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>
+190
Ver Arquivo
@@ -0,0 +1,190 @@
<!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 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 newDate = function(days) {
var date = new Date();
return date.setDate(date.getDate() + days);
};
var newTimestamp = function(days) {
return Date.now() - days * 100000;
};
var config = {
type: 'line',
data: {
//labels: [newTimestamp(0), newTimestamp(1), newTimestamp(2), newTimestamp(3), newTimestamp(4), newTimestamp(5), newTimestamp(6)], // unix timestamps
// labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
labels: ["01/01/2015 20:00", "01/02/2015 21:00", "01/03/2015 22:00", "01/05/2015 23:00", "01/07/2015 03:00", "01/08/2015 10:00", "01/10/2015"], // Hours
// labels: ["01/01/2015", "01/02/2015", "01/03/2015", "01/06/2015", "01/15/2015", "01/17/2015", "01/30/2015"], // Days
// labels: ["12/25/2014", "01/08/2015", "01/15/2015", "01/22/2015", "01/29/2015", "02/05/2015", "02/12/2015"], // Weeks
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: [{
type: "time",
display: true,
time: {
format: 'MM/DD/YYYY HH:mm',
// round: 'day'
},
scaleLabel: {
show: true,
labelString: 'Date'
}
}, ],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'value'
}
}]
},
elements: {
line: {
tension: 0.3
}
},
}
};
$.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]
.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(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
@@ -0,0 +1,144 @@
<!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: {
callback: function(dataLabel, index) {
return 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>
+157 -36
Ver Arquivo
@@ -1,43 +1,164 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
</head>
<body>
<canvas id="canvas" height="450" width="600"></canvas>
<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>
<script>
<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.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 lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}
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: {
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;
});
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>
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(lineChartData);
</script>
</body>
</html>
+115 -31
Ver Arquivo
@@ -1,38 +1,122 @@
<!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>
<canvas id="canvas" height="450" width="450"></canvas>
<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>
<script>
<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') + ')';
};
var pieData = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
];
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
}
};
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();
});
$('#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>
var myPie = new Chart(document.getElementById("canvas").getContext("2d")).Pie(pieData);
</script>
</body>
</html>
+120
Ver Arquivo
@@ -0,0 +1,120 @@
<!doctype html>
<html>
<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:50%" width="50%">
<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">
</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 = {
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
scale: {
beginAtZero: true,
reverse: false
}
}
};
window.onload = function() {
var ctx = document.getElementById("chart-area");
window.myPolarArea = Chart.PolarArea(ctx, config);
updateLegend();
};
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>
</html>
-44
Ver Arquivo
@@ -1,44 +0,0 @@
<!doctype html>
<html>
<head>
<title>Polar Area Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
</style>
</head>
<body>
<canvas id="canvas" height="400" width="400"></canvas>
<script>
var chartData = [
{
value : Math.random(),
color: "#D97041"
},
{
value : Math.random(),
color: "#C7604C"
},
{
value : Math.random(),
color: "#21323D"
},
{
value : Math.random(),
color: "#9D9B7F"
},
{
value : Math.random(),
color: "#7D4F6D"
},
{
value : Math.random(),
color: "#584A5E"
}
];
var myPolarArea = new Chart(document.getElementById("canvas").getContext("2d")).PolarArea(chartData);
</script>
</body>
</html>
+130 -36
Ver Arquivo
@@ -1,43 +1,137 @@
<!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>
<canvas id="canvas" height="450" width="450"></canvas>
<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>
<script>
<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 radarChartData = {
labels : ["Eating","Drinking","Sleeping","Designing","Coding","Partying","Running"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}
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: [null, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
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: [null, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
},
options: {
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>
var myRadar = new Chart(document.getElementById("canvas").getContext("2d")).Radar(radarChartData,{scaleShowLabels : false, pointLabelFontSize : 10});
</script>
</body>
</html>
+174
Ver Arquivo
@@ -0,0 +1,174 @@
<!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',
show: true,
}
}],
yAxes: [{
type: 'linear',
ticks: {
userCallback: function(tick) {
return tick.toString() + "dB";
}
},
scaleLabel: {
labelString: 'Voltage',
show: true
}
}]
}
}
});
};
</script>
</body>
</html>
+177
Ver Arquivo
@@ -0,0 +1,177 @@
<!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
@@ -0,0 +1,168 @@
<!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: {
show: true,
labelString: 'x axis'
}
}],
yAxes: [{
position: 'right',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
show: 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>
-155
Ver Arquivo
@@ -1,155 +0,0 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
float: left;
}
</style>
</head>
<body>
<div style="width:600px;height:600px;">
<canvas id="doughnut" height="300" width="200"></canvas>
<canvas id="line" height="300" width="200"></canvas>
<canvas id="polarArea" height="300" width="200"></canvas>
<canvas id="bar" height="300" width="200"></canvas>
<canvas id="pie" height="300" width="200"></canvas>
<canvas id="radar" height="300" width="200"></canvas>
</div>
<script>
var doughnutData = [
{
value: 30,
color:"#F7464A"
},
{
value : 50,
color : "#46BFBD"
},
{
value : 100,
color : "#FDB45C"
},
{
value : 40,
color : "#949FB1"
},
{
value : 120,
color : "#4D5360"
}
];
var lineChartData = {
labels : ["","","","","","",""],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
};
var pieData = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
];
var barChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [28,48,40,19,96,27,100]
}
]
};
var chartData = [
{
value : Math.random(),
color: "#D97041"
},
{
value : Math.random(),
color: "#C7604C"
},
{
value : Math.random(),
color: "#21323D"
},
{
value : Math.random(),
color: "#9D9B7F"
},
{
value : Math.random(),
color: "#7D4F6D"
},
{
value : Math.random(),
color: "#584A5E"
}
];
var radarChartData = {
labels : ["","","","","","",""],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
};
new Chart(document.getElementById("doughnut").getContext("2d")).Doughnut(doughnutData);
new Chart(document.getElementById("line").getContext("2d")).Line(lineChartData);
new Chart(document.getElementById("radar").getContext("2d")).Radar(radarChartData);
new Chart(document.getElementById("polarArea").getContext("2d")).PolarArea(chartData);
new Chart(document.getElementById("bar").getContext("2d")).Bar(barChartData);
new Chart(document.getElementById("pie").getContext("2d")).Pie(pieData);
</script>
</body>
</html>
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 78 KiB

-1443
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-320
Ver Arquivo
@@ -1,320 +0,0 @@
$(window).load(function() {
var lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
};
var barChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [28,48,40,19,96,27,100]
}
]
};
var radarChartData = {
labels : ["A","B","C","D","E","F","G"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
};
var pieChartData = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
];
var polarAreaChartData = [
{
value : 62,
color: "#D97041"
},
{
value : 70,
color: "#C7604C"
},
{
value : 41,
color: "#21323D"
},
{
value : 24,
color: "#9D9B7F"
},
{
value : 55,
color: "#7D4F6D"
},
{
value : 18,
color: "#584A5E"
}
];
var doughnutChartData = [
{
value: 30,
color:"#F7464A"
},
{
value : 50,
color : "#46BFBD"
},
{
value : 100,
color : "#FDB45C"
},
{
value : 40,
color : "#949FB1"
},
{
value : 120,
color : "#4D5360"
}
];
var globalGraphSettings = {animation : Modernizr.canvas};
setIntroChart();
function setIntroChart(){
var ctx = document.getElementById("introChart").getContext("2d");
new Chart(ctx).Line(lineChartData,{animation: Modernizr.canvas, scaleShowLabels : false, scaleFontColor : "#767C8D"});
};
function showLineChart(){
var ctx = document.getElementById("lineChartCanvas").getContext("2d");
new Chart(ctx).Line(lineChartData,globalGraphSettings);
};
function showBarChart(){
var ctx = document.getElementById("barChartCanvas").getContext("2d");
new Chart(ctx).Bar(barChartData,globalGraphSettings);
};
function showRadarChart(){
var ctx = document.getElementById("radarChartCanvas").getContext("2d");
new Chart(ctx).Radar(radarChartData,globalGraphSettings);
}
function showPolarAreaChart(){
var ctx = document.getElementById("polarAreaChartCanvas").getContext("2d");
new Chart(ctx).PolarArea(polarAreaChartData,globalGraphSettings);
}
function showPieChart(){
var ctx = document.getElementById("pieChartCanvas").getContext("2d");
new Chart(ctx).Pie(pieChartData,globalGraphSettings);
};
function showDoughnutChart(){
var ctx = document.getElementById("doughnutChartCanvas").getContext("2d");
new Chart(ctx).Doughnut(doughnutChartData,globalGraphSettings);
};
var graphInitDelay = 300;
//Set up each of the inview events here.
$("#lineChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showLineChart,graphInitDelay);
});
$("#barChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showBarChart,graphInitDelay);
});
$("#radarChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showRadarChart,graphInitDelay);
});
$("#pieChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showPieChart,graphInitDelay);
});
$("#polarAreaChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showPolarAreaChart,graphInitDelay);
});
$("#doughnutChart").on("inview",function(){
var $this = $(this);
$this.removeClass("hidden").off("inview");
setTimeout(showDoughnutChart,graphInitDelay);
});
});
/**
* author Christopher Blum
* - based on the idea of Remy Sharp, http://remysharp.com/2009/01/26/element-in-view-event-plugin/
* - forked from http://github.com/zuk/jquery.inview/
*/
(function ($) {
var inviewObjects = {}, viewportSize, viewportOffset,
d = document, w = window, documentElement = d.documentElement, expando = $.expando;
$.event.special.inview = {
add: function(data) {
inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) };
},
remove: function(data) {
try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {}
}
};
function getViewportSize() {
var mode, domObject, size = { height: w.innerHeight, width: w.innerWidth };
// if this is correct then return it. iPad has compat Mode, so will
// go into check clientHeight/clientWidth (which has the wrong value).
if (!size.height) {
mode = d.compatMode;
if (mode || !$.support.boxModel) { // IE, Gecko
domObject = mode === 'CSS1Compat' ?
documentElement : // Standards
d.body; // Quirks
size = {
height: domObject.clientHeight,
width: domObject.clientWidth
};
}
}
return size;
}
function getViewportOffset() {
return {
top: w.pageYOffset || documentElement.scrollTop || d.body.scrollTop,
left: w.pageXOffset || documentElement.scrollLeft || d.body.scrollLeft
};
}
function checkInView() {
var $elements = $(), elementsLength, i = 0;
$.each(inviewObjects, function(i, inviewObject) {
var selector = inviewObject.data.selector,
$element = inviewObject.$element;
$elements = $elements.add(selector ? $element.find(selector) : $element);
});
elementsLength = $elements.length;
if (elementsLength) {
viewportSize = viewportSize || getViewportSize();
viewportOffset = viewportOffset || getViewportOffset();
for (; i<elementsLength; i++) {
// Ignore elements that are not in the DOM tree
if (!$.contains(documentElement, $elements[i])) {
continue;
}
var $element = $($elements[i]),
elementSize = { height: $element.height(), width: $element.width() },
elementOffset = $element.offset(),
inView = $element.data('inview'),
visiblePartX,
visiblePartY,
visiblePartsMerged;
// Don't ask me why because I haven't figured out yet:
// viewportOffset and viewportSize are sometimes suddenly null in Firefox 5.
// Even though it sounds weird:
// It seems that the execution of this function is interferred by the onresize/onscroll event
// where viewportOffset and viewportSize are unset
if (!viewportOffset || !viewportSize) {
return;
}
if (elementOffset.top + elementSize.height > viewportOffset.top &&
elementOffset.top < viewportOffset.top + viewportSize.height &&
elementOffset.left + elementSize.width > viewportOffset.left &&
elementOffset.left < viewportOffset.left + viewportSize.width) {
visiblePartX = (viewportOffset.left > elementOffset.left ?
'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ?
'left' : 'both');
visiblePartY = (viewportOffset.top > elementOffset.top ?
'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ?
'top' : 'both');
visiblePartsMerged = visiblePartX + "-" + visiblePartY;
if (!inView || inView !== visiblePartsMerged) {
$element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]);
}
} else if (inView) {
$element.data('inview', false).trigger('inview', [false]);
}
}
}
}
$(w).bind("scroll resize", function() {
viewportSize = viewportOffset = null;
});
// IE < 9 scrolls to focused elements without firing the "scroll" event
if (!documentElement.addEventListener && documentElement.attachEvent) {
documentElement.attachEvent("onfocusin", function() {
viewportOffset = null;
});
}
// Use setInterval in order to also make sure this captures elements within
// "overflow:scroll" elements or elements that appeared in the dom tree due to
// dom manipulation and reflow
// old: $(window).scroll(checkInView);
//
// By the way, iOS (iPad, iPhone, ...) seems to not execute, or at least delays
// intervals while the user scrolls. Therefore the inview event might fire a bit late there
setInterval(checkInView, 250);
})(jQuery);
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 82 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 47 KiB

-141
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
-205
Ver Arquivo
@@ -1,205 +0,0 @@
* {
padding: 0;
margin: 0;
color: inherit;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
body {
color: #282b36;
border-top: 8px solid #282b36;
}
canvas {
font-family: "proxima-nova", sans-serif sans-serif;
}
.redBorder,
.greenBorder,
.yellowBorder {
width: 33.33%;
float: left;
height: 8px;
}
.redBorder {
background-color: #f33e6f;
}
.greenBorder {
background-color: #46bfbd;
}
.yellowBorder {
background-color: #fdb45c;
}
h1 {
font-family: "proxima-nova", sans-serif;
font-weight: 600;
font-size: 55px;
margin-top: 40px;
}
h2 {
font-family: "proxima-nova", sans-serif;
font-weight: 400;
margin-top: 20px;
font-size: 26px;
line-height: 40px;
}
h3 {
font-family: "proxima-nova", sans-serif;
font-weight: 600;
text-align: center;
margin: 20px 0;
}
h3 a {
color: #2d91ea;
text-decoration: none;
border-bottom: 1px solid #2d91ea;
}
p {
font-family: "proxima-nova", sans-serif;
line-height: 24px;
font-size: 18px;
color: #767c8d;
}
.btn {
display: inline-block;
padding: 20px;
font-family: "proxima-nova", sans-serif;
font-weight: 600;
color: #fff;
text-decoration: none;
border-radius: 5px;
text-align: center;
font-size: 18px;
-webkit-transition-property: background-color box-shadow;
-webkit-transition-duration: 200ms;
-webkit-transition-timing-function: ease-in-out;
-moz-transition-property: background-color box-shadow;
-moz-transition-duration: 200ms;
-moz-transition-timing-function: ease-in-out;
-ms-transition-property: background-color box-shadow;
-ms-transition-duration: 200ms;
-ms-transition-timing-function: ease-in-out;
-o-transition-property: background-color box-shadow;
-o-transition-duration: 200ms;
-o-transition-timing-function: ease-in-out;
transition-property: background-color box-shadow;
transition-duration: 200ms;
transition-timing-function: ease-in-out;
}
.btn:active {
box-shadow: inset 1px 1px 4px rgba(0, 0, 0, 0.25);
}
.btn.red {
background-color: #f33e6f;
}
.btn.red:hover {
background-color: #f2265d;
}
.btn.blue {
background-color: #2d91ea;
}
.btn.blue:hover {
background-color: #1785e6;
}
header {
width: 978px;
margin: 20px auto;
display: block;
position: relative;
}
header hgroup {
width: 50%;
padding: 20px 0;
}
header #introChart {
position: absolute;
top: 60px;
right: 0;
}
header .btn {
margin-right: 10px;
width: 180px;
}
footer {
width: 100%;
text-align: center;
background-color: #ebebeb;
}
footer p {
color: #767c8d;
font-family: "proxima-nova", sans-serif;
font-size: 16px;
padding: 20px 0;
}
section {
width: 978px;
margin: 40px auto;
}
section:before {
content: '';
width: 600px;
margin: 0 auto;
border-top: 1px solid #ebebeb;
height: 20px;
display: block;
}
section:after {
content: "";
display: table;
clear: both;
}
*section {
zoom: 1;
}
#features article {
width: 33.33%;
float: left;
}
#features article p {
display: block;
width: 90%;
margin: 0 auto;
text-align: center;
}
#features article img {
width: 250px;
height: 250px;
margin: 0 auto;
display: block;
}
#examples article {
-webkit-transition: opacity 200ms ease-in-out;
-ms-transition: opacity 200ms ease-in-out;
-moz-transition: opacity 200ms ease-in-out;
-o-transition: opacity 200ms ease-in-out;
transition: opacity 200ms ease-in-out;
position: relative;
margin-top: 20px;
clear: both;
}
#examples article:after {
content: '';
width: 600px;
padding-top: 40px;
margin: 40px auto;
border-bottom: 1px solid #ebebeb;
height: 20px;
display: block;
clear: both;
}
#examples article p {
margin-top: 10px;
}
#examples article .half {
width: 50%;
float: left;
}
#examples article .canvasWrapper {
float: left;
width: 449px;
padding: 0 20px;
}
#examples h3 {
clear: both;
}
#examples .hidden {
opacity: 0;
}
+14
Ver Arquivo
@@ -0,0 +1,14 @@
(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);
+20
Ver Arquivo
@@ -0,0 +1,20 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
var defaultConfig = {
aspectRatio: 1,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i = 0; i < data.datasets[0].data.length; i++){%><li><span style=\"background-color:<%=data.datasets[0].backgroundColor[i]%>\"><%if(data.labels && i < data.labels.length){%><%=data.labels[i]%><%}%></span></li><%}%></ul>",
};
Chart.Doughnut = function(context, config) {
config.options = helpers.configMerge(defaultConfig, config.options);
config.type = 'doughnut';
return new Chart(context, config);
}
}).call(this);
+14
Ver Arquivo
@@ -0,0 +1,14 @@
(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);
+20
Ver Arquivo
@@ -0,0 +1,20 @@
(function() {
"use strict";
var root = this;
var Chart = root.Chart;
var helpers = Chart.helpers;
var defaultConfig = {
aspectRatio: 1,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i = 0; i < data.datasets[0].data.length; i++){%><li><span style=\"background-color:<%=data.datasets[0].backgroundColor[i]%>\"><%if(data.labels && i < data.labels.length){%><%=data.labels[i]%><%}%></span></li><%}%></ul>",
};
Chart.PolarArea = function(context, config) {
config.options = helpers.configMerge(defaultConfig, config.options);
config.type = 'polarArea';
return new Chart(context, config);
}
}).call(this);
+19
Ver Arquivo
@@ -0,0 +1,19 @@
(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);
+39
Ver Arquivo
@@ -0,0 +1,39 @@
(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: {
template: "(<%= value.x %>, <%= value.y %>)",
multiTemplate: "<%if (datasetLabel){%><%=datasetLabel%>: <%}%>(<%= value.x %>, <%= value.y %>)",
},
};
Chart.Scatter = function(context, config) {
config.options = helpers.configMerge(defaultConfig, config.options);
config.type = 'line';
return new Chart(context, config);
}
}).call(this);
+352
Ver Arquivo
@@ -0,0 +1,352 @@
(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 = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.controllers.bar.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];
},
// 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 (dataset.type === 'bar') {
++barCount;
} else if (dataset.type === undefined && this.chart.config.type === '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);
},
removeElement: function(index) {
this.getDataset().metaData.splice(index, 1);
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
var numData = this.getDataset().data.length;
var numRectangles = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numRectangles) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numRectangles - numData);
} else if (numData > numRectangles) {
// Add new elements
for (var index = numRectangles; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
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++) {
if (this.chart.data.datasets[i].yAxisID === yScale.id) {
base += this.chart.data.datasets[i].data[index] < 0 ? this.chart.data.datasets[i].data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
if (this.chart.data.datasets[j].yAxisID === yScale.id) {
base += this.chart.data.datasets[j].data[index] > 0 ? this.chart.data.datasets[j].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.chart.isCombo ? this.chart.data.datasets.length : helpers.where(this.chart.data.datasets, function(ds) {
return ds.type == 'bar';
}).length;
var tickWidth = (function() {
var min = xScale.getPixelForValue(null, 1) - xScale.getPixelForValue(null, 0);
for (var i = 2; i < this.getDataset().data.length; i++) {
min = Math.min(xScale.getPixelForValue(null, i) - xScale.getPixelForValue(null, 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;
},
calculateBarX: function(index, datasetIndex) {
var yScale = this.getScaleForID(this.getDataset().yAxisID);
var xScale = this.getScaleForID(this.getDataset().xAxisID);
var ruler = this.getRuler();
var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo);
leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0;
if (yScale.options.stacked) {
return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
}
return leftTick +
(ruler.barWidth / 2) +
ruler.categorySpacing +
(ruler.barWidth * datasetIndex) +
(ruler.barSpacing / 2) +
(ruler.barSpacing * datasetIndex);
},
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++) {
if (this.chart.data.datasets[i].data[index] < 0) {
sumNeg += this.chart.data.datasets[i].data[index] || 0;
} else {
sumPos += this.chart.data.datasets[i].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);
+211
Ver Arquivo
@@ -0,0 +1,211 @@
(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,
},
hover: {
mode: 'single'
},
//The percentage of the chart that we cut out of the middle.
cutoutPercentage: 50,
};
Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut);
helpers.extend(Chart.defaults.pie, {
cutoutPercentage: 0
});
Chart.controllers.doughnut = Chart.controllers.pie = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.controllers.doughnut.prototype, {
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
linkScales: function() {
// no scales for doughnut
},
getDataset: function() {
return this.chart.data.datasets[this.index];
},
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);
},
removeElement: function(index) {
this.getDataset().metaData.splice(index, 1);
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Make sure we have metaData for each data point
var numData = this.getDataset().data.length;
var numArcs = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numArcs) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numArcs - numData)
} else if (numData > numArcs) {
// Add new elements
for (var index = numArcs; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
update: function update(reset) {
this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) / 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.chart.data.datasets.length;
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 resetModel = {
x: this.chart.chart.width / 2,
y: this.chart.chart.height / 2,
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
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: this.chart.chart.width / 2,
y: this.chart.chart.height / 2,
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) {
return (Math.PI * 1.999999) * (value / this.getDataset().total);
} else {
return 0;
}
},
});
}).call(this);
+289
Ver Arquivo
@@ -0,0 +1,289 @@
(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 = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.controllers.line.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];
},
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();
},
removeElement: function(index) {
this.getDataset().metaData.splice(index, 1);
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var numData = this.getDataset().data.length;
var numPoints = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numPoints) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numPoints - numData);
} else if (numData > numPoints) {
// Add new elements
for (var index = numPoints; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
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 : (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),
skipNull: this.getDataset().skipNull !== undefined ? this.getDataset().skipNull : this.chart.options.elements.line.skipNull,
drawNull: this.getDataset().drawNull !== undefined ? this.getDataset().drawNull : this.chart.options.elements.line.drawNull,
// 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();
},
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 : yScale.getPixelForValue(this.getDataset().data[index], index, this.index),
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : (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: 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),
skip: point.custom && point.custom.skip ? point.custom.skip : this.getDataset().data[index] === null,
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
},
});
},
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
);
point._model.controlPointPreviousX = controlPoints.previous.x;
point._model.controlPointNextX = controlPoints.next.x;
// Prevent the bezier going outside of the bounds of the graph
// Cap outer bezier handles to the upper/lower scale bounds
if (controlPoints.next.y > this.chart.chartArea.bottom) {
point._model.controlPointNextY = this.chart.chartArea.bottom;
} else if (controlPoints.next.y < this.chart.chartArea.top) {
point._model.controlPointNextY = this.chart.chartArea.top;
} else {
point._model.controlPointNextY = controlPoints.next.y;
}
// Cap inner bezier handles to the upper/lower scale bounds
if (controlPoints.previous.y > this.chart.chartArea.bottom) {
point._model.controlPointPreviousY = this.chart.chartArea.bottom;
} else if (controlPoints.previous.y < this.chart.chartArea.top) {
point._model.controlPointPreviousY = this.chart.chartArea.top;
} else {
point._model.controlPointPreviousY = controlPoints.previous.y;
}
// 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 = 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);
+213
Ver Arquivo
@@ -0,0 +1,213 @@
(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,
};
Chart.controllers.polarArea = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.controllers.polarArea.prototype, {
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
linkScales: function() {
// no scales for doughnut
},
getDataset: function() {
return this.chart.data.datasets[this.index];
},
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
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);
},
removeElement: function(index) {
this.getDataset().metaData.splice(index, 1);
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var numData = this.getDataset().data.length;
var numPoints = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numPoints) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numPoints - numData)
} else if (numData > numPoints) {
// Add new elements
for (var index = numPoints; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
update: function update(reset) {
this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) - 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.chart.data.datasets.length;
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 = 1 / this.getDataset().data.length * 2;
var startAngle = (-0.5 * Math.PI) + (Math.PI * circumference) * index;
var endAngle = startAngle + (circumference * Math.PI);
var resetModel = {
x: this.chart.chart.width / 2,
y: this.chart.chart.height / 2,
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,
// Desired view properties
_model: reset ? resetModel : {
x: this.chart.chart.width / 2,
y: this.chart.chart.height / 2,
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 (this.getDataset().total > 0) {
return (Math.PI * 2) * (value / this.getDataset().total);
} else {
return 0;
}
},
updateScaleRange: function() {
helpers.extend(this.chart.scale, {
size: helpers.min([this.chart.width, this.chart.height]),
xCenter: this.chart.width / 2,
yCenter: this.chart.height / 2
});
},
});
return;
Chart.Type.extend({});
}).call(this);
+270
Ver Arquivo
@@ -0,0 +1,270 @@
(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 = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.controllers.radar.prototype, {
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
linkScales: function() {
// No need. Single scale only
},
getDataset: function() {
return this.chart.data.datasets[this.index];
},
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
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();
},
removeElement: function(index) {
this.getDataset().metaData.splice(index, 1);
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var numData = this.getDataset().data.length;
var numPoints = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numPoints) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numPoints - numData)
} else if (numData > numPoints) {
// Add new elements
for (var index = numPoints; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
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: 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
skipNull: this.getDataset().skipNull !== undefined ? this.getDataset().skipNull : this.chart.options.elements.line.skipNull,
drawNull: this.getDataset().drawNull !== undefined ? this.getDataset().drawNull : this.chart.options.elements.line.drawNull,
// 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,
// 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 : 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),
skip: point.custom && point.custom.skip ? point.custom.skip : this.getDataset().data[index] === null,
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius),
},
});
},
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
);
point._model.controlPointPreviousX = controlPoints.previous.x;
point._model.controlPointNextX = controlPoints.next.x;
// Prevent the bezier going outside of the bounds of the graph
// Cap outer bezier handles to the upper/lower scale bounds
if (controlPoints.next.y > this.chart.chartArea.bottom) {
point._model.controlPointNextY = this.chart.chartArea.bottom;
} else if (controlPoints.next.y < this.chart.chartArea.top) {
point._model.controlPointNextY = this.chart.chartArea.top;
} else {
point._model.controlPointNextY = controlPoints.next.y;
}
// Cap inner bezier handles to the upper/lower scale bounds
if (controlPoints.previous.y > this.chart.chartArea.bottom) {
point._model.controlPointPreviousY = this.chart.chartArea.bottom;
} else if (controlPoints.previous.y < this.chart.chartArea.top) {
point._model.controlPointPreviousY = this.chart.chartArea.top;
} else {
point._model.controlPointPreviousY = controlPoints.previous.y;
}
// 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);
+112
Ver Arquivo
@@ -0,0 +1,112 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.animation = {
duration: 1000,
easing: "easeOutQuart",
onProgress: function() {},
onComplete: function() {},
};
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.currentStep == this.animations[i].animationObject.numSteps) {
// 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);
+485
Ver Arquivo
@@ -0,0 +1,485 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
previous = 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.data = this.config.data;
this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});
this.id = helpers.uid();
//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.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,
data: this.data,
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,
data: this.data,
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,
data: this.data,
chart: this.chart,
});
this.scale = scale;
this.scales['radialScale'] = scale;
}
Chart.scaleService.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);
return;
}
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) {
Chart.scaleService.update(this, this.chart.width, this.chart.height);
// Make sure dataset controllers are updated and new controllers are reset
this.buildOrUpdateControllers(true);
// 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 ((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.onAnimationProgress;
animation.onAnimationComplete = this.options.onAnimationComplete;
Chart.animationService.addAnimation(this, animation, duration, lazy);
} else {
this.draw();
if (this.options.onAnimationComplete && this.options.onAnimationComplete.call) {
this.options.onAnimationComplete.call(this);
}
}
return this;
},
draw: function(ease) {
var easingDecimal = ease || 1;
this.clear();
// Draw all the scales
helpers.each(this.scales, function(scale) {
scale.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) {
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) {
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 = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
helpers.each(dataset.metaData, function(element, index) {
if (element.inLabelRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
}
}, this);
}, this);
return elementsArray;
},
getDatasetAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; datasetIndex++) {
for (var elementIndex = 0; elementIndex < this.data.datasets[datasetIndex].metaData.length; elementIndex++) {
if (this.data.datasets[datasetIndex].metaData[elementIndex].inLabelRange(eventPosition.x, eventPosition.y)) {
helpers.each(this.data.datasets[datasetIndex].metaData, function(element, index) {
elementsArray.push(element);
}, this);
}
}
}
return elementsArray.length ? elementsArray : [];
},
generateLegend: function generateLegend() {
return helpers.template(this.options.legendTemplate, 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,
_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 || [];
// Find Active Elements
if (e.type == 'mouseout') {
this.active = [];
} else {
this.active = function() {
switch (this.options.hover.mode) {
case 'single':
return this.getElementAtEvent(e);
case 'label':
return this.getElementsAtEvent(e);
case 'dataset':
return this.getDatasetAtEvent(e);
default:
return e;
}
}.call(this);
}
// 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);
}
}
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++) {
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 i = 0; i < this.active.length; i++) {
this.data.datasets[this.active[i]._datasetIndex].controller.setHoverStyle(this.active[i]);
}
break;
default:
// Don't change anything
}
}
// Built in Tooltips
if (this.options.tooltips.enabled || this.options.tooltips.custom) {
// The usual updates
this.tooltip.initialize();
// Active
if (this.active.length) {
this.tooltip._model.opacity = 1;
helpers.extend(this.tooltip, {
_active: this.active,
});
this.tooltip.update();
} else {
// Inactive
this.tooltip._model.opacity = 0;
}
}
// 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);
// If entering, leaving, or changing elements, animate the change via pivot
if ((!this.lastActive.length && this.active.length) ||
(this.lastActive.length && !this.active.length) ||
(this.lastActive.length && this.active.length && changed)) {
this.stop();
// 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 Active
this.lastActive = this.active;
return this;
},
});
}).call(this);
+92
Ver Arquivo
@@ -0,0 +1,92 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
previous = 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') {
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 ? 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);
+880
Ver Arquivo
@@ -0,0 +1,880 @@
(function() {
"use strict";
//Declare root variable - window in the browser, global on the server
var root = this,
previous = 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;
},
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 (window.console && typeof window.console.warn === "function") console.warn(str);
},
amd = helpers.amd = (typeof define === 'function' && define.amd),
//-- 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
var d01 = Math.sqrt(Math.pow(MiddlePoint.x - FirstPoint.x, 2) + Math.pow(MiddlePoint.y - FirstPoint.y, 2)),
d12 = Math.sqrt(Math.pow(AfterPoint.x - MiddlePoint.x, 2) + Math.pow(AfterPoint.y - MiddlePoint.y, 2)),
fa = t * d01 / (d01 + d12), // scaling factor for triangle Ta
fb = t * d12 / (d01 + d12);
return {
previous: {
x: MiddlePoint.x - fa * (AfterPoint.x - FirstPoint.x),
y: MiddlePoint.y - fa * (AfterPoint.y - FirstPoint.y)
},
next: {
x: MiddlePoint.x + fb * (AfterPoint.x - FirstPoint.x),
y: MiddlePoint.y + fb * (AfterPoint.y - FirstPoint.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);
},
/* jshint ignore:start */
// Blows up jshint errors based on the new Function constructor
//Templating methods
//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/
templateStringCache = {},
template = helpers.template = function(templateString, valuesObject) {
// If templateString is function rather than string-template - call the function for valuesObject
if (templateString instanceof Function) {
return templateString(valuesObject);
}
function tmpl(str, data) {
// Figure out if we're getting a template, or if we need to
// load the template - and be sure to cache the result.
var fn;
if (templateStringCache.hasOwnProperty(str)) {
fn = templateStringCache[str];
} else {
// Generate a reusable function that will serve as a template
// generator (and which will be cached).
var functionCode = "var p=[],print=function(){p.push.apply(p,arguments);};" +
// Introduce the data as local variables using with(){}
"with(obj){p.push('" +
// Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")
.split("<%").join("\t")
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
.replace(/\t=(.*?)%>/g, "',$1,'")
.split("\t").join("');")
.split("%>").join("p.push('")
.split("\r").join("\\'") +
"');}return p.join('');";
fn = new Function("obj", functionCode);
// Cache the result
templateStringCache[str] = fn;
}
// Provide some basic currying to the user
return data ? fn(data) : fn;
}
return tmpl(templateString, valuesObject);
},
/* jshint ignore:end */
//--Animation methods
//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) {
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;
chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
if (window.devicePixelRatio !== 1) {
ctx.canvas.height = height * window.devicePixelRatio;
ctx.canvas.width = width * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
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 || window.devicePixelRatio;
}
},
//-- 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 (!window.Color) {
console.log('Color.js not found!');
return color;
}
return window.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.remove();
}
},
isArray = helpers.isArray = function(obj) {
if (!Array.isArray) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return Array.isArray(obj);
};
}).call(this);
Arquivo executável
+115
Ver Arquivo
@@ -0,0 +1,115 @@
/*!
* 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);
// Always bind this so that if the responsive state changes we still work
var _this = this;
Chart.helpers.addResizeListener(context.canvas.parentNode, function() {
if (config.options.responsive) {
_this.controller.resize();
}
});
if (config) {
this.controller = new Chart.Controller(this);
return this.controller;
}
return 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", "touchend"],
hover: {
onHover: null,
mode: 'single',
animationDuration: 400,
},
onClick: null,
defaultColor: 'rgba(0,0,0,0.1)',
// Element defaults defined in element extensions
elements: {},
// Legend template string
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i = 0; i < data.datasets.length; i++){%><li><span style=\"background-color:<%=data.datasets[i].backgroundColor%>\"><%if(data.datasets[i].label){%><%=data.datasets[i].label%><%}%></span></li><%}%></ul>",
},
};
if (typeof amd !== 'undefined') {
define(function() {
return Chart;
});
} else if (typeof module === 'object' && module.exports) {
module.exports = Chart;
}
root.Chart = Chart;
Chart.noConflict = function() {
root.Chart = previous;
return Chart;
};
}).call(this);
+527
Ver Arquivo
@@ -0,0 +1,527 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.scale = {
display: true,
// grid line settings
gridLines: {
show: 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
show: false,
},
// label settings
ticks: {
beginAtZero: false,
fontSize: 12,
fontStyle: "normal",
fontColor: "#666",
fontFamily: "Helvetica Neue",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%=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: 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();
// 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: helpers.noop,
//
beforeSetDimensions: helpers.noop,
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
this.width = this.maxWidth;
} else {
this.height = this.maxHeight;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
},
afterSetDimensions: helpers.noop,
//
beforeBuildTicks: helpers.noop,
buildTicks: helpers.noop,
afterBuildTicks: helpers.noop,
beforeTickToLabelConversion: helpers.noop,
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);
} else {
return helpers.template(this.options.ticks.template, {
value: numericalTick
});
}
}, this);
},
afterTickToLabelConversion: helpers.noop,
//
beforeCalculateTickRotation: helpers.noop,
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;
var firstRotatedWidth;
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: helpers.noop,
//
beforeFit: helpers.noop,
fit: function() {
this.minSize = {
width: 0,
height: 0,
};
// Width
if (this.isHorizontal()) {
this.minSize.width = this.maxWidth; // fill all the width
} else {
this.minSize.width = this.options.gridLines.show && this.options.display ? 10 : 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.gridLines.show && 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.show) {
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.show && 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.
var maxLabelHeight = this.maxHeight - this.minSize.height;
var longestLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * 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);
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: helpers.noop,
// Shared Methods
isHorizontal: function() {
return this.options.position == "top" || this.options.position == "bottom";
},
// 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;
}
return this.left + Math.round(pixel);
} 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;
return this.left + Math.round(valueOffset);
} else {
return this.top + (decimal * (this.height / this.ticks.length));
}
},
// 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;
// Make sure we draw text in the correct color
this.ctx.fillStyle = this.options.ticks.fontColor;
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 ((this.options.ticks.fontSize + 4) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) {
skipRatio = 1 + Math.floor(((this.options.ticks.fontSize + 4) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
}
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.show) {
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.show) {
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 = this.font;
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.show) {
// Draw the scale label
this.ctx.textAlign = "center";
this.ctx.textBaseline = 'middle';
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) {
var yLineValue = this.getPixelForTick(index); // xvalues for grid lines
if (this.options.gridLines.show) {
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.show) {
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 = this.font;
this.ctx.textBaseline = "middle";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, this);
if (this.options.scaleLabel.show) {
// 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.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);
+335
Ver Arquivo
@@ -0,0 +1,335 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
// The scale service is used to resize charts along with all of their axes. We make this as
// a service where scales are registered with their respective charts so that changing the
// scales does not require
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.scaleMerge(Chart.defaults.scale, defaults);
},
getScaleConstructor: function(type) {
return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
},
getScaleDefaults: function(type) {
return this.defaults.hasOwnProperty(type) ? this.defaults[type] : {};
},
// The interesting function
update: function(chartInstance, width, height) {
var xPadding = width > 30 ? 5 : 2;
var yPadding = height > 30 ? 5 : 2;
if (chartInstance) {
var leftScales = helpers.where(chartInstance.scales, function(scaleInstance) {
return scaleInstance.options.position == "left";
});
var rightScales = helpers.where(chartInstance.scales, function(scaleInstance) {
return scaleInstance.options.position == "right";
});
var topScales = helpers.where(chartInstance.scales, function(scaleInstance) {
return scaleInstance.options.position == "top";
});
var bottomScales = helpers.where(chartInstance.scales, function(scaleInstance) {
return scaleInstance.options.position == "bottom";
});
// Scales that overlay the chartarea such as the radialLinear scale
var chartAreaScales = helpers.where(chartInstance.scales, function(scaleInstance) {
return scaleInstance.options.position == "chartArea";
});
// Essentially we now have any number of scales 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
// |------------------------------------------------------|
// | | T1 | |
// |----|-----|-------------------------------------|-----|
// | | | | |
// | L1 | L2 | Chart area | R1 |
// | | | | |
// | | | | |
// |----|-----|-------------------------------------|-----|
// | | B1 | |
// | | | |
// |------------------------------------------------------|
// 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 scale the maximum size it can be. The scale 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; // min 50%
var chartHeight = height / 2; // min 50%
chartWidth -= (2 * xPadding);
chartHeight -= (2 * yPadding);
// Step 2
var verticalScaleWidth = (width - chartWidth) / (leftScales.length + rightScales.length);
// Step 3
var horizontalScaleHeight = (height - chartHeight) / (topScales.length + bottomScales.length);
// Step 4;
var minimumScaleSizes = [];
var verticalScaleMinSizeFunction = function(scaleInstance) {
var minSize = scaleInstance.update(verticalScaleWidth, chartHeight);
minimumScaleSizes.push({
horizontal: false,
minSize: minSize,
scale: scaleInstance,
});
};
var horizontalScaleMinSizeFunction = function(scaleInstance) {
var minSize = scaleInstance.update(chartWidth, horizontalScaleHeight);
minimumScaleSizes.push({
horizontal: true,
minSize: minSize,
scale: scaleInstance,
});
};
// vertical scales
helpers.each(leftScales, verticalScaleMinSizeFunction);
helpers.each(rightScales, verticalScaleMinSizeFunction);
// horizontal scales
helpers.each(topScales, horizontalScaleMinSizeFunction);
helpers.each(bottomScales, horizontalScaleMinSizeFunction);
// Step 5
var maxChartHeight = height - (2 * yPadding);
var maxChartWidth = width - (2 * xPadding);
helpers.each(minimumScaleSizes, function(wrapper) {
if (wrapper.horizontal) {
maxChartHeight -= wrapper.minSize.height;
} else {
maxChartWidth -= wrapper.minSize.width;
}
});
// At this point, maxChartHeight and maxChartWidth are the size the chart area could
// be if the axes are drawn at their minimum sizes.
// Step 6
var verticalScaleFitFunction = function(scaleInstance) {
var wrapper = helpers.findNextWhere(minimumScaleSizes, function(wrapper) {
return wrapper.scale === scaleInstance;
});
if (wrapper) {
scaleInstance.update(wrapper.minSize.width, maxChartHeight);
}
};
var horizontalScaleFitFunction = function(scaleInstance) {
var wrapper = helpers.findNextWhere(minimumScaleSizes, function(wrapper) {
return wrapper.scale === scaleInstance;
});
var scaleMargin = {
left: totalLeftWidth,
right: totalRightWidth,
top: 0,
bottom: 0,
};
if (wrapper) {
scaleInstance.update(maxChartWidth, wrapper.minSize.height, scaleMargin);
}
};
var totalLeftWidth = xPadding;
var totalRightWidth = xPadding;
var totalTopHeight = yPadding;
var totalBottomHeight = yPadding;
helpers.each(leftScales, verticalScaleFitFunction);
helpers.each(rightScales, verticalScaleFitFunction);
// Figure out how much margin is on the left and right of the horizontal axes
helpers.each(leftScales, function(scaleInstance) {
totalLeftWidth += scaleInstance.width;
});
helpers.each(rightScales, function(scaleInstance) {
totalRightWidth += scaleInstance.width;
});
helpers.each(topScales, horizontalScaleFitFunction);
helpers.each(bottomScales, horizontalScaleFitFunction);
helpers.each(topScales, function(scaleInstance) {
totalTopHeight += scaleInstance.height;
});
helpers.each(bottomScales, function(scaleInstance) {
totalBottomHeight += scaleInstance.height;
});
// Let the left scale know the final margin
helpers.each(leftScales, function(scaleInstance) {
var wrapper = helpers.findNextWhere(minimumScaleSizes, function(wrapper) {
return wrapper.scale === scaleInstance;
});
var scaleMargin = {
left: 0,
right: 0,
top: totalTopHeight,
bottom: totalBottomHeight
};
if (wrapper) {
scaleInstance.update(wrapper.minSize.width, maxChartHeight, scaleMargin);
}
});
helpers.each(rightScales, function(scaleInstance) {
var wrapper = helpers.findNextWhere(minimumScaleSizes, function(wrapper) {
return wrapper.scale === scaleInstance;
});
var scaleMargin = {
left: 0,
right: 0,
top: totalTopHeight,
bottom: totalBottomHeight
};
if (wrapper) {
scaleInstance.update(wrapper.minSize.width, maxChartHeight, scaleMargin);
}
});
// Recalculate because the size of each scale might have changed slightly due to the margins (label rotation for instance)
totalLeftWidth = xPadding;
totalRightWidth = xPadding;
totalTopHeight = yPadding;
totalBottomHeight = yPadding;
helpers.each(leftScales, function(scaleInstance) {
totalLeftWidth += scaleInstance.width;
});
helpers.each(rightScales, function(scaleInstance) {
totalRightWidth += scaleInstance.width;
});
helpers.each(topScales, function(scaleInstance) {
totalTopHeight += scaleInstance.height;
});
helpers.each(bottomScales, function(scaleInstance) {
totalBottomHeight += scaleInstance.height;
});
// Figure out if our chart area changed. This would occur if the dataset scale 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 newMaxChartHeight = height - totalTopHeight - totalBottomHeight;
var newMaxChartWidth = width - totalLeftWidth - totalRightWidth;
if (newMaxChartWidth !== maxChartWidth || newMaxChartHeight !== maxChartHeight) {
helpers.each(leftScales, function(scale) {
scale.height = newMaxChartHeight;
});
helpers.each(rightScales, function(scale) {
scale.height = newMaxChartHeight;
});
helpers.each(topScales, function(scale) {
scale.width = newMaxChartWidth;
});
helpers.each(bottomScales, function(scale) {
scale.width = newMaxChartWidth;
});
maxChartHeight = newMaxChartHeight;
maxChartWidth = newMaxChartWidth;
}
// Step 7
// Position the scales
var left = xPadding;
var top = yPadding;
var right = 0;
var bottom = 0;
var verticalScalePlacer = function(scaleInstance) {
scaleInstance.left = left;
scaleInstance.right = left + scaleInstance.width;
scaleInstance.top = totalTopHeight;
scaleInstance.bottom = totalTopHeight + maxChartHeight;
// Move to next point
left = scaleInstance.right;
};
var horizontalScalePlacer = function(scaleInstance) {
scaleInstance.left = totalLeftWidth;
scaleInstance.right = totalLeftWidth + maxChartWidth;
scaleInstance.top = top;
scaleInstance.bottom = top + scaleInstance.height;
// Move to next point
top = scaleInstance.bottom;
};
helpers.each(leftScales, verticalScalePlacer);
helpers.each(topScales, horizontalScalePlacer);
// Account for chart width and height
left += maxChartWidth;
top += maxChartHeight;
helpers.each(rightScales, verticalScalePlacer);
helpers.each(bottomScales, horizontalScalePlacer);
// Step 8
chartInstance.chartArea = {
left: totalLeftWidth,
top: totalTopHeight,
right: totalLeftWidth + maxChartWidth,
bottom: totalTopHeight + maxChartHeight,
};
// Step 9
helpers.each(chartAreaScales, function(scaleInstance) {
scaleInstance.left = chartInstance.chartArea.left;
scaleInstance.top = chartInstance.chartArea.top;
scaleInstance.right = chartInstance.chartArea.right;
scaleInstance.bottom = chartInstance.chartArea.bottom;
scaleInstance.update(maxChartWidth, maxChartHeight);
});
}
}
};
}).call(this);
+347
Ver Arquivo
@@ -0,0 +1,347 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.defaults.global.tooltips = {
enabled: true,
custom: null,
backgroundColor: "rgba(0,0,0,0.8)",
fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
fontSize: 10,
fontStyle: "normal",
fontColor: "#fff",
titleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
titleFontSize: 12,
titleFontStyle: "bold",
titleFontColor: "#fff",
yPadding: 6,
xPadding: 6,
caretSize: 8,
cornerRadius: 6,
xOffset: 10,
template: [
'<% if(label){ %>',
'<%=label %>: ',
'<% } %>',
'<%=value %>',
].join(''),
multiTemplate: [
'<%if (datasetLabel){ %>',
'<%=datasetLabel %>: ',
'<% } %>',
'<%=value %>'
].join(''),
multiKeyBackground: '#fff',
};
Chart.Tooltip = Chart.Element.extend({
initialize: function() {
var options = this._options;
helpers.extend(this, {
_model: {
// Positioning
xPadding: options.tooltips.xPadding,
yPadding: options.tooltips.yPadding,
xOffset: options.tooltips.xOffset,
// Labels
textColor: options.tooltips.fontColor,
_fontFamily: options.tooltips.fontFamily,
_fontStyle: options.tooltips.fontStyle,
fontSize: options.tooltips.fontSize,
// Title
titleTextColor: options.tooltips.titleFontColor,
_titleFontFamily: options.tooltips.titleFontFamily,
_titleFontStyle: options.tooltips.titleFontStyle,
titleFontSize: options.tooltips.titleFontSize,
// Appearance
caretHeight: options.tooltips.caretSize,
cornerRadius: options.tooltips.cornerRadius,
backgroundColor: options.tooltips.backgroundColor,
opacity: 0,
legendColorBackground: options.tooltips.multiKeyBackground,
},
});
},
update: function() {
var ctx = this._chart.ctx;
switch (this._options.hover.mode) {
case 'single':
helpers.extend(this._model, {
text: helpers.template(this._options.tooltips.template, {
// These variables are available in the template function. Add others here
element: this._active[0],
value: this._data.datasets[this._active[0]._datasetIndex].data[this._active[0]._index],
label: this._active[0]._model.label !== undefined ? this._active[0]._model.label : this._data.labels ? this._data.labels[this._active[0]._index] : '',
}),
});
var tooltipPosition = this._active[0].tooltipPosition();
helpers.extend(this._model, {
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
caretPadding: tooltipPosition.padding
});
break;
case 'label':
// Tooltip Content
var dataArray,
dataIndex;
var labels = [],
colors = [];
for (var i = this._data.datasets.length - 1; i >= 0; i--) {
dataArray = this._data.datasets[i].metaData;
dataIndex = helpers.indexOf(dataArray, this._active[0]);
if (dataIndex !== -1) {
break;
}
}
var medianPosition = (function(index) {
// Get all the points at that particular index
var elements = [],
dataCollection,
xPositions = [],
yPositions = [],
xMax,
yMax,
xMin,
yMin;
helpers.each(this._data.datasets, function(dataset) {
dataCollection = dataset.metaData;
if (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()) {
elements.push(dataCollection[dataIndex]);
}
}, this);
// Reverse labels if stacked
helpers.each(this._options.stacked ? elements.reverse() : elements, function(element) {
xPositions.push(element._view.x);
yPositions.push(element._view.y);
//Include any colour information about the element
labels.push(helpers.template(this._options.tooltips.multiTemplate, {
// These variables are available in the template function. Add others here
element: element,
datasetLabel: this._data.datasets[element._datasetIndex].label,
value: this._data.datasets[element._datasetIndex].data[element._index],
}));
colors.push({
fill: element._view.backgroundColor,
stroke: element._view.borderColor
});
}, this);
yMin = helpers.min(yPositions);
yMax = helpers.max(yPositions);
xMin = helpers.min(xPositions);
xMax = helpers.max(xPositions);
return {
x: (xMin > this._chart.width / 2) ? xMin : xMax,
y: (yMin + yMax) / 2,
};
}).call(this, dataIndex);
// Apply for now
helpers.extend(this._model, {
x: medianPosition.x,
y: medianPosition.y,
labels: labels,
title: (function() {
return this._data.timeLabels ? this._data.timeLabels[this._active[0]._index] :
(this._data.labels && this._data.labels.length) ? this._data.labels[this._active[0]._index] :
'';
}).call(this),
legendColors: colors,
legendBackgroundColor: this._options.tooltips.multiKeyBackground,
});
// Calculate Appearance Tweaks
this._model.height = (labels.length * this._model.fontSize) + ((labels.length - 1) * (this._model.fontSize / 2)) + (this._model.yPadding * 2) + this._model.titleFontSize * 1.5;
var titleWidth = ctx.measureText(this._model.title).width,
//Label has a legend square as well so account for this.
labelWidth = helpers.longestText(ctx, this.font, labels) + this._model.fontSize + 3,
longestTextWidth = helpers.max([labelWidth, titleWidth]);
this._model.width = longestTextWidth + (this._model.xPadding * 2);
var halfHeight = this._model.height / 2;
//Check to ensure the height will fit on the canvas
if (this._model.y - halfHeight < 0) {
this._model.y = halfHeight;
} else if (this._model.y + halfHeight > this._chart.height) {
this._model.y = this._chart.height - halfHeight;
}
//Decide whether to align left or right based on position on canvas
if (this._model.x > this._chart.width / 2) {
this._model.x -= this._model.xOffset + this._model.width;
} else {
this._model.x += this._model.xOffset;
}
break;
}
return this;
},
draw: function() {
var ctx = this._chart.ctx;
var vm = this._view;
switch (this._options.hover.mode) {
case 'single':
ctx.font = helpers.fontString(vm.fontSize, vm._fontStyle, vm._fontFamily);
vm.xAlign = "center";
vm.yAlign = "above";
//Distance between the actual element.y position and the start of the tooltip caret
var caretPadding = vm.caretPadding || 2;
var tooltipWidth = ctx.measureText(vm.text).width + 2 * vm.xPadding,
tooltipRectHeight = vm.fontSize + 2 * vm.yPadding,
tooltipHeight = tooltipRectHeight + vm.caretHeight + caretPadding;
if (vm.x + tooltipWidth / 2 > this._chart.width) {
vm.xAlign = "left";
} else if (vm.x - tooltipWidth / 2 < 0) {
vm.xAlign = "right";
}
if (vm.y - tooltipHeight < 0) {
vm.yAlign = "below";
}
var tooltipX = vm.x - tooltipWidth / 2,
tooltipY = vm.y - tooltipHeight;
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(vm.opacity).rgbString();
// Custom Tooltips
if (this._options.tooltips.custom) {
this._options.tooltips.custom(this);
}
if (!this._options.tooltips.enabled) {
return;
}
switch (vm.yAlign) {
case "above":
//Draw a caret above the x/y
ctx.beginPath();
ctx.moveTo(vm.x, vm.y - caretPadding);
ctx.lineTo(vm.x + vm.caretHeight, vm.y - (caretPadding + vm.caretHeight));
ctx.lineTo(vm.x - vm.caretHeight, vm.y - (caretPadding + vm.caretHeight));
ctx.closePath();
ctx.fill();
break;
case "below":
tooltipY = vm.y + caretPadding + vm.caretHeight;
//Draw a caret below the x/y
ctx.beginPath();
ctx.moveTo(vm.x, vm.y + caretPadding);
ctx.lineTo(vm.x + vm.caretHeight, vm.y + caretPadding + vm.caretHeight);
ctx.lineTo(vm.x - vm.caretHeight, vm.y + caretPadding + vm.caretHeight);
ctx.closePath();
ctx.fill();
break;
}
switch (vm.xAlign) {
case "left":
tooltipX = vm.x - tooltipWidth + (vm.cornerRadius + vm.caretHeight);
break;
case "right":
tooltipX = vm.x - (vm.cornerRadius + vm.caretHeight);
break;
}
helpers.drawRoundedRectangle(ctx, tooltipX, tooltipY, tooltipWidth, tooltipRectHeight, vm.cornerRadius);
ctx.fill();
ctx.fillStyle = helpers.color(vm.textColor).alpha(vm.opacity).rgbString();
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(vm.text, tooltipX + tooltipWidth / 2, tooltipY + tooltipRectHeight / 2);
break;
case 'label':
// Custom Tooltips
if (this._options.tooltips.custom) {
this._options.tooltips.custom(this);
}
if (!this._options.tooltips.enabled) {
return;
}
helpers.drawRoundedRectangle(ctx, vm.x, vm.y - vm.height / 2, vm.width, vm.height, vm.cornerRadius);
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(vm.opacity).rgbString();
ctx.fill();
ctx.closePath();
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.fillStyle = helpers.color(vm.titleTextColor).alpha(vm.opacity).rgbString();
ctx.font = helpers.fontString(vm.fontSize, vm._titleFontStyle, vm._titleFontFamily);
ctx.fillText(vm.title, vm.x + vm.xPadding, this.getLineHeight(0));
ctx.font = helpers.fontString(vm.fontSize, vm._fontStyle, vm._fontFamily);
helpers.each(vm.labels, function(label, index) {
ctx.fillStyle = helpers.color(vm.textColor).alpha(vm.opacity).rgbString();
ctx.fillText(label, vm.x + vm.xPadding + vm.fontSize + 3, this.getLineHeight(index + 1));
//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)
//ctx.clearRect(vm.x + vm.xPadding, this.getLineHeight(index + 1) - vm.fontSize/2, vm.fontSize, vm.fontSize);
//Instead we'll make a white filled block to put the legendColour palette over.
ctx.fillStyle = helpers.color(vm.legendColors[index].stroke).alpha(vm.opacity).rgbString();
ctx.fillRect(vm.x + vm.xPadding - 1, this.getLineHeight(index + 1) - vm.fontSize / 2 - 1, vm.fontSize + 2, vm.fontSize + 2);
ctx.fillStyle = helpers.color(vm.legendColors[index].fill).alpha(vm.opacity).rgbString();
ctx.fillRect(vm.x + vm.xPadding, this.getLineHeight(index + 1) - vm.fontSize / 2, vm.fontSize, vm.fontSize);
}, this);
break;
}
},
getLineHeight: function(index) {
var baseLineHeight = this._view.y - (this._view.height / 2) + this._view.yPadding,
afterTitleIndex = index - 1;
//If the index is zero, we're getting the title
if (index === 0) {
return baseLineHeight + this._view.titleFontSize / 2;
} else {
return baseLineHeight + ((this._view.fontSize * 1.5 * afterTitleIndex) + this._view.fontSize / 2) + this._view.titleFontSize * 1.5;
}
},
});
}).call(this);
+96
Ver Arquivo
@@ -0,0 +1,96 @@
/*!
* 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);
+192
Ver Arquivo
@@ -0,0 +1,192 @@
/*!
* 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
skipNull: true,
drawNull: false,
};
Chart.elements.Line = Chart.Element.extend({
draw: function() {
var vm = this._view;
var ctx = this._chart.ctx;
var first = this._children[0];
var last = this._children[this._children.length - 1];
ctx.save();
// Draw the background first (so the border is always on top)
helpers.each(this._children, function(point, index) {
var previous = helpers.previousItem(this._children, index);
var next = helpers.nextItem(this._children, index);
// First point only
if (index === 0) {
ctx.moveTo(point._view.x, point._view.y);
return;
}
// Start Skip and drag along scale baseline
if (point._view.skip && vm.skipNull && !this._loop) {
ctx.lineTo(previous._view.x, point._view.y);
ctx.moveTo(next._view.x, point._view.y);
}
// End Skip Stright line from the base line
else if (previous._view.skip && vm.skipNull && !this._loop) {
ctx.moveTo(point._view.x, previous._view.y);
ctx.lineTo(point._view.x, point._view.y);
}
if (previous._view.skip && vm.skipNull) {
ctx.moveTo(point._view.x, point._view.y);
}
// Normal Bezier Curve
else {
if (vm.tension > 0) {
ctx.bezierCurveTo(
previous._view.controlPointNextX,
previous._view.controlPointNextY,
point._view.controlPointPreviousX,
point._view.controlPointPreviousY,
point._view.x,
point._view.y
);
} else {
ctx.lineTo(point._view.x, point._view.y);
}
}
}, this);
// For radial scales, loop back around to the first point
if (this._loop) {
if (vm.tension > 0 && !first._view.skip) {
ctx.bezierCurveTo(
last._view.controlPointNextX,
last._view.controlPointNextY,
first._view.controlPointPreviousX,
first._view.controlPointPreviousY,
first._view.x,
first._view.y
);
} else {
ctx.lineTo(first._view.x, first._view.y);
}
}
// If we had points and want to fill this line, do so.
if (this._children.length > 0 && vm.fill) {
//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);
// First point only
if (index === 0) {
ctx.moveTo(point._view.x, point._view.y);
return;
}
// Start Skip and drag along scale baseline
if (point._view.skip && vm.skipNull && !this._loop) {
ctx.moveTo(previous._view.x, point._view.y);
ctx.moveTo(next._view.x, point._view.y);
return;
}
// End Skip Stright line from the base line
if (previous._view.skip && vm.skipNull && !this._loop) {
ctx.moveTo(point._view.x, previous._view.y);
ctx.moveTo(point._view.x, point._view.y);
return;
}
if (previous._view.skip && vm.skipNull) {
ctx.moveTo(point._view.x, point._view.y);
return;
}
// Normal Bezier Curve
if (vm.tension > 0) {
ctx.bezierCurveTo(
previous._view.controlPointNextX,
previous._view.controlPointNextY,
point._view.controlPointPreviousX,
point._view.controlPointPreviousY,
point._view.x,
point._view.y
);
} else {
ctx.lineTo(point._view.x, point._view.y);
}
}, this);
if (this._loop && !first._view.skip) {
if (vm.tension > 0) {
ctx.bezierCurveTo(
last._view.controlPointNextX,
last._view.controlPointNextY,
first._view.controlPointPreviousX,
first._view.controlPointPreviousY,
first._view.x,
first._view.y
);
} else {
ctx.lineTo(first._view.x, first._view.y);
}
}
ctx.stroke();
ctx.restore();
},
});
}).call(this);
+89
Ver Arquivo
@@ -0,0 +1,89 @@
/*!
* 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);
+97
Ver Arquivo
@@ -0,0 +1,97 @@
(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;
if (vm.y < vm.base) {
return {
x: vm.x,
y: vm.y
};
} else {
return {
x: vm.x,
y: vm.base
};
}
},
});
}).call(this);
+47
Ver Arquivo
@@ -0,0 +1,47 @@
(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.data.labels;
},
// 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.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var valueOffset = (valueWidth * index) + this.paddingLeft;
if (this.options.gridLines.offsetGridLines && includeOffset) {
valueOffset += (valueWidth / 2);
}
return this.left + Math.round(valueOffset);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
var valueHeight = innerHeight / Math.max((this.data.labels.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var valueOffset = (valueHeight * index) + this.paddingTop;
if (this.options.gridLines.offsetGridLines && includeOffset) {
valueOffset += (valueHeight / 2);
}
return this.top + Math.round(valueOffset);
}
},
});
Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
}).call(this);
+177
Ver Arquivo
@@ -0,0 +1,177 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
position: "left",
};
var LinearScale = Chart.Scale.extend({
buildTicks: function() {
// First Calculate the range
this.min = null;
this.max = null;
var positiveValues = [];
var negativeValues = [];
if (this.options.stacked) {
helpers.each(this.data.datasets, function(dataset) {
if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
helpers.each(dataset.data, function(rawValue, index) {
var value = this.getRightValue(rawValue);
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);
var values = positiveValues.concat(negativeValues);
this.min = helpers.min(values);
this.max = helpers.max(values);
} else {
helpers.each(this.data.datasets, function(dataset) {
if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
helpers.each(dataset.data, function(rawValue, index) {
var value = this.getRightValue(rawValue);
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++;
}
// 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(11, Math.ceil(this.width / 50));
} else {
// The factor of 2 used to scale the font size has been experimentally determined.
maxTicks = Math.min(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.
// 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;
}
}
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);
}
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);
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);
},
// 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 pixel;
var range = this.end - this.start;
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
pixel = this.left + (innerWidth / range * (this.getRightValue(value) - this.start));
return Math.round(pixel + this.paddingLeft);
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
pixel = (this.bottom - this.paddingBottom) - (innerHeight / range * (this.getRightValue(value) - this.start));
return Math.round(pixel);
}
},
// Get the correct value. If the value type is object get the x or y based on whether we are horizontal or not
getRightValue: function(rawValue) {
return (typeof(rawValue) === "object" && rawValue !== null) ? (this.isHorizontal() ? rawValue.x : rawValue.y) : rawValue;
},
});
Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);
}).call(this);
+161
Ver Arquivo
@@ -0,0 +1,161 @@
(function() {
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
position: "left",
// label settings
ticks: {
template: "<%var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));if (remain === 1 || remain === 2 || remain === 5) {%><%=value.toExponential()%><%} else {%><%= null %><%}%>",
}
};
var LogarithmicScale = Chart.Scale.extend({
buildTicks: function() {
// Calculate Range (we may break this out into it's own lifecycle function)
this.min = null;
this.max = null;
var values = [];
if (this.options.stacked) {
helpers.each(this.data.datasets, function(dataset) {
if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
helpers.each(dataset.data, function(rawValue, index) {
var value = this.getRightValue(rawValue);
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);
this.min = helpers.min(values);
this.max = helpers.max(values);
} else {
helpers.each(this.data.datasets, function(dataset) {
if (this.isHorizontal() ? dataset.xAxisID === this.id : dataset.yAxisID === this.id) {
helpers.each(dataset.data, function(rawValue, index) {
var value = this.getRightValue(rawValue);
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) {
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;
}
}
// 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 minExponent = Math.floor(helpers.log10(this.min));
var maxExponent = Math.ceil(helpers.log10(this.max));
for (var exponent = minExponent; exponent < maxExponent; ++exponent) {
for (var i = 1; i < 10; ++i) {
this.tickValues.push(i * Math.pow(10, exponent));
}
}
this.tickValues.push(1.0 * Math.pow(10, maxExponent));
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 value. If the value type is object get the x or y based on whether we are horizontal or not
getRightValue: function(rawValue) {
return typeof rawValue === "object" ? (this.isHorizontal() ? rawValue.x : rawValue.y) : rawValue;
},
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);
+396
Ver Arquivo
@@ -0,0 +1,396 @@
(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: {
show: 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.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);
},
buildTicks: function() {
this.min = null;
this.max = null;
helpers.each(this.data.datasets, function(dataset) {
helpers.each(dataset.data, function(value, index) {
if (value === null) 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++;
}
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(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.
// 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;
}
}
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);
},
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(helpers.template(this.options.ticks.template, {
value: this.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.cos(thisAngle) * distanceFromCenter) + this.xCenter,
y: (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.show) {
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.show) {
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.show) {
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.data.labels.length,
halfLabelsCount = this.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.data.labels[i], pointLabelPosition.x, pointLabelPosition.y);
}
}
}
}
});
Chart.scaleService.registerScaleType("radialLinear", LinearRadialScale, defaultConfig);
}).call(this);
+194
Ver Arquivo
@@ -0,0 +1,194 @@
(function() {
"use strict";
if (!window.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: [
'millisecond',
'second',
'minute',
'hour',
'day',
'week',
'month',
'quarter',
'year',
],
unit: {
'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,
},
}
};
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, // defaults to unit's corresponding unitFormat below or override using pattern string from http://momentjs.com/docs/#/displaying/format/
},
};
var TimeScale = Chart.Scale.extend({
buildTicks: function(index) {
this.ticks = [];
this.labelMoments = [];
// Parse each label into a moment
this.data.labels.forEach(function(label, index) {
var labelMoment = this.parseTime(label);
if (this.options.time.round) {
labelMoment.startOf(this.options.time.round);
}
this.labelMoments.push(labelMoment);
}, this);
// Find the first and last moments, and range
this.firstTick = moment.min.call(this, this.labelMoments).clone();
this.lastTick = moment.max.call(this, this.labelMoments).clone();
// Set unit override if applicable
if (this.options.time.unit) {
this.tickUnit = this.options.time.unit || 'day';
this.displayFormat = time.unit[this.tickUnit].display;
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 + 4;
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 = time.unit[this.tickUnit].display;
// Work our way up to comfort
helpers.each(time.units, function(format) {
if (this.tickRange <= labelCapacity) {
return;
}
this.tickUnit = format;
this.tickRange = Math.ceil(this.lastTick.diff(this.firstTick, this.tickUnit) + buffer);
this.displayFormat = time.unit[format].display;
}, this);
}
this.firstTick.startOf(this.tickUnit);
this.lastTick.endOf(this.tickUnit);
this.smallestLabelSeparation = this.width;
var i = 0;
for (i = 1; i < this.labelMoments.length; i++) {
this.smallestLabelSeparation = Math.min(this.smallestLabelSeparation, this.labelMoments[i].diff(this.labelMoments[i - 1], this.tickUnit, true));
}
// 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 (i = 0; i <= this.tickRange; ++i) {
this.ticks.push(this.firstTick.clone().add(i, this.tickUnit));
}
},
convertTicksToLabels: function() {
this.ticks = this.ticks.map(function(tick, index, ticks) {
var formattedTick = tick.format(this.options.time.displayFormat ? this.options.time.displayFormat : time.unit[this.tickUnit].display);
if (this.options.ticks.userCallback) {
return this.options.ticks.userCallback(formattedTick, index, ticks);
} else {
return formattedTick;
}
}, this);
},
getPixelForValue: function(value, index, datasetIndex, includeOffset) {
var offset = this.labelMoments[index].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 {
//return this.top + (decimal * (this.height / this.ticks.length));
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);
+586
Ver Arquivo
@@ -0,0 +1,586 @@
// Test the bar controller
describe('Bar controller tests', function() {
it('Should be constructed', function() {
var chart = {
data: {
datasets: [{
}, {
xAxisID: 'myXAxis',
yAxisID: 'myYAxis',
data: []
}]
}
};
var controller = new Chart.controllers.bar(chart, 1);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(1);
expect(chart.data.datasets[1].metaData).toEqual([]);
controller.updateIndex(0);
expect(controller.index).toBe(0);
});
it('Should use the first scale IDs if the dataset does not specify them', function() {
var chart = {
data: {
datasets: [{
}, {
data: []
}]
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.bar(chart, 1);
expect(chart.data.datasets[1].xAxisID).toBe('firstXScaleID');
expect(chart.data.datasets[1].yAxisID).toBe('firstYScaleID');
});
it('should correctly count the number of bar datasets', function() {
var chart = {
data: {
datasets: [{
type: 'line'
}, {
type: 'bar'
}, {
// no type, defaults to bar
}]
},
config: {
type: 'bar'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.bar(chart, 1);
expect(controller.getBarCount()).toBe(2);
});
it('Should create rectangle elements for each data item during initialization', function() {
var chart = {
data: {
datasets: [{}, {
data: [10, 15, 0, -4]
}]
},
config: {
type: 'bar'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.bar(chart, 1);
expect(chart.data.datasets[1].metaData.length).toBe(4); // 4 rectangles created
expect(chart.data.datasets[1].metaData[0] instanceof Chart.elements.Rectangle).toBe(true);
expect(chart.data.datasets[1].metaData[1] instanceof Chart.elements.Rectangle).toBe(true);
expect(chart.data.datasets[1].metaData[2] instanceof Chart.elements.Rectangle).toBe(true);
expect(chart.data.datasets[1].metaData[3] instanceof Chart.elements.Rectangle).toBe(true);
});
it('should remove elements', function() {
var chart = {
data: {
datasets: [{}, {
data: [10, 15, 0, -4]
}]
},
config: {
type: 'bar'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.bar(chart, 1);
controller.removeElement(1);
expect(chart.data.datasets[1].metaData.length).toBe(3);
});
it('should update elements', function() {
var data = {
datasets: [{
data: [1, 2],
label: 'dataset1',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}, {
data: [10, 15, 0, -4],
label: 'dataset2'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bar.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bar.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
data: data,
config: {
type: 'bar'
},
options: {
elements: {
rectangle: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.bar(chart, 1);
chart.data.datasets[1].data = [1, 2]; // remove 2 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[1].metaData.length).toBe(2);
var bar1 = chart.data.datasets[1].metaData[0];
var bar2 = chart.data.datasets[1].metaData[1];
expect(bar1._datasetIndex).toBe(1);
expect(bar1._index).toBe(0);
expect(bar1._xScale).toBe(chart.scales.firstXScaleID);
expect(bar1._yScale).toBe(chart.scales.firstYScaleID);
expect(bar1._model).toEqual({
x: 106.80000000000003,
y: 194,
label: 'label1',
datasetLabel: 'dataset2',
base: 194,
width: 12.240000000000002,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
});
expect(bar2._datasetIndex).toBe(1);
expect(bar2._index).toBe(1);
expect(bar2._xScale).toBe(chart.scales.firstXScaleID);
expect(bar2._yScale).toBe(chart.scales.firstYScaleID);
expect(bar2._model).toEqual({
x: 140.8,
y: -15,
label: 'label2',
datasetLabel: 'dataset2',
base: 194,
width: 12.240000000000002,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
});
chart.data.datasets[1].data = [1, 2, 3];
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[1].metaData.length).toBe(3); // should add a new meta data item
});
it ('should draw all bars', function() {
var data = {
datasets: [{}, {
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bar.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bar.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
data: data,
config: {
type: 'bar'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.bar(chart, 1);
spyOn(chart.data.datasets[1].metaData[0], 'draw');
spyOn(chart.data.datasets[1].metaData[1], 'draw');
spyOn(chart.data.datasets[1].metaData[2], 'draw');
spyOn(chart.data.datasets[1].metaData[3], 'draw');
controller.draw();
expect(chart.data.datasets[1].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[1].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[1].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[1].metaData[3].draw.calls.count()).toBe(1);
});
it ('should set hover styles on rectangles', function() {
var data = {
datasets: [{}, {
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bar.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bar.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
data: data,
config: {
type: 'bar'
},
options: {
elements: {
rectangle: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.bar(chart, 1);
controller.update();
var bar = chart.data.datasets[1].metaData[0];
controller.setHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(230, 0, 0)');
expect(bar._model.borderColor).toBe('rgb(0, 0, 230)');
expect(bar._model.borderWidth).toBe(2);
// Set a dataset style
chart.data.datasets[1].hoverBackgroundColor = 'rgb(128, 128, 128)';
chart.data.datasets[1].hoverBorderColor = 'rgb(0, 0, 0)';
chart.data.datasets[1].hoverBorderWidth = 5;
controller.setHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
expect(bar._model.borderColor).toBe('rgb(0, 0, 0)');
expect(bar._model.borderWidth).toBe(5);
// Should work with array styles so that we can set per bar
chart.data.datasets[1].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
chart.data.datasets[1].hoverBorderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
chart.data.datasets[1].hoverBorderWidth = [2.5, 5];
controller.setHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
expect(bar._model.borderWidth).toBe(2.5);
// Should allow a custom style
bar.custom = {
hoverBackgroundColor: 'rgb(255, 0, 0)',
hoverBorderColor: 'rgb(0, 255, 0)',
hoverBorderWidth: 1.5
};
controller.setHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
expect(bar._model.borderWidth).toBe(1.5);
});
it ('should remove a hover style from a bar', function() {
var data = {
datasets: [{}, {
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.bar.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.bar.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
data: data,
config: {
type: 'bar'
},
options: {
elements: {
rectangle: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.bar(chart, 1);
controller.update();
var bar = chart.data.datasets[1].metaData[0];
// Change default
chart.options.elements.rectangle.backgroundColor = 'rgb(128, 128, 128)';
chart.options.elements.rectangle.borderColor = 'rgb(15, 15, 15)';
chart.options.elements.rectangle.borderWidth = 3.14;
// Remove to defaults
controller.removeHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(128, 128, 128)');
expect(bar._model.borderColor).toBe('rgb(15, 15, 15)');
expect(bar._model.borderWidth).toBe(3.14);
// Should work with array styles so that we can set per bar
chart.data.datasets[1].backgroundColor = ['rgb(255, 255, 255)', 'rgb(128, 128, 128)'];
chart.data.datasets[1].borderColor = ['rgb(9, 9, 9)', 'rgb(0, 0, 0)'];
chart.data.datasets[1].borderWidth = [2.5, 5];
controller.removeHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(bar._model.borderColor).toBe('rgb(9, 9, 9)');
expect(bar._model.borderWidth).toBe(2.5);
// Should allow a custom style
bar.custom = {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1.5
};
controller.removeHoverStyle(bar);
expect(bar._model.backgroundColor).toBe('rgb(255, 0, 0)');
expect(bar._model.borderColor).toBe('rgb(0, 255, 0)');
expect(bar._model.borderWidth).toBe(1.5);
});
});
+431
Ver Arquivo
@@ -0,0 +1,431 @@
// Test the bar controller
describe('Doughnut controller tests', function() {
it('Should be constructed', function() {
var chart = {
data: {
datasets: [{
data: []
}]
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
});
it('Should create arc elements for each data item during initialization', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, 4]
}]
},
config: {
type: 'doughnut'
},
options: {
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 rectangles created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true);
});
it ('Should remove elements', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, 4]
}]
},
config: {
type: 'doughnut'
},
options: {
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
controller.removeElement(1);
expect(chart.data.datasets[0].metaData.length).toBe(3);
});
it ('Should reset and update elements', function() {
var chart = {
chart: {
width: 100,
height: 200,
},
data: {
datasets: [{
data: [10, 15, 0, 4]
}, {
data: [1]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)'
}
}
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
controller.reset(); // reset first
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
circumference: 2.166614539857563,
outerRadius: 49,
innerRadius: 36.75,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
circumference: 3.2499218097863447,
outerRadius: 49,
innerRadius: 36.75,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
circumference: 0,
outerRadius: 49,
innerRadius: 36.75,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
circumference: 0.8666458159430251,
outerRadius: 49,
innerRadius: 36.75,
});
controller.update();
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 50,
y: 100,
startAngle: Math.PI * -0.5,
endAngle: 0.5958182130626666,
circumference: 2.166614539857563,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label0',
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 50,
y: 100,
startAngle: 0.5958182130626666,
endAngle: 3.8457400228490113,
circumference: 3.2499218097863447,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label1'
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
x: 50,
y: 100,
startAngle: 3.8457400228490113,
endAngle: 3.8457400228490113,
circumference: 0,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label2'
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
x: 50,
y: 100,
startAngle: 3.8457400228490113,
endAngle: 4.712385838792036,
circumference: 0.8666458159430251,
outerRadius: 49,
innerRadius: 36.75,
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)',
label: 'label3'
});
// Change the amount of data and ensure that arcs are updated accordingly
chart.data.datasets[0].data = [1, 2]; // remove 2 elements from dataset 0
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(2);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
// Add data
chart.data.datasets[0].data = [1, 2, 3, 4];
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(4);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Arc).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Arc).toBe(true);
});
it ('should draw all arcs', function() {
var chart = {
chart: {
width: 100,
height: 200,
},
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
hoverBackgroundColor: 'rgb(255, 255, 255)'
}
}
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
controller.draw();
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[1].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
});
it ('should set the hover style of an arc', function() {
var chart = {
chart: {
width: 100,
height: 200,
},
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
}
}
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
controller.reset(); // reset first
controller.update();
var arc = chart.data.datasets[0].metaData[0];
controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(0, 0, 230)');
expect(arc._model.borderWidth).toBe(2);
// Set a dataset style to take precedence
chart.data.datasets[0].hoverBackgroundColor = 'rgb(9, 9, 9)';
chart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)';
chart.data.datasets[0].hoverBorderWidth = 1.56;
controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(1.56);
// Dataset styles can be an array
chart.data.datasets[0].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
chart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)'];
chart.data.datasets[0].hoverBorderWidth = [0.1, 1.56];
controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(0.1);
// Element custom styles also work
arc.custom = {
hoverBackgroundColor: 'rgb(7, 7, 7)',
hoverBorderColor: 'rgb(17, 17, 17)',
hoverBorderWidth: 3.14159,
};
controller.setHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
expect(arc._model.borderWidth).toBe(3.14159);
});
it ('should unset the hover style of an arc', function() {
var chart = {
chart: {
width: 100,
height: 200,
},
data: {
datasets: [{
data: [10, 15, 0, 4]
}],
labels: ['label0', 'label1', 'label2', 'label3']
},
config: {
type: 'doughnut'
},
options: {
animation: {
animateRotate: false,
animateScale: false
},
cutoutPercentage: 50,
elements: {
arc: {
backgroundColor: 'rgb(255, 0, 0)',
borderColor: 'rgb(0, 0, 255)',
borderWidth: 2,
}
}
}
};
var controller = new Chart.controllers.doughnut(chart, 0);
controller.reset(); // reset first
controller.update();
var arc = chart.data.datasets[0].metaData[0];
controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)');
expect(arc._model.borderColor).toBe('rgb(0, 0, 255)');
expect(arc._model.borderWidth).toBe(2);
// Set a dataset style to take precedence
chart.data.datasets[0].backgroundColor = 'rgb(9, 9, 9)';
chart.data.datasets[0].borderColor = 'rgb(18, 18, 18)';
chart.data.datasets[0].borderWidth = 1.56;
controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(1.56);
// Dataset styles can be an array
chart.data.datasets[0].backgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)'];
chart.data.datasets[0].borderColor = ['rgb(18, 18, 18)'];
chart.data.datasets[0].borderWidth = [0.1, 1.56];
controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)');
expect(arc._model.borderColor).toBe('rgb(18, 18, 18)');
expect(arc._model.borderWidth).toBe(0.1);
// Element custom styles also work
arc.custom = {
backgroundColor: 'rgb(7, 7, 7)',
borderColor: 'rgb(17, 17, 17)',
borderWidth: 3.14159,
};
controller.removeHoverStyle(arc);
expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)');
expect(arc._model.borderColor).toBe('rgb(17, 17, 17)');
expect(arc._model.borderWidth).toBe(3.14159);
});
});
+918
Ver Arquivo
@@ -0,0 +1,918 @@
// Test the line controller
describe('Line controller tests', function() {
it('Should be constructed', function() {
var chart = {
data: {
datasets: [{
xAxisID: 'myXAxis',
yAxisID: 'myYAxis',
data: []
}]
}
};
var controller = new Chart.controllers.line(chart, 0);
expect(controller).not.toBe(undefined);
expect(controller.index).toBe(0);
expect(chart.data.datasets[0].metaData).toEqual([]);
controller.updateIndex(1);
expect(controller.index).toBe(1);
});
it('Should use the first scale IDs if the dataset does not specify them', function() {
var chart = {
data: {
datasets: [{
data: []
}]
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.line(chart, 0);
expect(chart.data.datasets[0].xAxisID).toBe('firstXScaleID');
expect(chart.data.datasets[0].yAxisID).toBe('firstYScaleID');
});
it('Should create line elements and point elements for each data item during initialization', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'line'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.line(chart, 0);
expect(chart.data.datasets[0].metaData.length).toBe(4); // 4 points created
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaDataset instanceof Chart.elements.Line).toBe(true); // 1 line element
});
it('should remove elements', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'line'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.line(chart, 0);
controller.removeElement(0);
expect(chart.data.datasets[0].metaData.length).toBe(3);
});
it ('should draw all elements', function() {
var chart = {
data: {
datasets: [{
data: [10, 15, 0, -4]
}]
},
config: {
type: 'line'
},
options: {
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
}
};
var controller = new Chart.controllers.line(chart, 0);
spyOn(chart.data.datasets[0].metaDataset, 'draw');
spyOn(chart.data.datasets[0].metaData[0], 'draw');
spyOn(chart.data.datasets[0].metaData[1], 'draw');
spyOn(chart.data.datasets[0].metaData[2], 'draw');
spyOn(chart.data.datasets[0].metaData[3], 'draw');
controller.draw();
expect(chart.data.datasets[0].metaDataset.draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[0].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[2].draw.calls.count()).toBe(1);
expect(chart.data.datasets[0].metaData[3].draw.calls.count()).toBe(1);
});
it ('should update elements', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.line.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.line.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
skipNull: true,
tension: 0.1,
},
point: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.line(chart, 0);
controller.update();
// Line element
expect(chart.data.datasets[0].metaDataset._model).toEqual({
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
drawNull: undefined,
skipNull: true,
tension: 0.1,
scaleTop: 0,
scaleBottom: 200,
scaleZero: 156,
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
skip: false,
tension: 0.1,
// Point
x: 63,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousY: 62,
controlPointNextX: 67.5,
controlPointNextY: 57.3,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
skip: false,
tension: 0.1,
// Point
x: 108,
y: 15,
// Control points
controlPointPreviousX: 105.27827106822767,
controlPointPreviousY: 12.125364948465183,
controlPointNextX: 114.17827106822767,
controlPointNextY: 21.52536494846518,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
skip: false,
tension: 0.1,
// Point
x: 152,
y: 156,
// Control points
controlPointPreviousX: 145.63719249781943,
controlPointPreviousY: 143.20289277651324,
controlPointNextX: 154.53719249781943,
controlPointNextY: 161.10289277651324,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
radius: 3,
skip: false,
tension: 0.1,
// Point
x: 197,
y: 194,
// Control points
controlPointPreviousX: 192.5,
controlPointPreviousY: 190.2,
controlPointNextX: 197,
controlPointNextY: 194,
});
// Use dataset level styles for lines & points
chart.data.datasets[0].tension = 0.2;
chart.data.datasets[0].backgroundColor = 'rgb(98, 98, 98)';
chart.data.datasets[0].borderColor = 'rgb(8, 8, 8)';
chart.data.datasets[0].borderWidth = 0.55;
chart.data.datasets[0].borderCapStyle = 'butt';
chart.data.datasets[0].borderDash = [2, 3];
chart.data.datasets[0].borderDashOffset = 7;
chart.data.datasets[0].borderJoinStyle = 'miter';
chart.data.datasets[0].fill = false;
chart.data.datasets[0].skipNull = false;
chart.data.datasets[0].drawNull = true;
// point styles
chart.data.datasets[0].radius = 22;
chart.data.datasets[0].hitRadius = 3.3;
chart.data.datasets[0].pointBackgroundColor = 'rgb(128, 129, 130)';
chart.data.datasets[0].pointBorderColor = 'rgb(56, 57, 58)';
chart.data.datasets[0].pointBorderWidth = 1.123;
controller.update();
expect(chart.data.datasets[0].metaDataset._model).toEqual({
backgroundColor: 'rgb(98, 98, 98)',
borderCapStyle: 'butt',
borderColor: 'rgb(8, 8, 8)',
borderDash: [2, 3],
borderDashOffset: 7,
borderJoinStyle: 'miter',
borderWidth: 0.55,
fill: false,
drawNull: true,
skipNull: false,
tension: 0.2,
scaleTop: 0,
scaleBottom: 200,
scaleZero: 156,
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
skip: false,
tension: 0.2,
// Point
x: 63,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousY: 62,
controlPointNextX: 72,
controlPointNextY: 52.6,
});
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
skip: false,
tension: 0.2,
// Point
x: 108,
y: 15,
// Control points
controlPointPreviousX: 102.55654213645535,
controlPointPreviousY: 9.250729896930364,
controlPointNextX: 120.35654213645535,
controlPointNextY: 28.050729896930367,
});
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
skip: false,
tension: 0.2,
// Point
x: 152,
y: 156,
// Control points
controlPointPreviousX: 139.27438499563885,
controlPointPreviousY: 130.40578555302648,
controlPointNextX: 157.07438499563887,
controlPointNextY: 166.20578555302646,
});
expect(chart.data.datasets[0].metaData[3]._model).toEqual({
backgroundColor: 'rgb(128, 129, 130)',
borderWidth: 1.123,
borderColor: 'rgb(56, 57, 58)',
hitRadius: 3.3,
radius: 22,
skip: false,
tension: 0.2,
// Point
x: 197,
y: 194,
// Control points
controlPointPreviousX: 188,
controlPointPreviousY: 186.4,
controlPointNextX: 197,
controlPointNextY: 194,
});
// Use custom styles for lines & first point
chart.data.datasets[0].metaDataset.custom = {
tension: 0.25,
backgroundColor: 'rgb(55, 55, 54)',
borderColor: 'rgb(8, 7, 6)',
borderWidth: 0.3,
borderCapStyle: 'square',
borderDash: [4, 3],
borderDashOffset: 4.4,
borderJoinStyle: 'round',
fill: true,
skipNull: true,
drawNull: false,
};
// point styles
chart.data.datasets[0].metaData[0].custom = {
radius: 2.2,
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
tension: 0.15,
skip: true,
hitRadius: 5,
};
controller.update();
expect(chart.data.datasets[0].metaDataset._model).toEqual({
backgroundColor: 'rgb(55, 55, 54)',
borderCapStyle: 'square',
borderColor: 'rgb(8, 7, 6)',
borderDash: [4, 3],
borderDashOffset: 4.4,
borderJoinStyle: 'round',
borderWidth: 0.3,
fill: true,
drawNull: true,
skipNull: false,
tension: 0.25,
scaleTop: 0,
scaleBottom: 200,
scaleZero: 156,
});
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
backgroundColor: 'rgb(0, 1, 3)',
borderWidth: 0.787,
borderColor: 'rgb(4, 6, 8)',
hitRadius: 5,
radius: 2.2,
skip: true,
tension: 0.15,
// Point
x: 63,
y: 62,
// Control points
controlPointPreviousX: 63,
controlPointPreviousY: 62,
controlPointNextX: 69.75,
controlPointNextY: 54.95,
});
});
it ('should handle number of data point changes in update', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.line.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.line.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
skipNull: true,
tension: 0.1,
},
point: {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 1,
borderColor: Chart.defaults.global.defaultColor,
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.line(chart, 0);
chart.data.datasets[0].data = [1, 2]; // remove 2 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(2);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
chart.data.datasets[0].data = [1, 2, 3, 4, 5]; // add 3 items
controller.buildOrUpdateElements();
controller.update();
expect(chart.data.datasets[0].metaData.length).toBe(5);
expect(chart.data.datasets[0].metaData[0] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[1] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[2] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[3] instanceof Chart.elements.Point).toBe(true);
expect(chart.data.datasets[0].metaData[4] instanceof Chart.elements.Point).toBe(true);
});
it ('should set point hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.line.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.line.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
skipNull: true,
tension: 0.1,
},
point: {
backgroundColor: 'rgb(255, 255, 0)',
borderWidth: 1,
borderColor: 'rgb(255, 255, 255)',
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.line(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)');
expect(point._model.borderColor).toBe('rgb(230, 230, 230)');
expect(point._model.borderWidth).toBe(1);
expect(point._model.radius).toBe(4);
// Can set hover style per dataset
chart.data.datasets[0].pointHoverRadius = 3.3;
chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)';
chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].pointHoverBorderWidth = 2.1;
controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
expect(point._model.radius).toBe(3.3);
// Custom style
point.custom = {
hoverRadius: 4.4,
hoverBorderWidth: 5.5,
hoverBackgroundColor: 'rgb(0, 0, 0)',
hoverBorderColor: 'rgb(10, 10, 10)'
};
controller.setHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);
expect(point._model.radius).toBe(4.4);
});
it ('should remove hover styles', function() {
var data = {
datasets: [{
data: [10, 15, 0, -4],
label: 'dataset2',
xAxisID: 'firstXScaleID',
yAxisID: 'firstYScaleID'
}],
labels: ['label1', 'label2', 'label3', 'label4']
};
var mockContext = window.createMockContext();
var VerticalScaleConstructor = Chart.scaleService.getScaleConstructor('linear');
var verticalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('linear'));
verticalScaleConfig = Chart.helpers.scaleMerge(verticalScaleConfig, Chart.defaults.line.scales.yAxes[0]);
var yScale = new VerticalScaleConstructor({
ctx: mockContext,
options: verticalScaleConfig,
data: data,
id: 'firstYScaleID'
});
// Update ticks & set physical dimensions
var verticalSize = yScale.update(50, 200);
yScale.top = 0;
yScale.left = 0;
yScale.right = verticalSize.width;
yScale.bottom = verticalSize.height;
var HorizontalScaleConstructor = Chart.scaleService.getScaleConstructor('category');
var horizontalScaleConfig = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
horizontalScaleConfig = Chart.helpers.scaleMerge(horizontalScaleConfig, Chart.defaults.line.scales.xAxes[0]);
var xScale = new HorizontalScaleConstructor({
ctx: mockContext,
options: horizontalScaleConfig,
data: data,
id: 'firstXScaleID'
});
// Update ticks & set physical dimensions
var horizontalSize = xScale.update(200, 50);
xScale.left = yScale.right;
xScale.top = yScale.bottom;
xScale.right = horizontalSize.width + xScale.left;
xScale.bottom = horizontalSize.height + xScale.top;
var chart = {
chartArea: {
bottom: 200,
left: xScale.left,
right: 200,
top: 0
},
data: data,
config: {
type: 'line'
},
options: {
elements: {
line: {
backgroundColor: 'rgb(255, 0, 0)',
borderCapStyle: 'round',
borderColor: 'rgb(0, 255, 0)',
borderDash: [],
borderDashOffset: 0.1,
borderJoinStyle: 'bevel',
borderWidth: 1.2,
fill: true,
skipNull: true,
tension: 0.1,
},
point: {
backgroundColor: 'rgb(255, 255, 0)',
borderWidth: 1,
borderColor: 'rgb(255, 255, 255)',
hitRadius: 1,
hoverRadius: 4,
hoverBorderWidth: 1,
radius: 3,
}
},
scales: {
xAxes: [{
id: 'firstXScaleID'
}],
yAxes: [{
id: 'firstYScaleID'
}]
}
},
scales: {
firstXScaleID: xScale,
firstYScaleID: yScale,
}
};
var controller = new Chart.controllers.line(chart, 0);
controller.update();
var point = chart.data.datasets[0].metaData[0];
chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)';
chart.options.elements.point.borderColor = 'rgb(50, 51, 52)';
chart.options.elements.point.borderWidth = 10.1;
chart.options.elements.point.radius = 1.01;
controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)');
expect(point._model.borderColor).toBe('rgb(50, 51, 52)');
expect(point._model.borderWidth).toBe(10.1);
expect(point._model.radius).toBe(1.01);
// Can set hover style per dataset
chart.data.datasets[0].radius = 3.3;
chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)';
chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)';
chart.data.datasets[0].pointBorderWidth = 2.1;
controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)');
expect(point._model.borderColor).toBe('rgb(123, 125, 127)');
expect(point._model.borderWidth).toBe(2.1);
expect(point._model.radius).toBe(3.3);
// Custom style
point.custom = {
radius: 4.4,
borderWidth: 5.5,
backgroundColor: 'rgb(0, 0, 0)',
borderColor: 'rgb(10, 10, 10)'
};
controller.removeHoverStyle(point);
expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)');
expect(point._model.borderColor).toBe('rgb(10, 10, 10)');
expect(point._model.borderWidth).toBe(5.5);
expect(point._model.radius).toBe(4.4);
});
});
+45
Ver Arquivo
@@ -0,0 +1,45 @@
// Test the core element functionality
describe('Core element tests', function() {
it ('should transition model properties', function() {
var element = new Chart.Element({
_model: {
numberProp: 0,
numberProp2: 100,
_underscoreProp: 0,
stringProp: 'abc',
objectProp: {
myObject: true
},
colorProp: 'rgb(0, 0, 0)'
}
});
// First transition clones model into view
element.transition(0.25);
expect(element._view).toEqual(element._model);
expect(element._start).toEqual(element._model); // also cloned
expect(element._view.objectProp).toBe(element._model.objectProp); // not cloned
expect(element._start.objectProp).toEqual(element._model.objectProp); // not cloned
element._model.numberProp = 100;
element._model.numberProp2 = 250;
element._model._underscoreProp = 200;
element._model.stringProp = 'def'
element._model.newStringProp = 'newString';
element._model.colorProp = 'rgb(255, 255, 0)'
element.transition(0.25);
expect(element._view).toEqual({
numberProp: 25,
numberProp2: 137.5,
_underscoreProp: 0, // underscore props are not transition to a new value
stringProp: 'def',
newStringProp: 'newString',
objectProp: {
myObject: true
},
colorProp: 'rgb(64, 64, 0)',
});
});
});
+460
Ver Arquivo
@@ -0,0 +1,460 @@
describe('Core helper tests', function() {
var helpers;
beforeAll(function() {
helpers = window.Chart.helpers;
});
it('Should iterate over an array and pass the extra data to that function', function() {
var testData = [0, 9, "abc"];
var scope = {}; // fake out the scope and ensure that 'this' is the correct thing
helpers.each(testData, function(item, index) {
expect(item).not.toBe(undefined);
expect(index).not.toBe(undefined);
expect(testData[index]).toBe(item);
expect(this).toBe(scope);
}, scope);
// Reverse iteration
var iterated = [];
helpers.each(testData, function(item, index) {
expect(item).not.toBe(undefined);
expect(index).not.toBe(undefined);
expect(testData[index]).toBe(item);
expect(this).toBe(scope);
iterated.push(item);
}, scope, true);
expect(iterated.slice().reverse()).toEqual(testData);
});
it('Should iterate over properties in an object', function() {
var testData = {
myProp1: 'abc',
myProp2: 276,
myProp3: ['a', 'b']
};
helpers.each(testData, function(value, key) {
if (key === 'myProp1') {
expect(value).toBe('abc');
} else if (key === 'myProp2') {
expect(value).toBe(276);
} else if (key === 'myProp3') {
expect(value).toEqual(['a', 'b']);
} else {
expect(false).toBe(true);
}
});
});
it('should not error when iterating over a null object', function() {
expect(function() {
helpers.each(undefined);
}).not.toThrow();
});
it('Should clone an object', function() {
var testData = {
myProp1: 'abc',
myProp2: ['a', 'b'],
myProp3: {
myProp4: 5,
myProp5: [1, 2]
}
};
var clone = helpers.clone(testData);
expect(clone).toEqual(testData);
expect(clone).not.toBe(testData);
expect(clone.myProp2).not.toBe(testData.myProp2);
expect(clone.myProp3).not.toBe(testData.myProp3);
expect(clone.myProp3.myProp5).not.toBe(testData.myProp3.myProp5);
});
it('should extend an object', function() {
var original = {
myProp1: 'abc',
myProp2: 56
};
var extension = {
myProp3: [2, 5, 6],
myProp2: 0
};
helpers.extend(original, extension);
expect(original).toEqual({
myProp1: 'abc',
myProp2: 0,
myProp3: [2, 5, 6],
});
});
it('Should merge a normal config without scales', function() {
var baseConfig = {
valueProp: 5,
arrayProp: [1, 2, 3, 4, 5, 6],
objectProp: {
prop1: 'abc',
prop2: 56
}
};
var toMerge = {
valueProp2: null,
arrayProp: ['a', 'c'],
objectProp: {
prop1: 'c',
prop3: 'prop3'
}
};
var merged = helpers.configMerge(baseConfig, toMerge);
expect(merged).toEqual({
valueProp: 5,
valueProp2: null,
arrayProp: ['a', 'c', 3, 4, 5, 6],
objectProp: {
prop1: 'c',
prop2: 56,
prop3: 'prop3'
}
});
});
it('should merge arrays containing objects', function() {
var baseConfig = {
arrayProp: [{
prop1: 'abc',
prop2: 56
}],
};
var toMerge = {
arrayProp: [{
prop1: 'myProp1',
prop3: 'prop3'
}, 2, {
prop1: 'myProp1'
}],
};
var merged = helpers.configMerge(baseConfig, toMerge);
expect(merged).toEqual({
arrayProp: [{
prop1: 'myProp1',
prop2: 56,
prop3: 'prop3'
},
2, {
prop1: 'myProp1'
}],
});
});
it ('Should merge scale configs', function() {
var baseConfig = {
scales: {
prop1: {
abc: 123,
def: '456'
},
prop2: 777,
yAxes: [{
type: 'linear',
}, {
type: 'log'
}]
}
};
var toMerge = {
scales: {
prop1: {
def: 'bbb',
ghi: 78
},
prop2: null,
yAxes: [{
type: 'linear',
axisProp: 456
}, {
// pulls in linear default config since axis type changes
type: 'linear',
position: 'right'
}, {
// Pulls in linear default config since axis not in base
type: 'linear'
}]
}
};
var merged = helpers.configMerge(baseConfig, toMerge);
expect(merged).toEqual({
scales: {
prop1: {
abc: 123,
def: 'bbb',
ghi: 78
},
prop2: null,
yAxes: [{
type: 'linear',
axisProp: 456
}, {
display: true,
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
lineWidth: 1,
offsetGridLines: false,
show: true,
zeroLineColor: "rgba(0,0,0,0.25)",
zeroLineWidth: 1,
},
position: "right",
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
labelString: '',
show: false,
},
ticks: {
beginAtZero: false,
fontColor: "#666",
fontFamily: "Helvetica Neue",
fontSize: 12,
fontStyle: "normal",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%=value%>"
},
type: 'linear'
}, {
display: true,
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
lineWidth: 1,
offsetGridLines: false,
show: true,
zeroLineColor: "rgba(0,0,0,0.25)",
zeroLineWidth: 1,
},
position: "left",
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
labelString: '',
show: false,
},
ticks: {
beginAtZero: false,
fontColor: "#666",
fontFamily: "Helvetica Neue",
fontSize: 12,
fontStyle: "normal",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%=value%>"
},
type: 'linear'
}]
}
});
});
it ('should get value or default', function() {
expect(helpers.getValueAtIndexOrDefault(98, 0, 56)).toBe(98);
expect(helpers.getValueAtIndexOrDefault(0, 0, 56)).toBe(0);
expect(helpers.getValueAtIndexOrDefault(undefined, undefined, 56)).toBe(56);
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 1, 100)).toBe(2);
expect(helpers.getValueAtIndexOrDefault([1, 2, 3], 3, 100)).toBe(100);
});
it ('should filter an array', function() {
var data = [-10, 0, 6, 0, 7];
var callback = function(item) { return item > 2};
expect(helpers.where(data, callback)).toEqual([6, 7]);
expect(helpers.findNextWhere(data, callback)).toEqual(6);
expect(helpers.findNextWhere(data, callback, 2)).toBe(7);
expect(helpers.findNextWhere(data, callback, 4)).toBe(undefined);
expect(helpers.findPreviousWhere(data, callback)).toBe(7);
expect(helpers.findPreviousWhere(data, callback, 3)).toBe(6);
expect(helpers.findPreviousWhere(data, callback, 0)).toBe(undefined);
});
it ('Should get the correct sign', function() {
expect(helpers.sign(0)).toBe(0);
expect(helpers.sign(10)).toBe(1);
expect(helpers.sign(-5)).toBe(-1);
});
it ('should do a log10 operation', function() {
expect(helpers.log10(0)).toBe(-Infinity);
expect(helpers.log10(1)).toBe(0);
expect(helpers.log10(1000)).toBe(3);
});
it ('Should generate ids', function() {
expect(helpers.uid()).toBe('chart-0');
expect(helpers.uid()).toBe('chart-1');
expect(helpers.uid()).toBe('chart-2');
expect(helpers.uid()).toBe('chart-3');
});
it ('should detect a number', function() {
expect(helpers.isNumber(123)).toBe(true);
expect(helpers.isNumber('123')).toBe(true);
expect(helpers.isNumber(null)).toBe(false);
expect(helpers.isNumber(NaN)).toBe(false);
expect(helpers.isNumber(undefined)).toBe(false);
expect(helpers.isNumber('cbc')).toBe(false);
});
it ('should convert between radians and degrees', function() {
expect(helpers.toRadians(180)).toBe(Math.PI);
expect(helpers.toRadians(90)).toBe(0.5 * Math.PI);
expect(helpers.toDegrees(Math.PI)).toBe(180);
expect(helpers.toDegrees(Math.PI * 3 /2)).toBe(270);
});
it ('should get an angle from a point', function() {
var center = {
x: 0,
y: 0
};
expect(helpers.getAngleFromPoint(center, {x: 0, y: 10})).toEqual({
angle: Math.PI / 2,
distance: 10,
});
expect(helpers.getAngleFromPoint(center, {x: Math.sqrt(2), y: Math.sqrt(2)})).toEqual({
angle: Math.PI / 4,
distance: 2
});
expect(helpers.getAngleFromPoint(center, {x: -1.0 * Math.sqrt(2), y: -1.0 * Math.sqrt(2)})).toEqual({
angle: Math.PI * 1.25,
distance: 2
});
});
it ('should spline curves', function() {
expect(helpers.splineCurve({x: 0, y: 0}, {x: 1, y: 1}, { x: 2, y: 0}, 0)).toEqual({
previous: {
x: 1,
y: 1,
},
next: {
x: 1,
y: 1,
}
});
expect(helpers.splineCurve({x: 0, y: 0}, {x: 1, y: 1}, { x: 2, y: 0}, 1)).toEqual({
previous: {
x: 0,
y: 1,
},
next: {
x: 2,
y: 1,
}
});
});
it ('should get the next or previous item in an array', function() {
var testData = [0, 1, 2];
expect(helpers.nextItem(testData, 0, false)).toEqual(1);
expect(helpers.nextItem(testData, 2, false)).toEqual(2);
expect(helpers.nextItem(testData, 2, true)).toEqual(0);
expect(helpers.nextItem(testData, 1, true)).toEqual(2);
expect(helpers.nextItem(testData, -1, false)).toEqual(0);
expect(helpers.previousItem(testData, 0, false)).toEqual(0);
expect(helpers.previousItem(testData, 0, true)).toEqual(2);
expect(helpers.previousItem(testData, 2, false)).toEqual(1);
expect(helpers.previousItem(testData, 1, true)).toEqual(0);
});
it ('should clear a canvas', function() {
var context = window.createMockContext();
helpers.clear({
width: 100,
height: 150,
ctx: context
});
expect(context.getCalls()).toEqual([{
name: 'clearRect',
args: [0, 0, 100, 150]
}]);
});
it ('should draw a rounded rectangle', function() {
var context = window.createMockContext();
helpers.drawRoundedRectangle(context, 10, 20, 30, 40, 5);
expect(context.getCalls()).toEqual([{
name: 'beginPath',
args: []
}, {
name: 'moveTo',
args: [15, 20]
}, {
name: 'lineTo',
args: [35, 20]
}, {
name: 'quadraticCurveTo',
args: [40, 20, 40, 25]
}, {
name: 'lineTo',
args: [40, 55]
}, {
name: 'quadraticCurveTo',
args: [40, 60, 35, 60]
}, {
name: 'lineTo',
args: [15, 60]
}, {
name: 'quadraticCurveTo',
args: [10, 60, 10, 55]
}, {
name: 'lineTo',
args: [10, 25]
}, {
name: 'quadraticCurveTo',
args: [10, 20, 15, 20]
}, {
name: 'closePath',
args: []
}])
});
});
+176
Ver Arquivo
@@ -0,0 +1,176 @@
// Test the rectangle element
describe('Arc element tests', function() {
it ('Should be constructed', function() {
var arc = new Chart.elements.Arc({
_datasetIndex: 2,
_index: 1
});
expect(arc).not.toBe(undefined);
expect(arc._datasetIndex).toBe(2);
expect(arc._index).toBe(1);
});
it ('should determine if in range', function() {
var arc = new Chart.elements.Arc({
_datasetIndex: 2,
_index: 1
});
// Make sure we can run these before the view is added
expect(arc.inRange(2, 2)).toBe(false);
expect(arc.inLabelRange(2)).toBe(false);
// Mock out the view as if the controller put it there
arc._view = {
startAngle: 0,
endAngle: Math.PI / 2,
x: 0,
y: 0,
innerRadius: 5,
outerRadius: 10,
};
expect(arc.inRange(2, 2)).toBe(false);
expect(arc.inRange(7, 0)).toBe(true);
expect(arc.inRange(0, 11)).toBe(false);
expect(arc.inRange(Math.sqrt(32), Math.sqrt(32))).toBe(true);
expect(arc.inRange(-1.0 * Math.sqrt(7), Math.sqrt(7))).toBe(false);
});
it ('should get the tooltip position', function() {
var arc = new Chart.elements.Arc({
_datasetIndex: 2,
_index: 1
});
// Mock out the view as if the controller put it there
arc._view = {
startAngle: 0,
endAngle: Math.PI / 2,
x: 0,
y: 0,
innerRadius: 0,
outerRadius: Math.sqrt(2),
};
var pos = arc.tooltipPosition();
expect(pos.x).toBeCloseTo(0.5);
expect(pos.y).toBeCloseTo(0.5);
});
it ('should draw correctly with no border', function() {
var mockContext = window.createMockContext();
var arc = new Chart.elements.Arc({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Mock out the view as if the controller put it there
arc._view = {
startAngle: 0,
endAngle: Math.PI / 2,
x: 10,
y: 5,
innerRadius: 1,
outerRadius: 3,
backgroundColor: 'rgb(0, 0, 255)',
borderColor: 'rgb(255, 0, 0)',
};
arc.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: []
}, {
name: 'arc',
args: [10, 5, 3, 0, Math.PI / 2]
}, {
name: 'arc',
args: [10, 5, 1, Math.PI / 2, 0, true]
}, {
name: 'closePath',
args: []
}, {
name: 'setStrokeStyle',
args: ['rgb(255, 0, 0)']
}, {
name: 'setLineWidth',
args: [undefined]
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 255)']
}, {
name: 'fill',
args: []
}, {
name: 'setLineJoin',
args: ['bevel']
}]);
});
it ('should draw correctly with a border', function() {
var mockContext = window.createMockContext();
var arc = new Chart.elements.Arc({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Mock out the view as if the controller put it there
arc._view = {
startAngle: 0,
endAngle: Math.PI / 2,
x: 10,
y: 5,
innerRadius: 1,
outerRadius: 3,
backgroundColor: 'rgb(0, 0, 255)',
borderColor: 'rgb(255, 0, 0)',
borderWidth: 5
};
arc.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: []
}, {
name: 'arc',
args: [10, 5, 3, 0, Math.PI / 2]
}, {
name: 'arc',
args: [10, 5, 1, Math.PI / 2, 0, true]
}, {
name: 'closePath',
args: []
}, {
name: 'setStrokeStyle',
args: ['rgb(255, 0, 0)']
}, {
name: 'setLineWidth',
args: [5]
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 255)']
}, {
name: 'fill',
args: []
}, {
name: 'setLineJoin',
args: ['bevel']
}, {
name: 'stroke',
args: []
}]);
});
});
+526
Ver Arquivo
@@ -0,0 +1,526 @@
// Tests for the line element
describe('Line element tests', function() {
it ('should be constructed', function() {
var line = new Chart.elements.Line({
_datasetindex: 2,
_points: [1, 2, 3, 4]
});
expect(line).not.toBe(undefined);
expect(line._datasetindex).toBe(2);
expect(line._points).toEqual([1, 2, 3, 4]);
});
it ('should draw with default settings', function() {
var mockContext = window.createMockContext();
// Create our points
var points = [];
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 0,
_view: {
x: 0,
y: 10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 1,
_view: {
x: 5,
y: 0
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 2,
_view: {
x: 15,
y: -10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 3,
_view: {
x: 19,
y: -5
}
}));
var line = new Chart.elements.Line({
_datasetindex: 2,
_chart: {
ctx: mockContext,
},
_children: points,
// Need to provide some settings
_view: {
fill: false, // don't want to fill
tension: 0.0, // no bezier curve for now
}
})
line.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'save',
args: [],
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'setLineCap',
args: ['butt']
}, {
name: 'setLineDash',
args: [[]]
}, {
name: 'setLineDashOffset',
args: [0.0]
}, {
name: 'setLineJoin',
args: ['miter']
}, {
name: 'setLineWidth',
args: [3]
}, {
name: 'setStrokeStyle',
args: ['rgba(0,0,0,0.1)']
}, {
name: 'beginPath',
args: []
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'stroke',
args: [],
}, {
name: 'restore',
args: []
}])
});
it ('should draw with custom settings', function() {
var mockContext = window.createMockContext();
// Create our points
var points = [];
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 0,
_view: {
x: 0,
y: 10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 1,
_view: {
x: 5,
y: 0
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 2,
_view: {
x: 15,
y: -10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 3,
_view: {
x: 19,
y: -5
}
}));
var line = new Chart.elements.Line({
_datasetindex: 2,
_chart: {
ctx: mockContext,
},
_children: points,
// Need to provide some settings
_view: {
fill: true,
scaleZero: 2, // for filling lines
tension: 0.0, // no bezier curve for now
borderCapStyle: 'round',
borderColor: 'rgb(255, 255, 0)',
borderDash: [2, 2],
borderDashOffset: 1.5,
borderJoinStyle: 'bevel',
borderWidth: 4,
backgroundColor: 'rgb(0, 0, 0)'
}
})
line.draw();
var expected = [{
name: 'save',
args: [],
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'lineTo',
args: [19, 2]
}, {
name: 'lineTo',
args: [0, 2]
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 0)']
}, {
name: 'closePath',
args: []
}, {
name: 'fill',
args: []
}, {
name: 'setLineCap',
args: ['round']
}, {
name: 'setLineDash',
args: [[2, 2]]
}, {
name: 'setLineDashOffset',
args: [1.5]
}, {
name: 'setLineJoin',
args: ['bevel']
}, {
name: 'setLineWidth',
args: [4]
}, {
name: 'setStrokeStyle',
args: ['rgb(255, 255, 0)']
}, {
name: 'beginPath',
args: []
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'stroke',
args: [],
}, {
name: 'restore',
args: []
}];
expect(mockContext.getCalls()).toEqual(expected)
});
it ('should be able to draw with a loop back to the beginning point', function() {
var mockContext = window.createMockContext();
// Create our points
var points = [];
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 0,
_view: {
x: 0,
y: 10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 1,
_view: {
x: 5,
y: 0
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 2,
_view: {
x: 15,
y: -10
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 3,
_view: {
x: 19,
y: -5
}
}));
var line = new Chart.elements.Line({
_datasetindex: 2,
_chart: {
ctx: mockContext,
},
_children: points,
_loop: true, // want the line to loop back to the first point
// Need to provide some settings
_view: {
fill: false, // don't want to fill
tension: 0.0, // no bezier curve for now
}
})
line.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'save',
args: [],
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'lineTo',
args: [0, 10]
}, {
name: 'setLineCap',
args: ['butt']
}, {
name: 'setLineDash',
args: [[]]
}, {
name: 'setLineDashOffset',
args: [0.0]
}, {
name: 'setLineJoin',
args: ['miter']
}, {
name: 'setLineWidth',
args: [3]
}, {
name: 'setStrokeStyle',
args: ['rgba(0,0,0,0.1)']
}, {
name: 'beginPath',
args: []
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'lineTo',
args: [5, 0]
}, {
name: 'lineTo',
args: [15, -10]
}, {
name: 'lineTo',
args: [19, -5]
}, {
name: 'lineTo',
args: [0, 10]
}, {
name: 'stroke',
args: [],
}, {
name: 'restore',
args: []
}])
});
it ('should draw with bezier curves if tension > 0', function() {
var mockContext = window.createMockContext();
// Create our points
var points = [];
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 0,
_view: {
x: 0,
y: 10,
controlPointNextX: 1,
controlPointNextY: 1,
controlPointPreviousX: 0,
controlPointPreviousY: 0,
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 1,
_view: {
x: 5,
y: 0,
controlPointNextX: 6,
controlPointNextY: 7,
controlPointPreviousX: 4,
controlPointPreviousY: 3,
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 2,
_view: {
x: 15,
y: -10,
controlPointNextX: 16,
controlPointNextY: 17,
controlPointPreviousX: 14,
controlPointPreviousY: 13,
}
}));
points.push(new Chart.elements.Point({
_datasetindex: 2,
_index: 3,
_view: {
x: 19,
y: -5,
controlPointNextX: 20,
controlPointNextY: 21,
controlPointPreviousX: 18,
controlPointPreviousY: 17,
}
}));
var line = new Chart.elements.Line({
_datasetindex: 2,
_chart: {
ctx: mockContext,
},
_children: points,
// Need to provide some settings
_view: {
fill: true,
scaleZero: 2, // for filling lines
tension: 0.5, // have bezier curves
borderCapStyle: 'round',
borderColor: 'rgb(255, 255, 0)',
borderDash: [2, 2],
borderDashOffset: 1.5,
borderJoinStyle: 'bevel',
borderWidth: 4,
backgroundColor: 'rgb(0, 0, 0)'
}
})
line.draw();
var expected = [{
name: 'save',
args: [],
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'bezierCurveTo',
args: [1, 1, 4, 3, 5, 0]
}, {
name: 'bezierCurveTo',
args: [6, 7, 14, 13, 15, -10]
}, {
name: 'bezierCurveTo',
args: [16, 17, 18, 17, 19, -5]
}, {
name: 'lineTo',
args: [19, 2]
}, {
name: 'lineTo',
args: [0, 2]
}, {
name: 'setFillStyle',
args: ['rgb(0, 0, 0)']
}, {
name: 'closePath',
args: []
}, {
name: 'fill',
args: []
}, {
name: 'setLineCap',
args: ['round']
}, {
name: 'setLineDash',
args: [[2, 2]]
}, {
name: 'setLineDashOffset',
args: [1.5]
}, {
name: 'setLineJoin',
args: ['bevel']
}, {
name: 'setLineWidth',
args: [4]
}, {
name: 'setStrokeStyle',
args: ['rgb(255, 255, 0)']
}, {
name: 'beginPath',
args: []
}, {
name: 'moveTo',
args: [0, 10]
}, {
name: 'bezierCurveTo',
args: [1, 1, 4, 3, 5, 0]
}, {
name: 'bezierCurveTo',
args: [6, 7, 14, 13, 15, -10]
}, {
name: 'bezierCurveTo',
args: [16, 17, 18, 17, 19, -5]
}, {
name: 'stroke',
args: [],
}, {
name: 'restore',
args: []
}];
expect(mockContext.getCalls()).toEqual(expected)
});
});
+190
Ver Arquivo
@@ -0,0 +1,190 @@
// Test the point element
describe('Point element tests', function() {
it ('Should be constructed', function() {
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1
});
expect(point).not.toBe(undefined);
expect(point._datasetIndex).toBe(2);
expect(point._index).toBe(1);
});
it ('Should correctly identify as in range', function() {
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1
});
// Safely handles if these are called before the viewmodel is instantiated
expect(point.inRange(5)).toBe(false);
expect(point.inLabelRange(5)).toBe(false);
// Attach a view object as if we were the controller
point._view = {
radius: 2,
hitRadius: 3,
x: 10,
y: 15
};
expect(point.inRange(10, 15)).toBe(true);
expect(point.inRange(10, 10)).toBe(false);
expect(point.inRange(10, 5)).toBe(false);
expect(point.inRange(5, 5)).toBe(false);
expect(point.inLabelRange(5)).toBe(false);
expect(point.inLabelRange(7)).toBe(true);
expect(point.inLabelRange(10)).toBe(true);
expect(point.inLabelRange(12)).toBe(true);
expect(point.inLabelRange(15)).toBe(false);
expect(point.inLabelRange(20)).toBe(false);
});
it ('should get the correct tooltip position', function() {
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
point._view = {
radius: 2,
borderWidth: 6,
x: 10,
y: 15
};
expect(point.tooltipPosition()).toEqual({
x: 10,
y: 15,
padding: 8
});
});
it ('should draw correctly', function() {
var mockContext = window.createMockContext();
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Attach a view object as if we were the controller
point._view = {
radius: 2,
hitRadius: 3,
borderColor: 'rgba(1, 2, 3, 1)',
borderWidth: 6,
backgroundColor: 'rgba(0, 255, 0)',
x: 10,
y: 15,
ctx: mockContext
};
point.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: []
}, {
name: 'arc',
args: [10, 15, 2, 0, 2 * Math.PI]
}, {
name: 'closePath',
args: [],
}, {
name: 'setStrokeStyle',
args: ['rgba(1, 2, 3, 1)']
}, {
name: 'setLineWidth',
args: [6]
}, {
name: 'setFillStyle',
args: ['rgba(0, 255, 0)']
}, {
name: 'fill',
args: [],
}, {
name: 'stroke',
args: []
}]);
});
it ('should draw correctly with default settings if necessary', function() {
var mockContext = window.createMockContext();
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Attach a view object as if we were the controller
point._view = {
radius: 2,
hitRadius: 3,
x: 10,
y: 15,
ctx: mockContext
};
point.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: []
}, {
name: 'arc',
args: [10, 15, 2, 0, 2 * Math.PI]
}, {
name: 'closePath',
args: [],
}, {
name: 'setStrokeStyle',
args: ['rgba(0,0,0,0.1)']
}, {
name: 'setLineWidth',
args: [1]
}, {
name: 'setFillStyle',
args: ['rgba(0,0,0,0.1)']
}, {
name: 'fill',
args: [],
}, {
name: 'stroke',
args: []
}]);
});
it ('should not draw if skipped', function() {
var mockContext = window.createMockContext();
var point = new Chart.elements.Point({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Attach a view object as if we were the controller
point._view = {
radius: 2,
hitRadius: 3,
x: 10,
y: 15,
ctx: mockContext,
skip: true
};
point.draw();
expect(mockContext.getCalls()).toEqual([]);
});
});
+246
Ver Arquivo
@@ -0,0 +1,246 @@
// Test the rectangle element
describe('Rectangle element tests', function() {
it ('Should be constructed', function() {
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
expect(rectangle).not.toBe(undefined);
expect(rectangle._datasetIndex).toBe(2);
expect(rectangle._index).toBe(1);
});
it ('Should correctly identify as in range', function() {
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Safely handles if these are called before the viewmodel is instantiated
expect(rectangle.inRange(5)).toBe(false);
expect(rectangle.inLabelRange(5)).toBe(false);
// Attach a view object as if we were the controller
rectangle._view = {
base: 0,
width: 4,
x: 10,
y: 15
};
expect(rectangle.inRange(10, 15)).toBe(true);
expect(rectangle.inRange(10, 10)).toBe(true);
expect(rectangle.inRange(10, 16)).toBe(false);
expect(rectangle.inRange(5, 5)).toBe(false);
expect(rectangle.inLabelRange(5)).toBe(false);
expect(rectangle.inLabelRange(7)).toBe(false);
expect(rectangle.inLabelRange(10)).toBe(true);
expect(rectangle.inLabelRange(12)).toBe(true);
expect(rectangle.inLabelRange(15)).toBe(false);
expect(rectangle.inLabelRange(20)).toBe(false);
// Test when the y is below the base (negative bar)
var negativeRectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
negativeRectangle._view = {
base: 0,
width: 4,
x: 10,
y: -15
};
expect(negativeRectangle.inRange(10, -16)).toBe(false);
expect(negativeRectangle.inRange(10, 1)).toBe(false);
expect(negativeRectangle.inRange(10, -5)).toBe(true);
});
it ('should get the correct height', function() {
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
rectangle._view = {
base: 0,
width: 4,
x: 10,
y: 15
};
expect(rectangle.height()).toBe(-15);
// Test when the y is below the base (negative bar)
var negativeRectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
negativeRectangle._view = {
base: -10,
width: 4,
x: 10,
y: -15
};
expect(negativeRectangle.height()).toBe(5);
});
it ('should get the correct tooltip position', function() {
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
rectangle._view = {
base: 0,
width: 4,
x: 10,
y: 15
};
expect(rectangle.tooltipPosition()).toEqual({
x: 10,
y: 0,
});
// Test when the y is below the base (negative bar)
var negativeRectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1
});
// Attach a view object as if we were the controller
negativeRectangle._view = {
base: -10,
width: 4,
x: 10,
y: -15
};
expect(negativeRectangle.tooltipPosition()).toEqual({
x: 10,
y: -15,
});
});
it ('should draw correctly', function() {
var mockContext = window.createMockContext();
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Attach a view object as if we were the controller
rectangle._view = {
backgroundColor: 'rgb(255, 0, 0)',
base: 0,
borderColor: 'rgb(0, 0, 255)',
borderWidth: 1,
ctx: mockContext,
width: 4,
x: 10,
y: 15,
};
rectangle.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: [],
}, {
name: 'setFillStyle',
args: ['rgb(255, 0, 0)']
}, {
name: 'setStrokeStyle',
args: ['rgb(0, 0, 255)'],
}, {
name: 'setLineWidth',
args: [1]
}, {
name: 'moveTo',
args: [8.5, 0]
}, {
name: 'lineTo',
args: [8.5, 15.5]
}, {
name: 'lineTo',
args: [11.5, 15.5]
}, {
name: 'lineTo',
args: [11.5, 0]
}, {
name: 'fill',
args: [],
}, {
name: 'stroke',
args: []
}]);
});
it ('should draw correctly with no stroke', function() {
var mockContext = window.createMockContext();
var rectangle = new Chart.elements.Rectangle({
_datasetIndex: 2,
_index: 1,
_chart: {
ctx: mockContext,
}
});
// Attach a view object as if we were the controller
rectangle._view = {
backgroundColor: 'rgb(255, 0, 0)',
base: 0,
borderColor: 'rgb(0, 0, 255)',
ctx: mockContext,
width: 4,
x: 10,
y: 15,
};
rectangle.draw();
expect(mockContext.getCalls()).toEqual([{
name: 'beginPath',
args: [],
}, {
name: 'setFillStyle',
args: ['rgb(255, 0, 0)']
}, {
name: 'setStrokeStyle',
args: ['rgb(0, 0, 255)'],
}, {
name: 'setLineWidth',
args: [undefined]
}, {
name: 'moveTo',
args: [8, 0]
}, {
name: 'lineTo',
args: [8, 15]
}, {
name: 'lineTo',
args: [12, 15]
}, {
name: 'lineTo',
args: [12, 0]
}, {
name: 'fill',
args: [],
}]);
});
});
+122
Ver Arquivo
@@ -0,0 +1,122 @@
(function() {
// Code from http://stackoverflow.com/questions/4406864/html-canvas-unit-testing
var Context = function() {
this._calls = []; // names/args of recorded calls
this._initMethods();
this._fillStyle = null;
this._lineCap = null;
this._lineDashOffset = null;
this._lineJoin = null;
this._lineWidth = null;
this._strokeStyle = null;
// Define properties here so that we can record each time they are set
Object.defineProperties(this, {
"fillStyle": {
'get': function() { return this._fillStyle; },
'set': function(style) {
this._fillStyle = style;
this.record('setFillStyle', [style]);
}
},
'lineCap': {
'get': function() { return this._lineCap; },
'set': function(cap) {
this._lineCap = cap;
this.record('setLineCap', [cap]);
}
},
'lineDashOffset': {
'get': function() { return this._lineDashOffset; },
'set': function(offset) {
this._lineDashOffset = offset;
this.record('setLineDashOffset', [offset]);
}
},
'lineJoin': {
'get': function() { return this._lineJoin; },
'set': function(join) {
this._lineJoin = join;
this.record('setLineJoin', [join]);
}
},
'lineWidth': {
'get': function() { return this._lineWidth; },
'set': function (width) {
this._lineWidth = width;
this.record('setLineWidth', [width]);
}
},
'strokeStyle': {
'get': function() { return this._strokeStyle; },
'set': function(style) {
this._strokeStyle = style;
this.record('setStrokeStyle', [style]);
}
},
});
};
Context.prototype._initMethods = function() {
// define methods to test here
// no way to introspect so we have to do some extra work :(
var methods = {
arc: function() {},
beginPath: function() {},
bezierCurveTo: function() {},
clearRect: function() {},
closePath: function() {},
fill: function() {},
fillRect: function() {},
fillText: function() {},
lineTo: function(x, y) {},
measureText: function(text) {
// return the number of characters * fixed size
return text ? { width: text.length * 10 } : {width: 0};
},
moveTo: function(x, y) {},
quadraticCurveTo: function() {},
restore: function() {},
rotate: function() {},
save: function() {},
setLineDash: function() {},
stroke: function() {},
translate: function() {},
};
// attach methods to the class itself
var scope = this;
var addMethod = function(name, method) {
scope[methodName] = function() {
scope.record(name, arguments);
return method.apply(scope, arguments);
};
}
for (var methodName in methods) {
var method = methods[methodName];
addMethod(methodName, method);
}
};
Context.prototype.record = function(methodName, args) {
this._calls.push({
name: methodName,
args: Array.prototype.slice.call(args)
});
},
Context.prototype.getCalls = function() {
return this._calls;
}
Context.prototype.resetCalls = function() {
this._calls = [];
};
window.createMockContext = function() {
return new Context();
};
})();
+189
Ver Arquivo
@@ -0,0 +1,189 @@
// Test the category scale
describe('Category scale tests', function() {
it('Should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('category');
expect(Constructor).not.toBe(undefined);
expect(typeof Constructor).toBe('function');
});
it('Should have the correct default config', function() {
var defaultConfig = Chart.scaleService.getScaleDefaults('category');
expect(defaultConfig).toEqual({
display: true,
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true, // draw ticks extending towards the label
lineWidth: 1,
offsetGridLines: false,
show: true,
zeroLineColor: "rgba(0,0,0,0.25)",
zeroLineWidth: 1,
},
position: "bottom",
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
labelString: '',
show: false,
},
ticks: {
beginAtZero: false,
fontColor: "#666",
fontFamily: "Helvetica Neue",
fontSize: 12,
fontStyle: "normal",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%=value%>"
}
});
});
it('Should generate ticks from the data labales', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick5']
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: {},
options: config,
data: mockData,
id: scaleID
});
scale.buildTicks();
expect(scale.ticks).toEqual(mockData.labels);
});
it ('Should get the correct pixel for a value when horizontal', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
config.gridLines.offsetGridLines = true;
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
var minSize = scale.update(200, 100);
expect(scale.width).toBe(200);
expect(scale.height).toBe(28);
expect(scale.paddingTop).toBe(0);
expect(scale.paddingBottom).toBe(0);
expect(scale.paddingLeft).toBe(28);
expect(scale.paddingRight).toBe(48);
expect(scale.labelRotation).toBe(0);
expect(minSize).toEqual({
width: 200,
height: 28,
});
scale.left = 5;
scale.top = 5;
scale.right = 205;
scale.bottom = 33;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(45);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(132);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(145);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(33);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(33);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(157);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(157);
});
it ('should get the correct pixel for a value when vertical', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['tick1', 'tick2', 'tick3', 'tick4', 'tick_last']
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('category'));
config.gridLines.offsetGridLines = true;
config.position = "left";
var Constructor = Chart.scaleService.getScaleConstructor('category');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
var minSize = scale.update(100, 200);
expect(scale.width).toBe(100);
expect(scale.height).toBe(200);
expect(scale.paddingTop).toBe(6);
expect(scale.paddingBottom).toBe(6);
expect(scale.paddingLeft).toBe(0);
expect(scale.paddingRight).toBe(0);
expect(scale.labelRotation).toBe(0);
expect(minSize).toEqual({
width: 100,
height: 200,
});
scale.left = 5;
scale.top = 5;
scale.right = 105;
scale.bottom = 205;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(30);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(161);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(180);
config.gridLines.offsetGridLines = false;
expect(scale.getPixelForValue(0, 0, 0, false)).toBe(11);
expect(scale.getPixelForValue(0, 0, 0, true)).toBe(11);
expect(scale.getPixelForValue(0, 4, 0, false)).toBe(199);
expect(scale.getPixelForValue(0, 4, 0, true)).toBe(199);
});
});
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+379
Ver Arquivo
@@ -0,0 +1,379 @@
describe('Logarithmic Scale tests', function() {
it('Should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
expect(Constructor).not.toBe(undefined);
expect(typeof Constructor).toBe('function');
});
it('Should have the correct default config', function() {
var defaultConfig = Chart.scaleService.getScaleDefaults('logarithmic');
expect(defaultConfig).toEqual({
display: true,
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true,
lineWidth: 1,
offsetGridLines: false,
show: true,
zeroLineColor: "rgba(0,0,0,0.25)",
zeroLineWidth: 1,
},
position: "left",
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
labelString: '',
show: false,
},
ticks: {
beginAtZero: false,
fontColor: "#666",
fontFamily: "Helvetica Neue",
fontSize: 12,
fontStyle: "normal",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
show: true,
template: "<%var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));if (remain === 1 || remain === 2 || remain === 5) {%><%=value.toExponential()%><%} else {%><%= null %><%}%>",
},
});
});
it('Should correctly determine the max & min data values', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 5000, 78, 450]
}, {
yAxisID: 'second scale',
data: [1, 1000, 10, 100],
}, {
yAxisID: scaleID,
data: [150]
}]
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('logarithmic'), // use default config for scale
data: mockData,
id: scaleID
});
expect(scale).not.toEqual(undefined); // must construct
expect(scale.min).toBe(undefined); // not yet set
expect(scale.max).toBe(undefined);
scale.update(400, 400);
expect(scale.min).toBe(1);
expect(scale.max).toBe(10000);
});
it('Should correctly determine the max & min for scatter data', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
xAxisID: scaleID, // for the horizontal scale
yAxisID: scaleID,
data: [{
x: 10,
y: 100
}, {
x: 2,
y: 6
}, {
x: 65,
y: 121
}, {
x: 99,
y: 7
}]
}]
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var verticalScale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
verticalScale.update(400, 400);
expect(verticalScale.min).toBe(1);
expect(verticalScale.max).toBe(1000);
var horizontalConfig = Chart.helpers.clone(config);
horizontalConfig.position = 'bottom';
var horizontalScale = new Constructor({
ctx: mockContext,
options: horizontalConfig,
data: mockData,
id: scaleID,
});
horizontalScale.update(400, 400);
expect(horizontalScale.min).toBe(1);
expect(horizontalScale.max).toBe(100);
});
it('Should correctly determine the min and max data values when stacked mode is turned on', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 1, 5, 78, 100]
}, {
yAxisID: 'second scale',
data: [-1000, 1000],
}, {
yAxisID: scaleID,
data: [150, 10, 10, 100, 10, 9]
}]
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
config.stacked = true; // enable scale stacked mode
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
scale.update(400, 400);
expect(scale.min).toBe(10);
expect(scale.max).toBe(1000);
});
it('Should ensure that the scale has a max and min that are not equal', function() {
var scaleID = 'myScale';
var mockData = {
datasets: []
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
scale.update(400, 00);
expect(scale.min).toBe(1);
expect(scale.max).toBe(10);
mockData.datasets = [{
yAxisID: scaleID,
data: [0.15, 0.15]
}];
scale.update(400, 400);
expect(scale.min).toBe(0.01);
expect(scale.max).toBe(1);
});
it('Should generate tick marks', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 1, 25, 78]
}, ]
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: {},
options: config,
data: mockData,
id: scaleID
});
// Set arbitrary width and height for now
scale.width = 50;
scale.height = 400;
scale.buildTicks();
// Counts down because the lines are drawn top to bottom
expect(scale.ticks).toEqual([100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);
expect(scale.start).toBe(1);
expect(scale.end).toBe(100);
});
it('Should generate tick marks in the correct order in reversed mode', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 1, 25, 78]
}, ]
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
config.ticks.reverse = true;
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: {},
options: config,
data: mockData,
id: scaleID
});
// Set arbitrary width and height for now
scale.width = 50;
scale.height = 400;
scale.buildTicks();
// Counts down because the lines are drawn top to bottom
expect(scale.ticks).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]);
expect(scale.start).toBe(100);
expect(scale.end).toBe(1);
});
it('Should build labels using the default template', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 1, 25, 78]
}, ]
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
scale.update(400, 400);
expect(scale.ticks).toEqual(['1e+2', '', '', '', '', '5e+1', '', '', '2e+1', '1e+1', '', '', '', '', '5e+0', '', '', '2e+0', '1e+0']);
});
it('Should build labels using the user supplied callback', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 1, 25, 78]
}, ]
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
config.ticks.userCallback = function(value, index) {
return index.toString();
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
scale.update(400, 400);
// Just the index
expect(scale.ticks).toEqual(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18']);
});
it('Should get the correct pixel value for a point', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
xAxisID: scaleID, // for the horizontal scale
yAxisID: scaleID,
data: [10, 5, 1, 25, 78]
}]
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('logarithmic'));
var Constructor = Chart.scaleService.getScaleConstructor('logarithmic');
var verticalScale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID
});
verticalScale.update(50, 100);
// Fake out positioning of the scale service
verticalScale.left = 0;
verticalScale.top = 0;
verticalScale.right = 50;
verticalScale.bottom = 110;
verticalScale.paddingTop = 5;
verticalScale.paddingBottom = 5;
verticalScale.width = 50;
verticalScale.height = 110;
expect(verticalScale.getPixelForValue(100, 0, 0)).toBe(5); // top + paddingTop
expect(verticalScale.getPixelForValue(1, 0, 0)).toBe(105); // bottom - paddingBottom
expect(verticalScale.getPixelForValue(10, 0, 0)).toBe(55); // halfway
var horizontalConfig = Chart.helpers.clone(config);
horizontalConfig.position = 'bottom';
var horizontalScale = new Constructor({
ctx: mockContext,
options: horizontalConfig,
data: mockData,
id: scaleID,
});
horizontalScale.update(100, 50);
// Fake out positioning of the scale service
horizontalScale.left = 0;
horizontalScale.top = 0;
horizontalScale.right = 110;
horizontalScale.bottom = 50;
horizontalScale.paddingLeft = 5;
horizontalScale.paddingRight = 5;
horizontalScale.width = 110;
horizontalScale.height = 50;
expect(horizontalScale.getPixelForValue(100, 0, 0)).toBe(105); // right - paddingRight
expect(horizontalScale.getPixelForValue(1, 0, 0)).toBe(5); // left + paddingLeft
expect(horizontalScale.getPixelForValue(10, 0, 0)).toBe(55); // halfway
});
});
+773
Ver Arquivo
@@ -0,0 +1,773 @@
// Tests for the radial linear scale used by the polar area and radar charts
describe('Test the radial linear scale', function() {
it('Should register the constructor with the scale service', function() {
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
expect(Constructor).not.toBe(undefined);
expect(typeof Constructor).toBe('function');
});
it('Should have the correct default config', function() {
var defaultConfig = Chart.scaleService.getScaleDefaults('radialLinear');
expect(defaultConfig).toEqual({
angleLines: {
show: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1
},
animate: true,
display: true,
gridLines: {
color: "rgba(0, 0, 0, 0.1)",
drawOnChartArea: true,
drawTicks: true,
lineWidth: 1,
offsetGridLines: false,
show: true,
zeroLineColor: "rgba(0,0,0,0.25)",
zeroLineWidth: 1,
},
lineArc: false,
pointLabels: {
fontColor: "#666",
fontFamily: "'Arial'",
fontSize: 10,
fontStyle: "normal",
},
position: "chartArea",
scaleLabel: {
fontColor: '#666',
fontFamily: 'Helvetica Neue',
fontSize: 12,
fontStyle: 'normal',
labelString: '',
show: false,
},
ticks: {
backdropColor: "rgba(255,255,255,0.75)",
backdropPaddingY: 2,
backdropPaddingX: 2,
beginAtZero: false,
fontColor: "#666",
fontFamily: "Helvetica Neue",
fontSize: 12,
fontStyle: "normal",
maxRotation: 90,
minRotation: 20,
mirror: false,
padding: 10,
reverse: false,
showLabelBackdrop: true,
show: true,
template: "<%=value%>",
},
});
});
it('Should correctly determine the max & min data values', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, -5, 78, -100]
}, {
yAxisID: scaleID,
data: [150]
}],
labels: ['lablel1', 'label2', 'label3', 'label4', 'label5', 'label6']
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('radialLinear'), // use default config for scale
data: mockData,
id: scaleID,
});
scale.update(200, 300);
expect(scale.min).toBe(-100);
expect(scale.max).toBe(200);
});
it('Should ensure that the scale has a max and min that are not equal', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [],
labels: []
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: Chart.scaleService.getScaleDefaults('radialLinear'), // use default config for scale
data: mockData,
id: scaleID,
});
scale.update(200, 300);
expect(scale.min).toBe(-1);
expect(scale.max).toBe(1);
});
it('should forcibly include 0 in the range if the beginAtZero option is used', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [20, 30, 40, 50]
}],
labels: [],
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
config.ticks.beginAtZero = false;
scale.update(400, 400);
expect(scale.ticks).toEqual(['20', '25', '30', '35', '40', '45', '50']);
config.ticks.beginAtZero = true;
scale.update(400, 400);
expect(scale.ticks).toEqual(['0', '5', '10', '15', '20', '25', '30', '35', '40', '45', '50']);
mockData.datasets[0].data = [-20, -30, -40, -50];
scale.update(400, 400);
expect(scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20', '-15', '-10', '-5', '0']);
config.ticks.beginAtZero = false;
scale.update(400, 400);
expect(scale.ticks).toEqual(['-50', '-45', '-40', '-35', '-30', '-25', '-20']);
});
it('Should generate tick marks in the correct order in reversed mode', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: []
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
config.ticks.reverse = true;
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
scale.update(200, 300);
// Reverse mode makes this count up
expect(scale.ticks).toEqual(['80', '60', '40', '20', '0']);
expect(scale.start).toBe(80);
expect(scale.end).toBe(0);
});
it('Should build labels using the user supplied callback', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: []
};
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
config.ticks.userCallback = function(value, index) {
return index.toString();
};
var mockContext = window.createMockContext();
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
scale.update(200, 300);
// Just the index
expect(scale.ticks).toEqual(['0', '1', '2', '3', '4']);
});
it('should correctly set the center point', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['point1', 'point2', 'point3', 'point4', 'point5'] // used in radar charts which use the same scales
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
scale.left = 10;
scale.right = 210;
scale.top = 5;
scale.bottom = 305;
scale.update(200, 300);
expect(scale.drawingArea).toBe(36);
expect(scale.xCenter).toBe(110);
expect(scale.yCenter).toBe(155);
});
it('should get the correct distance from the center point', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}],
labels: ['point1', 'point2', 'point3', 'point4', 'point5'] // used in radar charts which use the same scales
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
scale.left = 0;
scale.right = 200;
scale.top = 0;
scale.bottom = 300;
scale.update(200, 300);
expect(scale.getDistanceFromCenterForValue(scale.min)).toBe(0);
expect(scale.getDistanceFromCenterForValue(scale.max)).toBe(36);
expect(scale.getPointPositionForValue(1, 5)).toEqual({
x: 102.13987716166409,
y: 149.30471176265638,
});
config.reverse = true;
scale.update(200, 300);
expect(scale.getDistanceFromCenterForValue(scale.min)).toBe(36);
expect(scale.getDistanceFromCenterForValue(scale.max)).toBe(0);
});
it('should draw correctly when there are no point labels', function() {
var scaleID = 'myScale';
var mockData = {
datasets: [{
yAxisID: scaleID,
data: [10, 5, 0, 25, 78]
}, ],
labels: ['point1', 'point2', 'point3', 'point4', 'point5'] // used in radar charts which use the same scales
};
var mockContext = window.createMockContext();
var config = Chart.helpers.clone(Chart.scaleService.getScaleDefaults('radialLinear'));
config.lineArc = true;
var Constructor = Chart.scaleService.getScaleConstructor('radialLinear');
var scale = new Constructor({
ctx: mockContext,
options: config,
data: mockData,
id: scaleID,
});
scale.left = 0;
scale.right = 200;
scale.top = 0;
scale.bottom = 300;
scale.update(200, 300);
scale.draw();
var expected = [{
"name": "measureText",
"args": ["0"]
}, {
"name": "measureText",
"args": ["80"]
}, {
"name": "measureText",
"args": ["point1"]
}, {
"name": "measureText",
"args": ["point2"]
}, {
"name": "measureText",
"args": ["point3"]
}, {
"name": "measureText",
"args": ["point4"]
}, {
"name": "measureText",
"args": ["point5"]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "arc",
"args": [100, 150, 9, 0, 6.283185307179586]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["20"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 133, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["20", 100, 141]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "arc",
"args": [100, 150, 18, 0, 6.283185307179586]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["40"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 124, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["40", 100, 132]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "arc",
"args": [100, 150, 27, 0, 6.283185307179586]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["60"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 115, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["60", 100, 123]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "arc",
"args": [100, 150, 36, 0, 6.283185307179586]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["80"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 106, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["80", 100, 114]
}];
expect(mockContext.getCalls()).toEqual(expected);
mockContext.resetCalls();
config.lineArc = false;
scale.draw();
expect(mockContext.getCalls()).toEqual([{
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 141]
}, {
"name": "lineTo",
"args": [108.55950864665638, 147.21884705062547]
}, {
"name": "lineTo",
"args": [105.29006727063226, 157.28115294937453]
}, {
"name": "lineTo",
"args": [94.70993272936774, 157.28115294937453]
}, {
"name": "lineTo",
"args": [91.44049135334362, 147.21884705062547]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["20"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 133, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["20", 100, 141]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 132]
}, {
"name": "lineTo",
"args": [117.11901729331277, 144.43769410125094]
}, {
"name": "lineTo",
"args": [110.58013454126451, 164.56230589874906]
}, {
"name": "lineTo",
"args": [89.41986545873549, 164.56230589874906]
}, {
"name": "lineTo",
"args": [82.88098270668723, 144.43769410125094]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["40"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 124, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["40", 100, 132]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 123]
}, {
"name": "lineTo",
"args": [125.67852593996915, 141.6565411518764]
}, {
"name": "lineTo",
"args": [115.87020181189678, 171.8434588481236]
}, {
"name": "lineTo",
"args": [84.12979818810322, 171.8434588481236]
}, {
"name": "lineTo",
"args": [74.32147406003085, 141.6565411518764]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["60"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 115, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["60", 100, 123]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 114]
}, {
"name": "lineTo",
"args": [134.23803458662553, 138.87538820250188]
}, {
"name": "lineTo",
"args": [121.16026908252903, 179.12461179749812]
}, {
"name": "lineTo",
"args": [78.83973091747097, 179.12461179749812]
}, {
"name": "lineTo",
"args": [65.76196541337447, 138.8753882025019]
}, {
"name": "closePath",
"args": []
}, {
"name": "stroke",
"args": []
}, {
"name": "measureText",
"args": ["80"]
}, {
"name": "setFillStyle",
"args": ["rgba(255,255,255,0.75)"]
}, {
"name": "fillRect",
"args": [88, 106, 24, 16]
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["80", 100, 114]
}, {
"name": "setLineWidth",
"args": [1]
}, {
"name": "setStrokeStyle",
"args": ["rgba(0, 0, 0, 0.1)"]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 150]
}, {
"name": "lineTo",
"args": [65.76196541337447, 138.8753882025019]
}, {
"name": "stroke",
"args": []
}, {
"name": "closePath",
"args": []
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["point5", 61.0066828318987, 137.33030323062715]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 150]
}, {
"name": "lineTo",
"args": [78.83973091747097, 179.12461179749812]
}, {
"name": "stroke",
"args": []
}, {
"name": "closePath",
"args": []
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["point4", 75.9008046560086, 183.16969676937285]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 150]
}, {
"name": "lineTo",
"args": [121.16026908252903, 179.12461179749812]
}, {
"name": "stroke",
"args": []
}, {
"name": "closePath",
"args": []
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["point3", 124.0991953439914, 183.16969676937285]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 150]
}, {
"name": "lineTo",
"args": [134.23803458662553, 138.87538820250188]
}, {
"name": "stroke",
"args": []
}, {
"name": "closePath",
"args": []
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["point2", 138.9933171681013, 137.33030323062715]
}, {
"name": "beginPath",
"args": []
}, {
"name": "moveTo",
"args": [100, 150]
}, {
"name": "lineTo",
"args": [100, 114]
}, {
"name": "stroke",
"args": []
}, {
"name": "closePath",
"args": []
}, {
"name": "setFillStyle",
"args": ["#666"]
}, {
"name": "fillText",
"args": ["point1", 100, 109]
}]);
});
});

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