Comparar commits

...

1056 Commits

Autor SHA1 Mensagem Data
Evert Timberg 87c8f51578 Merge pull request #2237 from troywarr/v2.0-dev
Fix "main" file path in bower.json
2016-04-10 20:15:34 -04:00
Troy Warr 5fa6003361 fix "main" file path in bower.json 2016-04-10 18:59:03 -05:00
Evert Timberg 00004fdd3b Merge pull request #2234 from nnnick/fix/2223
Don't measure undefined or null strings.
2016-04-10 10:15:52 -04:00
Evert Timberg 68b493732c Don't measure undefined or null strings. 2016-04-10 10:10:31 -04:00
Evert Timberg e93677e0c8 Merge pull request #2233 from jamiepenney/v2.0-dev
Update Line chart documentation
2016-04-09 19:33:10 -04:00
Jamie Penney 8fca9540ab Document the point radius setting 2016-04-10 11:15:55 +12:00
Jamie Penney 8c2bc34b9c Fix whitespace in Line Chart documentation 2016-04-10 11:04:23 +12:00
etimberg ebb8ca233d Bump version to v2.0.0 2016-04-09 08:01:01 -04:00
Evert Timberg 6ba2efe3a4 Built files 2016-04-03 13:23:09 -04:00
Evert Timberg d5fd737058 Merge pull request #2206 from nnnick/fix/constraint-width-percent
Allow percentages as the max-width/max-height of the container
2016-04-03 13:18:06 -04:00
Evert Timberg 93a2e9fc55 Merge pull request #2209 from nnnick/zoom_and_pan_pre_work
Zoom and pan pre work
2016-04-03 09:19:19 -04:00
Evert Timberg a7fede4f46 Fix jshint error 2016-04-03 09:15:11 -04:00
Evert Timberg 488826ace3 Update doc file to indicate that category scale supports min/max attributes 2016-04-02 23:07:41 -04:00
Evert Timberg 9ee70d6d48 Category scale supports min / max 2016-04-02 23:05:48 -04:00
Evert Timberg 95bd0a54dd Clip out the chart area so that things outside do not draw 2016-04-02 21:41:57 -04:00
Evert Timberg 2b361e1fee Fix typo 2016-04-02 09:41:18 -04:00
Evert Timberg 7875b0c68d Install latest chrome before running tests 2016-04-02 09:37:20 -04:00
Evert Timberg 5c1f242785 Use latest firefox version 2016-04-02 09:37:07 -04:00
Evert Timberg 3350d5fb13 Refactoring to reduce code size 2016-04-02 09:19:33 -04:00
Evert Timberg b15b316e85 use watchify for incremental test rebuilds 2016-04-02 09:02:38 -04:00
Evert Timberg b6d7ceba1c Add initial implementation of constraint percentage width / height support. Added tests for dom sizing methods. 2016-04-01 23:11:01 -04:00
Evert Timberg be6b254d50 Merge pull request #2203 from nnnick/fix/minor-doc-updates
Minor doc fixes
2016-04-01 22:16:05 -04:00
Evert Timberg 0b56ea452f Minor doc fixes 2016-04-01 22:12:37 -04:00
Evert Timberg 37da19df78 Merge pull request #2186 from nnnick/fix/2115
Better handling when data.datasets does not exist
2016-03-29 20:13:42 -04:00
etimberg d8347039cf Better handling when data.datasets does not exist 2016-03-29 20:10:29 -04:00
Evert Timberg f39fa53a7e Fix doc titles 2016-03-26 10:57:43 -04:00
Evert Timberg cefaef4707 Fix tests 2016-03-26 10:49:02 -04:00
Tanner Linsley d4b6be5afe Merge pull request #2173 from niemyjski/patch-1
Removed the default padding
2016-03-24 14:08:24 -05:00
Blake Niemyjski 798f643fab Removed the default padding
You should put a style on the container element
2016-03-24 14:07:35 -05:00
etimberg 60a429f5cb Update doc version 2016-03-23 19:22:43 -04:00
etimberg f6cb3cf0ef Updated build 2016-03-20 11:17:49 -04:00
Evert Timberg f3926198d9 Merge pull request #2157 from nnnick/fix/2156
Fix scale merge when the xAxes object is specified but the type is not
2016-03-20 11:15:41 -04:00
etimberg 79f38b49d8 Fix scale merge when the xAxes object is specified but the type is not 2016-03-20 11:12:26 -04:00
Evert Timberg 9a0553a1b5 Update built files 2016-03-19 09:16:44 -04:00
Evert Timberg 74fd697351 Merge pull request #2155 from nnnick/fix/2154
Better use of default scale types.
2016-03-19 09:03:49 -04:00
Evert Timberg e090691ef7 Better use of default scale types. 2016-03-19 08:50:50 -04:00
Evert Timberg 67bd2dae6d Merge pull request #2145 from nnnick/fix/2110
Instead of showing a warning on load, throw an error on create if moment is not defined.
2016-03-16 20:08:15 -04:00
etimberg 998c6939bf Instead of showing a warning on load, throw an error on create if moment is not defined. 2016-03-16 19:59:20 -04:00
Evert Timberg 2ab86f5557 Merge pull request #2144 from nnnick/fix/1942
Better conversion to ticks to make it easier to use callbacks
2016-03-16 19:44:10 -04:00
etimberg 21a33f0e41 Better conversion to ticks to make it easier to use callbacks 2016-03-16 19:39:09 -04:00
Evert Timberg 1157b19626 Merge pull request #2139 from nnnick/fix/2104
Fix zoom reset
2016-03-15 20:09:51 -04:00
Evert Timberg 04f1e57459 Fix zoom reset 2016-03-15 20:03:28 -04:00
Evert Timberg 1292558f7c Merge pull request #2132 from nnnick/fix/2131
Fix axis IDs in documentation
2016-03-14 19:51:09 -04:00
Evert Timberg f09f32f59e Merge pull request #2133 from borancar/v2.0-dev
Add composer.json
2016-03-14 19:49:36 -04:00
Evert Timberg bf724abe8b Fix axis IDs in documentation 2016-03-14 19:43:21 -04:00
Boran Car fffbc27db3 Add composer.json 2016-03-14 23:41:04 +00:00
Evert Timberg e511fc2a1c Merge pull request #2128 from The-Smallest/v2-rectangle-generic
Generic Rectangle: any border (botton, left, top, right) can be skipped now.
2016-03-13 14:06:31 -04:00
Evert Timberg f64324e2a8 Merge pull request #2129 from nnnick/fix/2037
Fix animation bug.
2016-03-13 12:29:48 -04:00
Evert Timberg 4fec7dfdbb Fix animation bug. Helpers.findNextWhere no longer returned the index of the item. This causes the wrong animation object to be removed. 2016-03-13 12:24:33 -04:00
Ivan Samoylenko f5bb8e25d5 Fixed bar.controller tests 2016-03-13 19:10:49 +03:00
Ivan Samoylenko 81e1448836 Added 'borderSkipped' parameter to Rectangle. 2016-03-13 18:58:36 +03:00
Evert Timberg 56611f550d Merge pull request #2125 from The-Smallest/docs-fixes
Missing whitespaces and code markup fixes
2016-03-13 09:30:14 -04:00
Ivan Samoylenko 72b0ef2df0 Missing whitespaces and code markup fixes 2016-03-13 14:47:37 +03:00
Evert Timberg 1fbbdd2d38 Merge pull request #2116 from 100000001/v2.0-dev
Expose yAlign and xAlign as a tooltip option
2016-03-10 07:06:19 -05:00
100000001 136efeaf4d Moved _model xAlign and yAlign setting to Positioning section and
swapped y and x
2016-03-10 09:05:59 +01:00
100000001 5d2444a5ee Expose yAlign and xAlign as a tooltip option 2016-03-10 09:00:26 +01:00
Evert Timberg 9bcc3ca34c Allow ticks.fixedStepSize or ticks.stepSize options to mean the same thing 2016-03-06 08:56:31 -05:00
Evert Timberg a16093e51c Merge pull request #2101 from nnnick/fix/2034
Fix some time rounding problems
2016-03-05 23:18:54 -05:00
Evert Timberg a87ebe0841 Fix test for time zone difference 2016-03-05 23:16:25 -05:00
Evert Timberg c3f765857e Fix some time rounding problems 2016-03-05 22:58:34 -05:00
Evert Timberg c99cf97ff6 Merge pull request #2087 from MatthiasWinkelmann/time-parser-#2086
A fix for nnnick/Chart.js#2086
2016-03-02 11:40:37 -05:00
Matthias Winkelmann 9410eaabbf fixed timezone bug in test 2016-03-02 16:51:48 +01:00
Matthias Winkelmann fc46e25f23 fixed test and added a test for a custom date parser 2016-03-02 16:40:58 +01:00
Matthias Winkelmann b69b388b31 fixed travis built 2016-03-02 14:16:52 +01:00
Matthias Winkelmann d5f837843e Fixes nnnick/Chart.js#2086 by introducing a new time.parser option with high priority to replace the (deprecated) time.format 2016-03-02 13:53:35 +01:00
Evert Timberg a25c2c740c Merge pull request #2074 from nnnick/fix/2070
Fix legend generation when no datasets
2016-02-28 17:56:11 -05:00
Evert Timberg 3d6b47b0d5 Fix legend generation when no datasets 2016-02-28 17:51:06 -05:00
Evert Timberg 156f8f0be8 Updated build files 2016-02-28 15:55:05 -05:00
Evert Timberg 237d5dca5a Merge pull request #2073 from nnnick/fix/event-padding
Take padding into account when determining the model coordinates from event coordinates
2016-02-28 15:44:30 -05:00
Evert Timberg 185ea3939d Take padding into account when determining the model coordinates from event coordinates 2016-02-28 15:32:15 -05:00
Evert Timberg aba16b402f Merge pull request #2069 from hamalaiv/fix/#2018
Fix/#2018
2016-02-28 14:26:51 -05:00
Evert Timberg 77971e6b99 Merge pull request #2072 from nnnick/fix/2050
Fix global font settings
2016-02-28 13:44:42 -05:00
Evert Timberg 8d5b3809f6 Fix global font settings 2016-02-28 13:41:17 -05:00
Ville Hämäläinen 33a1fa928d fix consistency with other samples 2016-02-28 10:20:10 +02:00
Ville Hämäläinen 04fe614800 fix title 2016-02-28 10:16:09 +02:00
Ville Hämäläinen 2977c8eb9c improve doughnut sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
- remove logs
2016-02-28 10:15:18 +02:00
Ville Hämäläinen a4fa956ab4 improve scatter sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 10:10:45 +02:00
Ville Hämäläinen 13fc892114 improve scatter-multi-axis sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 10:09:14 +02:00
Ville Hämäläinen 94cd6a480c improve polar-area sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 10:05:31 +02:00
Ville Hämäläinen 595464fc7e improve polar-area sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 10:03:43 +02:00
Ville Hämäläinen 5602826aeb improve combo-bar-line sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 10:01:34 +02:00
Ville Hämäläinen 0985e6d564 improve bar sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
- fix x-axis labels when adding data
2016-02-28 10:00:01 +02:00
Ville Hämäläinen 680fa8a68e improve bar-stacked sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 09:55:28 +02:00
Ville Hämäläinen e7233c2f61 improve bar-multi-axis sample
- set title
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 09:54:16 +02:00
Ville Hämäläinen 72f59264e9 fix titles 2016-02-28 09:50:45 +02:00
Ville Hämäläinen 2513d5dd48 improve time-scale sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
- remove logs
2016-02-28 09:50:31 +02:00
Ville Hämäläinen 14fd5de460 improve combo-time-scale sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
- remove logs
2016-02-28 09:46:59 +02:00
Ville Hämäläinen 0480f2e18d improve progress-bar sample
- set title
- set same size canvas as other samples
- fix adding data after all data has been removed
- remove user select from canvas
- remove html legend
2016-02-28 09:43:21 +02:00
Ville Hämäläinen f23b640c81 improve progress-bar sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
2016-02-28 09:29:29 +02:00
Ville Hämäläinen 9d210d8a8c improve tooltip-hooks sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove html legend
2016-02-28 09:25:46 +02:00
Ville Hämäläinen c7845d124d improve radar-skip-points sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
2016-02-28 09:22:14 +02:00
Ville Hämäläinen 428567d8cf improve radar sample
- improve title
- set same size canvas as other samples
- remove user select from canvas
- remove html legend
2016-02-28 09:18:56 +02:00
Ville Hämäläinen aa604af05b improve line-x-axis-filter sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove logs
2016-02-28 09:02:59 +02:00
Ville Hämäläinen 194c11c3d7 improve line-stacked-area sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove logs
- remove html legend
2016-02-28 08:59:38 +02:00
Ville Hämäläinen cd52936473 improve line-skip-points sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove logs
- remove html legend
2016-02-28 08:56:26 +02:00
Ville Hämäläinen 48cb104f14 improve line-logarithmic sample
- set title
- set same size canvas as other samples
- remove user select from canvas
- remove logs
2016-02-28 08:24:58 +02:00
Ville Hämäläinen a7b16464bf improve line-logarithmic sample
- set title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove logs
2016-02-28 07:57:02 +02:00
Ville Hämäläinen 1f8709f88a fix x-axis labels when adding data 2016-02-28 07:51:40 +02:00
Ville Hämäläinen 87633f61e9 improve line-legend sample
- improve title
- set same size canvas as other samples
- fix x-axis labels when adding data
- remove user select from canvas
- remove logs
2016-02-28 07:50:13 +02:00
Ville Hämäläinen dae599e16d improve line-customTooltips sample
- set title for chart
- set same size canvas as other samples
- remove user select from canvas
- remove logs
2016-02-28 07:34:37 +02:00
Ville Hämäläinen 4729b05cc1 improve line chart sample
- set title for chart
- remove html legend
- set same size canvas as other samples
- remove user select from canvas
2016-02-28 07:28:39 +02:00
Ville Hämäläinen 521236bd92 improve bubble chart sample
- fix add dataset when all datasets have been removed
- set title for chart
- remove html legend
- set same size canvas as other samples
- remove user select from canvas
- set name for added datasets
2016-02-28 07:13:09 +02:00
Evert Timberg 431f930c15 Merge pull request #2067 from nnnick/fix/animations
Fix bar chart and doughnut chart animations
2016-02-27 12:38:43 -05:00
Evert Timberg 04e6926961 Fix bar chart and doughnut chart animations 2016-02-27 12:32:20 -05:00
Evert Timberg 1cc9184c47 Merge pull request #2066 from mathiask88/cacheCleanupFix
Much faster cache clean up
2016-02-27 12:00:44 -05:00
Mathias Küsel 96315dd3c9 Much faster cache clean up 2016-02-27 17:19:33 +01:00
Evert Timberg 5fe1914e17 Merge pull request #2065 from nnnick/fix/2009
Fix #2009
2016-02-27 09:01:31 -05:00
Evert Timberg b812bcc8a5 Fix #2009 2016-02-27 08:58:27 -05:00
Evert Timberg 6ad533ce2b Merge pull request #2057 from hamalaiv/fix/2036
fix alpha for tooltip colors
2016-02-26 21:46:36 -05:00
Ville Hämäläinen 0f6e329aaa fix alpha for tooltip colors 2016-02-25 20:17:40 +02:00
Evert Timberg cfd3ebb77e Merge pull request #2041 from nnnick/fix/radius-0
Fix point radius 0
2016-02-20 08:48:25 -05:00
Evert Timberg f5a2e394c8 Fix radius 0 2016-02-20 08:44:25 -05:00
Evert Timberg 1bebda87f6 Merge pull request #2031 from mathiask88/customPointStyle
Adds the ability to draw custom point styles
2016-02-18 16:42:03 -05:00
Mathias Küsel 86b9139617 Adds the ability to draw custom point styles 2016-02-18 22:03:20 +01:00
Tanner Linsley f572125820 Merge pull request #2027 from nnnick/fix-stacking-order-and-reversable-legend
Fix stacking, tooltip, and legend order for stackables
2016-02-17 13:11:40 -07:00
Tanner Linsley 50d0c98030 Tooltips now respect stacked ordering
Tooltips detect the stacked scale property now, reversing when
appropriate
2016-02-17 12:42:29 -07:00
Tanner Linsley ee81d4a804 Reversible Legends
Legends can now be reversed with the `reversed: true` property.
2016-02-17 12:42:09 -07:00
Tanner Linsley ac5be9bde2 Proper line and bar stacking order
Stacked line and bar charts now behave predictably with the first
dataset on the bottom stacked upwards.
2016-02-17 12:41:32 -07:00
Evert Timberg d31db87115 Updated build 2016-02-15 10:52:51 -05:00
Evert Timberg c3149a9400 Merge pull request #2017 from nnnick/fix/1884
When the last label would overlap with the previously shown label, skip the previously shown one
2016-02-15 10:49:59 -05:00
Evert Timberg 4c35bba639 When the last label would overlap with the previously shown label, skip the previously shown one 2016-02-15 10:43:19 -05:00
Evert Timberg 2672efad63 Merge pull request #2015 from nnnick/fix/1962
Disable autoskipper for time scales
2016-02-15 09:44:53 -05:00
Evert Timberg 309ab1f477 Disable autoskipper for time scales 2016-02-15 09:41:35 -05:00
Evert Timberg 37b3fb5d6c Legend tests + fix minor bug where padding was not taken into account when going down to the next line 2016-02-15 09:23:31 -05:00
Evert Timberg e589734cbb Title block tests 2016-02-14 18:04:12 -05:00
etimberg 01b88f19df Clean up code climate style issues and formatting. 2016-02-14 17:06:00 -05:00
Evert Timberg 756208413b Merge pull request #2014 from nnnick/update-code-climate-config
Update code climate config
2016-02-14 15:12:55 -05:00
etimberg a79d365b49 add some more reporters 2016-02-14 14:43:02 -05:00
etimberg 1dc943ddb4 updates from running code climate locally 2016-02-14 13:25:37 -05:00
Evert Timberg db2073139b improve syntax 2016-02-14 11:05:33 -05:00
Evert Timberg 172839af2c try and make this work 2016-02-14 10:31:31 -05:00
Evert Timberg 0732793b7e explicitly run certain engines 2016-02-14 10:24:17 -05:00
Evert Timberg 41f2b5707a Add codeclimate config 2016-02-14 10:08:00 -05:00
Evert Timberg 58fcb37760 fix typo in readme 2016-02-14 10:03:37 -05:00
Evert Timberg d366f2b4d3 Merge pull request #2013 from nnnick/fix-coverage-report
Fix coverage report
2016-02-14 09:59:37 -05:00
Evert Timberg 766b748a58 Run coverage properly on the CI 2016-02-14 09:48:24 -05:00
Evert Timberg 38b2925e6c Use coveralls to report lines of coverage and add a badge to the readme 2016-02-14 09:38:26 -05:00
Evert Timberg 489f7ce6f7 use a new node version 2016-02-14 09:38:02 -05:00
etimberg 3226dfa495 coverage report works 2016-02-13 22:44:55 -05:00
etimberg a84f9d9177 Update other test tasks to use karma-browserify 2016-02-13 21:58:49 -05:00
etimberg 96551c20db begin fixing coverage tests 2016-02-13 21:50:12 -05:00
etimberg f6951816a0 Improve joshing reporting. Added a JSHint config file.
Fixed JSHint warnings.
2016-02-13 20:12:26 -05:00
Tanner Linsley d9af94a715 Merge pull request #2007 from nnnick/browserify-build-system
Browserify build system
2016-02-13 09:25:23 -07:00
Tanner Linsley eb2b04a9ff Documentation Updates for UMD support 2016-02-12 23:03:44 -07:00
Tanner Linsley 2f5e0924ef Built Files 2016-02-11 23:45:30 -07:00
Tanner Linsley c5020c3e5a Updated Samples 2016-02-11 23:45:25 -07:00
Tanner Linsley eb01a0d6f8 Core helpers reference 2016-02-11 23:45:14 -07:00
Tanner Linsley 999125c521 Testing for the new build system 2016-02-11 23:25:06 -07:00
Tanner Linsley 813d18bd78 Passing All Tests, Updated Dependencies 2016-02-11 23:16:43 -07:00
Tanner Linsley 007d029837 Bundled builds
Possible usages are:

src/Chart.js (umd)
dist/Chart.js (ChartJS)
dist/Chart.min.js (ChartJS minified)
dist/Chart.bundle.js (ChartJS with Moment.js)
dist/Chart.bundle.min.js (ChartJS with Moment.js minified)
2016-02-11 21:29:26 -07:00
Tanner Linsley f2780bb825 Browserify for easier UMD consumptions and vanilla builds 2016-02-11 20:30:53 -07:00
Tanner Linsley 09783be8a9 Merge branch 'v2.0-dev' into fix-legend-tooltip-stacked-ordering 2016-02-10 12:15:40 -07:00
Evert Timberg a3dea119e8 Merge pull request #1978 from roben/v2.0-dev
Fix tooltip error and add fixed steps to linear scale
2016-02-09 07:29:40 -05:00
Robert Becker 55f9b68b0c Updated build and documentation 2016-02-09 13:04:07 +01:00
Robert Becker e9c18f603d Merged remote-tracking branch 'upstream/v2.0-dev' into v2.0-dev to fix conflicts.
Refactored linear scale fixed step size implementation.
Added nbproject to .gitignore
2016-02-09 12:56:16 +01:00
Evert Timberg eb7241cbc9 Merge pull request #1986 from nnnick/fix/1292
Update bar sample file to use elements config. Fixes #1292
2016-02-07 20:09:18 -05:00
etimberg 84ed07a84e Update bar sample file to use elements config. Fixes #1292 2016-02-07 20:06:50 -05:00
Evert Timberg 7235d829ec Merge pull request #1985 from nnnick/fix/1144
Update docs for #1144
2016-02-07 20:01:01 -05:00
etimberg ee16c1edbc Update docs for #1144 2016-02-07 19:55:32 -05:00
etimberg 9cf31da4c9 Add docs for global font options 2016-02-07 19:48:39 -05:00
Evert Timberg e931276003 Merge pull request #1984 from nnnick/fix/1890
Write an almost equals function and use it in the linear scale. …
2016-02-06 09:41:34 -05:00
Evert Timberg 61ca178e2b Write an almost equals function and use it in the linear scale. Added a test for this new function. 2016-02-06 09:38:44 -05:00
Robert Becker ada4c8eca3 Removed nbproject folder 2016-02-05 14:36:37 +01:00
Robert Becker 92bc1a04cf Chart.js was missing? 2016-02-05 10:11:58 +01:00
Robert Becker 1692b977cd Fixed tab sizing in core.helpers.js 2016-02-05 09:43:20 +01:00
Robert Becker 098b05f1b2 Further reformatted scale.linear.js to match original indenting.
Refactored and fixed scale calculation.
Added dist files to commit.
2016-02-05 09:41:45 +01:00
Robert Becker 85de9fbe9c Further reformatted scale.linear.js to match original indenting. 2016-02-05 09:33:57 +01:00
Robert Becker 80ede9b9bb Added documentation for fixedStepSize.
Reformatted scale.linear.js to match original indenting.
2016-02-05 09:28:50 +01:00
Robert Becker 09721407d2 Removed debug log. 2016-02-04 15:28:06 +01:00
Robert Becker 9a20381af4 Fixed typo in core.helpers.js.
Added ticks.fixedStepSize configuration parameter to force linear scale steps.
2016-02-04 15:20:17 +01:00
Robert Becker df218ead82 Merge branch 'v2.0-dev' of github.com:roben/Chart.js into v2.0-dev
# Conflicts:
#	src/core/core.helpers.js
2016-02-04 10:38:35 +01:00
Robert Becker ba6afa7257 Fixed label callbacks adding only a single line instead of multiple lines as stated in docs. 2016-02-04 10:35:53 +01:00
Robert Becker e7df265c7a Fixed label callbacks adding only a single line instead of multiple lines as stated in docs. 2016-02-04 10:34:29 +01:00
Evert Timberg 73300e91c4 Merge pull request #1972 from nnnick/fix/1971
Always show lines by default.
2016-02-02 20:18:03 -05:00
Evert Timberg dfaf786e1a Always show lines by default. 2016-02-02 20:14:59 -05:00
Evert Timberg 25e787cbf0 Merge pull request #1964 from nnnick/feature/1954
Add default font options
2016-02-01 21:12:11 -05:00
Evert Timberg d16f4fc5ce Add default font options 2016-02-01 21:06:54 -05:00
Evert Timberg aafe21db7e New built files 2016-02-01 18:49:11 -05:00
Evert Timberg 9ed88599d2 Merge pull request #1963 from nnnick/fix/1952
Fix stacked bar data limit calculation
2016-02-01 18:47:07 -05:00
Evert Timberg 0e8babf1d7 Fix stacked bar data limit calculation 2016-02-01 18:44:39 -05:00
Evert Timberg 16dc9e6167 Merge pull request #1950 from nnnick/fix/time-scale-min-max
Time scale updates to remove unnecessary extra ticks
2016-02-01 18:29:56 -05:00
Evert Timberg 172c088c6b Minor fix 2016-01-30 17:19:32 -05:00
Evert Timberg f75116a91e Update millisecond default format. Removed unnecessary space at right edge of time scale. 2016-01-30 16:35:10 -05:00
Evert Timberg 1afe9f1a6e Built files with latest changes 2016-01-30 09:04:23 -05:00
Evert Timberg 212b6d3992 Merge pull request #1938 from nnnick/testing_improvements
Testing improvements
2016-01-27 18:04:22 -05:00
Evert Timberg bfd6f5f78e Radar controller tests 2016-01-27 18:00:32 -05:00
Evert Timberg 0890c809aa default config tests 2016-01-24 15:15:36 -05:00
Evert Timberg d0a0d57fe2 Initial polar area tests 2016-01-24 13:29:13 -05:00
Evert Timberg 6aa2933ec5 Bubble controller tests 2016-01-24 10:59:19 -05:00
Evert Timberg d0b67c603b Line and bar test updates 2016-01-24 10:58:30 -05:00
Evert Timberg 68ab74a46d Fix linear scale stacked mode 2016-01-24 09:22:28 -05:00
Evert Timberg 0ed39c9fd7 Fix error in math helpers. 2016-01-24 09:21:10 -05:00
Evert Timberg c312835eb1 Add some tests for scales. Cleaned up some minor bugs in the time scale. Wrote better helpers for helpers.min and helpers.max 2016-01-23 12:44:55 -05:00
Evert Timberg 888379ec5c Merge pull request #1929 from nnnick/fix/1917
Ensure that adding datasets to charts with time scales works
2016-01-21 22:04:31 -05:00
Evert Timberg 59e3ccb42a buildOrUpdateControllers now returns an array of all the new controllers that were created. Build controllers before updating the scales but only reset them afterwards because the scales need to update label moments first. 2016-01-21 22:00:21 -05:00
Evert Timberg 76ef7de646 Fix sample file addData button 2016-01-21 21:32:59 -05:00
Evert Timberg cfb06ed34d Merge pull request #1927 from nnnick/fix/1918
All sample files use CDN version of jQuery to make getting started easier.
2016-01-21 20:55:05 -05:00
Evert Timberg c8ea3af32c All sample files use CDN version of jQuery to make getting started easier. 2016-01-21 20:50:48 -05:00
Evert Timberg 3c614a5dfe Merge pull request #1915 from nnnick/fix/1914
Properly begin path before drawing line at edge of scale
2016-01-18 21:38:27 -05:00
Evert Timberg 2d4e2f9889 Properly begin path before drawing line at edge of scale 2016-01-18 21:35:35 -05:00
Evert Timberg 62988e9768 Merge pull request #1912 from mathiask88/pointStyleFix
Fixes the point size for rect and rectRot
2016-01-18 15:55:06 -05:00
Mathias Küsel b282a01ab6 Fixes rect size 2016-01-18 20:04:31 +01:00
Evert Timberg 8e681a606d Merge pull request #1911 from mathiask88/fixResize
Fixes resize() function
2016-01-18 12:50:46 -05:00
Mathias Küsel 33303d8d8a Fixes resize() function 2016-01-18 17:46:11 +01:00
Evert Timberg 00913be944 Merge pull request #1908 from nnnick/fix/1907
Fix reversed ticks on linear scale + update test
2016-01-17 20:39:59 -05:00
Evert Timberg 1de0435feb Fix reversed ticks on linear scale + update test 2016-01-17 20:37:43 -05:00
Evert Timberg 2db334dbf6 Merge pull request #1905 from mathiask88/pointStyles
Adds different point styles
2016-01-16 12:49:47 -05:00
Mathias Küsel 655c1152eb Adds different point styles 2016-01-16 18:07:57 +01:00
Evert Timberg f6b18a5998 Merge pull request #1900 from mathiask88/smallOptimizations
Small optimizations
2016-01-16 09:10:11 -05:00
Mathias Küsel c42cb148da Transition optimizations 2016-01-15 13:06:03 +01:00
Mathias Küsel fa7baa1627 Do not calculate control points if we want straight lines 2016-01-15 13:05:51 +01:00
Mathias Küsel 19613f531c Just assign instead of extend 2016-01-15 13:05:23 +01:00
Mathias Küsel 4f6e86640f Adds a caching system to expensive measureText() function 2016-01-15 13:05:03 +01:00
Mathias Küsel 25d6c2f064 Removes unused context bindings 2016-01-14 18:17:14 +01:00
Evert Timberg b756507625 Merge pull request #1887 from mathiask88/v2.0-dev
Add option to disable line drawing
2016-01-14 11:02:51 -05:00
Mathias Küsel 24e4a924c4 Add option to disable line drawing 2016-01-14 13:39:06 +01:00
Evert Timberg 7735371f45 Merge pull request #1893 from mathiask88/updateOptimizations
Add some optimizations to often used functions
2016-01-12 08:22:36 -05:00
Mathias Küsel 977d45a3e0 Add some optimizations to often used functions 2016-01-12 09:47:55 +01:00
Evert Timberg 307d02bf48 Merge pull request #1892 from davis/v2.0-dev
Fix orf/olf being undefined
2016-01-11 21:57:52 -05:00
Davis Kim 88fc6ecc5c Fix orf/olf being undefined 2016-01-11 18:54:45 -08:00
Evert Timberg ff94a54891 Merge pull request #1879 from nnnick/fix/1110
Fix/1110
2016-01-09 14:47:24 -05:00
Evert Timberg 0ed27d4474 Make sure tick string could be null / undefined 2016-01-09 14:42:55 -05:00
Evert Timberg 5070059ac1 Add template option for point labels + test + doc update 2016-01-09 14:39:43 -05:00
Evert Timberg 956b1dd1e0 Merge pull request #1878 from nnnick/fix/1871
Don't try to use undefined Scale constructors
2016-01-09 11:59:39 -05:00
Evert Timberg 8c68f78ec3 Don't try to use undefined Scale constructors 2016-01-09 11:55:44 -05:00
Evert Timberg 1202c03535 Update build 2016-01-09 10:48:15 -05:00
Evert Timberg 6b28790223 Merge pull request #1877 from nnnick/fix/1862
Fix stacked combo bar charts & add test
2016-01-09 10:01:19 -05:00
Evert Timberg 46861c9f0b Update bar controller tests 2016-01-09 09:58:14 -05:00
Evert Timberg d49b5b82c7 Add test for scale 2016-01-09 09:51:04 -05:00
Evert Timberg 0e393a3122 Update controllers 2016-01-09 09:50:56 -05:00
Evert Timberg 8cfa60c04d Merge pull request #1854 from nnnick/fix/1853
Do not force resize if the size has not changed
2016-01-08 13:16:06 -05:00
Evert Timberg 46ca099265 Merge pull request #1866 from morleyzhi/v2.0-dev
Fix a bug where ticks get culled when they don't need to be (fixes #1865)
2016-01-07 16:21:49 -05:00
Morley Zhi 203bbcec6c Fix a bug where ticks get culled when they don't need to be 2016-01-07 15:57:53 -05:00
Evert Timberg 6f0d32fa8c Merge pull request #1863 from morleyzhi/v2.0-dev
Use ticks.maxTicksLimit to limit gridLines in a similar way
2016-01-07 14:43:59 -05:00
Morley Zhi fe57c8728e Re-enable this; turns out I was mislead by the label spacing 2016-01-07 12:41:42 -05:00
Morley Zhi ebf695734c Looks like maxTicksLimit already limits gridlines, so restore this 2016-01-07 12:37:13 -05:00
Morley Zhi f00517643e Always show the last tick 2016-01-07 12:28:09 -05:00
Morley Zhi 84a6eb4a3b Updates
(1) Only limit gridlines when maxTicksLimit is defined, so we don't blow up the tests.
(2) Add a note about running tests in CONTRIBUTING.md
(3) Rebuild files
2016-01-07 11:40:26 -05:00
Morley Zhi 6478f93ded Use ticks.maxTicksLimit to limit gridlines (fixes #1859); use getValueOrDefault for resolving the maxTicksLimit option 2016-01-07 10:44:56 -05:00
Evert Timberg 1967bef9f6 Merge pull request #1850 from kirushanth-sakthivetpillai/bugfix/browserify-umd
Update gulpfile.js
2016-01-06 21:06:36 -05:00
Evert Timberg 310eada01a Do not force resize if the size has not changed 2016-01-05 20:16:18 -05:00
Kirushanth Sakthivetpillai 1e91cf816b Update gulpfile.js
root can be either window, globals but without this, JS will not lookup in globals object
2016-01-05 11:19:48 -05:00
Evert Timberg cd29ede572 Update built files 2016-01-03 09:11:58 -05:00
Evert Timberg ae19cfd35f Merge pull request #1848 from nnnick/fix/1461
Add suggestedMin, suggestedMax, min, and max options to radialLinear scale
2016-01-02 21:21:28 -05:00
etimberg 8dca052a16 Add suggestedMin, suggestedMax, min, and max options to radialLinear scale 2016-01-02 21:03:09 -05:00
Evert Timberg 579e322809 Merge pull request #1840 from nnnick/fix/1731-part-2
Better handling of large tooltips
2016-01-02 20:16:37 -05:00
Evert Timberg 8487375730 Update readme to latest beta version 2016-01-01 12:54:50 -05:00
Evert Timberg 2caff1f4fa Fix sample showing scale titles 2016-01-01 12:21:16 -05:00
Evert Timberg 4ac60956db Merge pull request #1845 from nnnick/fix/1822
Prevent flickering for bars that represent data that is NaN
2015-12-31 19:51:21 -05:00
etimberg 97cc714c94 Don't draw bars that represent data that is not valid (null, undefined, or NaN) 2015-12-31 19:32:03 -05:00
etimberg a9a003c4c4 clean up helpers file before starting work 2015-12-31 18:41:21 -05:00
Evert Timberg f7c6ca544b Merge pull request #1842 from nnnick/v2.0-fix-browserify-webpack-support
Offer window alternative to `this` context.  Fixes Webspack and Browserify support
2015-12-30 11:52:26 -05:00
Tanner Linsley ac9fe08068 Offer window alternative to this context. Fixes Webspack and Browserify support 2015-12-30 09:43:51 -07:00
Evert Timberg d9cc1219ce Better handling of large tooltips 2015-12-29 12:58:53 -05:00
Evert Timberg 824f5880fb Merge pull request #1837 from nnnick/fix/1766
Better fitting of scales
2015-12-29 10:16:46 -05:00
Evert Timberg cea6934258 Merge pull request #1836 from nnnick/fix/1740
Draw line at edge of scales
2015-12-29 10:09:54 -05:00
Evert Timberg d6a27d8eb3 Clean up code 2015-12-29 09:56:55 -05:00
Evert Timberg 081cf7ba07 Fix tests 2015-12-29 09:24:09 -05:00
Evert Timberg 0c534e1eb8 Fix layout service 2015-12-29 09:07:01 -05:00
Evert Timberg 754268890b Alias the pixel for nicer drawing 2015-12-28 09:37:31 -05:00
Evert Timberg f2899934db Draw line at edge of scales & update tests 2015-12-28 09:26:59 -05:00
Evert Timberg 5a5d698b11 Fix some errors with docs that were noticed when building 2015-12-28 08:29:54 -05:00
Evert Timberg e2206ab269 Merge pull request #1835 from nnnick/fix/release-v2-beta2
Update build & bump version
2015-12-27 11:50:05 -05:00
etimberg ff11975648 Fix issues identified in PR 2015-12-27 11:48:14 -05:00
etimberg 421e610150 Update build & bump version 2015-12-27 10:46:08 -05:00
Evert Timberg 94a8c9a27f Merge pull request #1832 from hallatore/Bug_SuggestedMinVsMin
min/max should have precedence over suggestedMin/suggestedMax
2015-12-25 10:44:29 -05:00
Tore Lervik a0c359ee80 min/max should have precedence over suggestedMin/suggestedMax 2015-12-25 13:53:09 +01:00
Tanner Linsley 31721a353c Merge pull request #1829 from nnnick/fix/1716-1731
Better tooltip positioning
2015-12-23 10:22:34 -07:00
Evert Timberg bbc6f5aa5f Fix broken test 2015-12-23 12:00:56 -05:00
Evert Timberg 968a11a631 Merge pull request #1826 from hallatore/Bug_BezierCurveAtZero
Fixed bug with bezier still being used with tension set to 0
2015-12-23 09:39:21 -05:00
Tore Lervik a1940caf91 Fixed build error bug with getting tension 2015-12-23 15:29:25 +01:00
Evert Timberg d9e1b2250e Merge pull request #1827 from hallatore/Bug_AutoSkipCheck
Fixed bug with skipRatio check not being triggered correctly.
2015-12-23 09:09:41 -05:00
Tore Lervik ad67d1ecf8 Fixed bug with skipRatio check not being triggered correctly. 2015-12-23 13:42:24 +01:00
Tore Lervik 2c178a5670 Fixed bug with bezier still being used with tension set to 0 2015-12-23 13:36:44 +01:00
Evert Timberg f170fd1b8d Improvements to tooltip alignment to avoid the canvas edges 2015-12-22 21:35:23 -05:00
Evert Timberg a423542775 Fix tests 2015-12-22 09:13:02 -05:00
Evert Timberg d5727d7bc0 Merge pull request #1819 from xriss/v2.0-dev
gulp-umd
2015-12-22 08:44:04 -05:00
Kriss 1221d8311a gulp-umd
Explicitly pass root to the factory function.
2015-12-22 13:21:23 +00:00
Evert Timberg eb61f5c3fc Merge pull request #1817 from prashcr/patch-2
Add missing comma
2015-12-22 08:19:45 -05:00
Evert Timberg fd668086b2 Merge pull request #1816 from hallatore/Bug_AutoSkip
Refactored skipRatio to use the longest label text for calculation.
2015-12-22 08:19:25 -05:00
Prashanth Chandra 8e7162ca91 Add missing comma 2015-12-22 17:50:11 +08:00
Evert Timberg 923378e2af Merge pull request #1815 from hallatore/Bug_firstTickUndefined
Bug first tick undefined
2015-12-21 19:59:12 -05:00
Tore Lervik 0437968a4e Fixed broken tests 2015-12-21 23:47:38 +01:00
Tore Lervik d134394a1d Refactored out property 2015-12-21 23:37:09 +01:00
Tore Lervik cd02434943 Refactored skipRatio to use the longest label text for calculation. 2015-12-21 23:32:52 +01:00
Tore Lervik c078ae15f0 Fixed a typo 2015-12-21 22:43:20 +01:00
Tore Lervik 86ca455cb6 Refactored firstTick null check 2015-12-21 22:40:33 +01:00
Tore Lervik 477fc72693 firstTick and lastTick can be null if the chart is empty. 2015-12-21 22:34:31 +01:00
Evert Timberg d7643bf865 Initial refactor of tooltip code 2015-12-21 15:52:33 -05:00
Evert Timberg d26ab24e3c Show rectangle points at end of bars, even negative ones. 2015-12-21 15:52:19 -05:00
Evert Timberg fc3a3aedaf Merge pull request #1814 from hallatore/Bug_SuggestedMinMax
Have to check for undefined because "if (0.0)" would equal false.
2015-12-21 14:43:41 -05:00
Tore Lervik 3577d959d0 Have to check for undefined because "if (0.0)" would equal false. 2015-12-21 20:28:20 +01:00
Evert Timberg 63b14dc2a9 Merge pull request #1810 from olyckne/fix/ticks_callback
Fix ticks callback and auto skip
2015-12-21 08:23:55 -05:00
Mattias Lyckne 888a8dd797 Update docs 2015-12-21 14:21:51 +01:00
Mattias Lyckne 7363c6fcbe Dont set autoSkip false if userCallback is defined
”The reason being is that the user could replace either callback or
userCallbac”
2015-12-21 13:59:29 +01:00
Mattias Lyckne dec4a5f57a Fix tests 2015-12-21 08:43:48 +01:00
Evert Timberg d163122536 Merge pull request #1808 from nnnick/fix/1737
Fix sizing of tooltip when beforeBody or afterBody is very long
2015-12-20 18:51:24 -05:00
Evert Timberg bafd36b5ec Fix sizing of tooltip when beforeBody or afterBody is very line 2015-12-20 18:48:44 -05:00
Evert Timberg ae643d3d76 Update built files 2015-12-20 18:31:49 -05:00
Evert Timberg 5f4e8a4c13 Merge pull request #1794 from nnnick/update-scale-lifecycle
Update Scale Lifcycle
2015-12-19 14:29:49 -05:00
Evert Timberg 29770d3e67 Merge pull request #1802 from akagroundhog/v2.0-dev
xPadding/yPadding fix in 00-Getting-Started.md
2015-12-18 17:43:07 -05:00
akagroundhog 421e294e2c xPadding/yPadding fix in 00-Getting-Started.md
xPadding is horizontal padding (left & right), yPadding is vertical padding (top & bottom).
2015-12-19 00:19:32 +03:00
Mattias Lyckne 23b2d991f7 disable autoSkip when there is a userCallback or autoSkip is set to false 2015-12-18 16:18:49 +01:00
Evert Timberg d295e49907 Merge pull request #1797 from xriss/patch-1
maxRotation test is off by one
2015-12-17 17:04:42 -05:00
Kriss d9363d637a maxRotation test is off by one
Most notable when maxRotation=0 and you end up with the text becoming non centred as it has rotated it by 1 and switched to right alligned mode.
2015-12-17 22:00:12 +00:00
Evert Timberg f7d3ea3841 Merge pull request #1788 from nnnick/fix/extended-bars
Better extensions of bar controllers
2015-12-17 09:36:15 -05:00
Evert Timberg 283f1d7387 Update check to new system + fix tests 2015-12-17 09:31:01 -05:00
Evert Timberg c8d3831152 Split out data limits step of scales into it's own step. Wire up callbacks from the options to those in the scale life-cycle. Updated the docs accordingly 2015-12-17 09:21:04 -05:00
etimberg 9aee15fe6c Updated docs 2015-12-15 20:19:32 -05:00
etimberg 8efa577ef5 Bar dataset controller needs a better way to know which datasets are bars since users could make their own bar types. 2015-12-15 20:13:37 -05:00
Evert Timberg 3ccf3fd249 Merge pull request #1787 from nnnick/fix/min-max
Updates new min/max settings
2015-12-15 19:35:46 -05:00
Evert Timberg cddfba1676 Better test 2015-12-15 19:33:38 -05:00
Evert Timberg 274897fc24 Fix tests 2015-12-15 19:30:09 -05:00
Evert Timberg f51d7753bd Update logarithmic algorithm 2015-12-15 19:18:18 -05:00
Evert Timberg 3e3912973c Slight improvement to new min/max options so that linear scales look right 2015-12-15 18:58:05 -05:00
Evert Timberg 6d490fbbbb Merge pull request #1779 from olyckne/adds_min_and_max_to_y_axes
Adds min and max setting to axes
2015-12-14 21:55:17 -05:00
Mattias Lyckne 968db4e783 Adds min and max setting to axes 2015-12-14 09:22:34 +01:00
Evert Timberg 1170ab5481 Merge pull request #1778 from nnnick/fix/1582
Update docs for polar area / doughnut charts + extending chart.js
2015-12-13 16:54:20 -05:00
Evert Timberg c2ee14dec9 Update docs. Improved pie / polar area docs. Updated advanced docs regarding extending scales / chart types 2015-12-13 15:29:57 -05:00
Evert Timberg 139cbe1c64 All dataset controllers now inherit from a common base class Chart.DatasetController. This makes writing external controllers much easier 2015-12-13 14:35:40 -05:00
Evert Timberg 1854ea086c Merge pull request #1775 from nnnick/fix/1711
Call animation callbacks.
2015-12-12 10:12:49 -05:00
Evert Timberg 716e303230 Call animation callbacks. Created a sample file that shows their use by updating a progress bar during the animation. Updated the documentation to show how they are called. 2015-12-12 10:01:08 -05:00
Evert Timberg 47d04ced8f Merge pull request #1755 from nnnick/fix/1725
Build controllers before scales are updated to ensure scale IDs are correct
2015-12-12 09:05:39 -05:00
Evert Timberg 95332e39f5 Merge branch 'v2.0-dev' into fix/1725
Conflicts:
	src/core/core.controller.js
2015-12-12 09:01:59 -05:00
Evert Timberg ae3025a2e1 Merge pull request #1774 from nnnick/fix/1762
Handle tension being set to 0 properly
2015-12-12 08:56:10 -05:00
Evert Timberg 39e5daaca8 Better property picking. Added a helper function so we don't have to write a complicated ternary everywhere. Updated tests accordingly. 2015-12-12 08:52:06 -05:00
Derek Perkins 4add69432f Merge pull request #1750 from nnnick/v2.0-legend
Legend and Title Support
2015-12-11 18:52:26 -07:00
Derek Perkins 7825ee5ef2 Merge pull request #1770 from dchesterton/patch-1
Lowercase NPM package name
2015-12-11 18:51:21 -07:00
Daniel Chesterton 4eed79ee52 Lowercase NPM package name 2015-12-11 23:58:56 +00:00
Evert Timberg 571120d650 Merge pull request #1756 from nnnick/fix/code-climate
Fix up issues in core scale
2015-12-08 21:49:33 -05:00
Evert Timberg 7999aab26a Fix up issues in core scale 2015-12-08 20:22:02 -05:00
Evert Timberg d689e0fc47 When only the dataset array changes scales did not update correctly. This was due to the fact that the new datasets did not have scale IDs yet. By building the controllers first, the IDs are mapped if necessary. Then we can correctly update scales. 2015-12-08 19:57:58 -05:00
Evert Timberg 819f865723 Merge branch 'v2.0-dev' into v2.0-legend
Conflicts:
	src/controllers/controller.doughnut.js
2015-12-07 22:10:38 -05:00
Evert Timberg 4f8f182d21 Better sizing when not displaying 2015-12-07 21:58:48 -05:00
Evert Timberg a2e1a97382 Update docs + remove unused config option since we don't need 2 different callbacks. 2015-12-07 21:52:15 -05:00
Evert Timberg 60920cd75a Polar area legend toggles data 2015-12-07 21:42:58 -05:00
Evert Timberg 59b7927994 Toggling of doughnut items now works 2015-12-07 21:23:20 -05:00
Evert Timberg 8befbbe8f0 Use config onClick function to toggle datasets for bars/lines/radar charts. 2015-12-07 20:36:44 -05:00
Evert Timberg b0f69a1092 Generate nice legend boxes for all current chart types 2015-12-07 19:11:54 -05:00
Evert Timberg 3b750e7f27 Merge pull request #1749 from nnnick/fix/code-climate
Fix some issues found by code climate
2015-12-07 18:26:51 -05:00
Evert Timberg ffa2870b56 Fix a few more issues in the tooltips 2015-12-07 18:23:51 -05:00
Evert Timberg 1cb7dde0d5 Start fixing code climate issues 2015-12-07 18:19:56 -05:00
Evert Timberg 20b9395585 Merge pull request #1745 from nnnick/fix/1710
Remove unused tooltip options
2015-12-07 17:46:49 -05:00
Tanner Linsley 73e9ff44fe Merge pull request #1744 from nnnick/fix/1466
Time Scale Updates for Tooltips
2015-12-07 12:10:12 -07:00
Evert Timberg bffbaf6b37 Generate label strings using an option function. This allows new chart types to override 2015-12-06 12:53:45 -05:00
Evert Timberg eba2fce923 Docs + move defaults to correct place. 2015-12-06 11:19:55 -05:00
Evert Timberg 792ee587ae Split legend and title block functionality into 2 separate blocks. This allows the title to be on the top of the chart while the legend is on the bottom 2015-12-06 10:20:38 -05:00
Evert Timberg eaf183352c Polar are controller needs a similar update to the doughnut controller 2015-12-06 10:19:09 -05:00
Evert Timberg 7ab2a5ed9a Remove unused xOffset property from the tooltip. Use the multiKeyBackground. Update documentation accordingly. 2015-12-06 09:38:19 -05:00
Evert Timberg 28fc6841f3 Add tooltipFormat option to time scale options.
Fix bars when displayed on a time scale.
Updated sample files.
2015-12-05 19:33:33 -05:00
Evert Timberg 5df23df291 Move time sample files to sub folder 2015-12-05 10:54:45 -05:00
Evert Timberg 52ae1f7d3c Merge pull request #1743 from nnnick/fix/1576
Gracefully handle setting `options.animation` to `false`
2015-12-05 10:44:24 -05:00
Evert Timberg 0c247dde28 Gracefully handle setting options.animation to false which occurs when migrating configs from v1. 2015-12-05 10:40:05 -05:00
Evert Timberg 784fa78267 Merge pull request #1738 from nnnick/fix/1735
Call `beforeBody` and `afterBody` using the correct function.
2015-12-05 10:01:15 -05:00
Evert Timberg d21b3c6d7e Merge pull request #1741 from nnnick/fix/1706
Highlight correct items in dataset mode
2015-12-05 10:01:03 -05:00
Evert Timberg a1e35ade49 Merge pull request #1742 from nnnick/fix/1715
Fixes rotational animation of new arcs
2015-12-05 10:00:45 -05:00
Evert Timberg 89da20354c Fix tests 2015-12-05 09:55:17 -05:00
Evert Timberg 2f1006c6de Make sure we always have a valid end angle when reseting the model. Previously this was undefined and interpreted as 0 in the animation code. 2015-12-05 09:39:25 -05:00
Evert Timberg 744e1429b9 Label polar area and doughnut datasets 2015-12-04 20:32:18 -05:00
Evert Timberg 59fb1696a8 Highlight correct items when hover mode is set to 'dataset' 2015-12-04 20:01:04 -05:00
Evert Timberg 38afefde25 Doughnut controller needs to obey chart area size 2015-12-04 19:22:48 -05:00
Evert Timberg d905f19355 Fix draw issue when radar chart dataset has 0 points and hence no children 2015-12-03 22:04:00 -05:00
Evert Timberg d8704ee37d Add legends to sample files 2015-12-03 22:03:39 -05:00
Evert Timberg 0b260d57cc Fix JSHint issue 2015-12-03 21:25:36 -05:00
Evert Timberg dcc06eb3bb Merge branch 'v2.0-dev' into v2.0-legend
Conflicts:
	src/core/core.scaleService.js
2015-12-03 21:21:10 -05:00
Evert Timberg 0a92cf1b40 Call beforeBody and afterBody using the correct function. 2015-12-03 18:46:21 -05:00
Tanner Linsley 62bc4e42ec Merge pull request #1736 from nnnick/umd-build
Umd build
2015-12-02 20:37:04 -07:00
etimberg 95a172df06 Remove old and stuff. Use the correct color variable instead of window.color 2015-12-02 22:15:03 -05:00
etimberg 40c8289ce8 Time scale uses moment loaded through UMD 2015-12-02 21:10:51 -05:00
etimberg b388a1e873 Pipe the build through UMD to get proper UMD headers 2015-12-02 21:08:52 -05:00
Evert Timberg 14c2cf56d1 Merge pull request #1728 from ashayas/bugfix/1722
Realized minRotation not needed, removed as an option and removed from tests
2015-12-02 07:30:55 -05:00
npsecoding 164671ffeb Realized minRotaion not needed, removed as an option and removed from tests 2015-12-01 22:29:19 -08:00
Tanner Linsley 05043d4771 Merge pull request #1724 from nnnick/fix/1717
Allow time scale to use multiple of base units
2015-12-01 19:42:31 -07:00
etimberg 25f061f340 Fix test failures 2015-12-01 21:07:53 -05:00
etimberg bf277473c6 Update scale fitting to prevent horizontal scales from jumping around. 2015-12-01 21:01:13 -05:00
etimberg 6b3fd19fa9 Time scale will now scale units. For example, it will try 1hr then 2hrs then 3 hrs then 6 hrs then 12 hrs ... until it finds a unit that fits. 2015-12-01 20:02:44 -05:00
etimberg c074d3b7d4 Update built files 2015-11-30 21:35:09 -05:00
Evert Timberg 6cce958548 Merge pull request #1720 from nnnick/fix/1718
Allow the user to change the time label display formats
2015-11-30 20:50:00 -05:00
etimberg ccb1c68b65 Update docs 2015-11-30 20:47:49 -05:00
etimberg f609452727 Allow the user to change the time label display formats 2015-11-30 20:42:48 -05:00
Evert Timberg b2150b93a2 New built files + some sample file updates 2015-11-29 13:33:24 -05:00
Evert Timberg b9fa20714f Merge pull request #1713 from nnnick/v2.0-beta1-docs
Initial docs to get ready for beta1
2015-11-29 13:13:01 -05:00
Evert Timberg e5ee242dc6 Merge branch 'v2.0-dev' into v2.0-beta1-docs
Conflicts:
	docs/01-Scales.md
2015-11-29 11:32:57 -05:00
Evert Timberg 9dbc5650ed Initial update to line and bar docs 2015-11-29 11:30:39 -05:00
Evert Timberg 0052ceb7a1 Initial update to scale documentation 2015-11-29 10:58:01 -05:00
Evert Timberg e91e6be851 Merge pull request #1696 from nnnick/fix/1688
When tooltip opacity is less than 1e-3, round to 0.
2015-11-29 10:16:25 -05:00
Evert Timberg 349586e14c Merge pull request #1695 from nnnick/fix/consistent-display-parameters
Fix inconsistent display parameters
2015-11-29 10:16:20 -05:00
Evert Timberg c4b30a7b0e Update getting started docs 2015-11-29 10:04:46 -05:00
Evert Timberg f0555af8cc Another build 2015-11-27 17:37:42 -05:00
Evert Timberg e5244b7dba Merge branch 'v2.0-dev' of https://github.com/nnnick/Chart.js into v2.0-dev 2015-11-27 17:37:14 -05:00
Evert Timberg bf2ca8bd0b Push up new built files 2015-11-27 17:35:34 -05:00
Evert Timberg f4bcef13f5 Merge pull request #1704 from Marius2805/v2.0-dev
V2.0 Docs: Fixed wrong example data structure for Pie/Doughnut Chart
2015-11-27 07:25:22 -05:00
Evert Timberg efdc23c567 Merge pull request #1703 from wuchangming/v2.0-dev
V2.0 dev 	Bug in handler event.type='touchend'
2015-11-27 07:24:53 -05:00
Marius Meißner e84d27dde7 Fixed wrong structure of example data 2015-11-27 08:34:32 +01:00
wuchangming 7aa2fd1af3 Bug in handler event.type='touchend'
In Chorme.
while event.type = "touchend” ,  event.touches is a empty TouchList,
event.touches.length === 0
2015-11-27 11:16:54 +08:00
wuchangming 5a1c968105 Merge remote-tracking branch 'nnnick/v2.0-dev' into v2.0-dev 2015-11-27 08:50:55 +08:00
Evert Timberg e87fd9e0cc Merge pull request #1702 from wuchangming/v2.0-dev
no such file
2015-11-26 07:41:23 -05:00
wuchangming dae1e429b8 no such file 2015-11-26 19:35:25 +08:00
Evert Timberg 55670b0cf7 When opacity is less than 1e-3, round to 0. IE11/Edge had problems with very small opacities on the order of 1e-10. 2015-11-25 19:31:26 -05:00
Evert Timberg 5f7507c324 Update docs 2015-11-24 19:21:09 -05:00
Evert Timberg a90aac7b26 Change scale show properties to display and update tests 2015-11-24 19:18:15 -05:00
Evert Timberg cf1f772157 Merge pull request #1693 from wcatron/basic-documentation
Add descriptions for options in documentation.
2015-11-24 18:22:33 -05:00
wcatron 8e9fef27c2 Add more explanation of bar and category percentage. 2015-11-24 14:25:15 -05:00
wcatron 75fb79f814 Fill out descriptions and add link to scales. 2015-11-24 14:06:38 -05:00
wcatron f4ef56993d Add full description text for scales. 2015-11-24 13:36:48 -05:00
Evert Timberg 3bfbf10cff Merge pull request #1689 from wcatron/basic-documentation
Update getting started example code.
2015-11-24 08:03:26 -05:00
Evert Timberg e6ea34e453 Merge pull request #1690 from byCedric/fix/canvas-dimensions-ie10-ie9
Updated retina scale to allow rendering in IE10 and IE9.
2015-11-24 08:00:41 -05:00
Cedric van Putten ae51789c32 Stored pixel ratio in a variable with a fallback value for browsers that doesn't support window.devicePixelRatio fixing rendering issues for IE10 and IE9. (issue #1622) 2015-11-24 11:26:24 +01:00
wcatron 4d48ab5109 Add suggested min and max to documentation. 2015-11-24 02:28:15 -05:00
wcatron c75c21105a Create very simple getting started example code. 2015-11-23 23:59:24 -05:00
Evert Timberg 830cf33c1f Merge pull request #1687 from wcatron/basic-documentation
Converting documentation to tables - radar, polar, and pie
2015-11-23 22:37:04 -05:00
etimberg 37abe74d43 Improve drawing when title is placed below legend boxes 2015-11-23 22:12:34 -05:00
etimberg ea15aaaec2 Fix draw issue 2015-11-23 21:54:45 -05:00
Evert Timberg 10d056a4d1 Adds strikethrough of legend text when dataset is hidden 2015-11-23 21:04:41 -05:00
wcatron a0377362d7 Update remainder of tables for radar, polar, and pie. 2015-11-23 19:32:38 -05:00
Evert Timberg 0d1f63e601 Update after legend toggle since scales may need to change 2015-11-23 19:03:24 -05:00
Evert Timberg afc6d9094b Allow clicking on legend text 2015-11-23 18:58:51 -05:00
Evert Timberg 420290969e Merge pull request #1684 from wcatron/basic-documentation
Converting documentation to tables - scales, line, and bar
2015-11-23 18:16:27 -05:00
wcatron dc152f875f Clean up periods and comments. 2015-11-23 12:09:40 -05:00
wcatron a4a07df612 Update options to tables, update example for bar. 2015-11-23 12:03:38 -05:00
Evert Timberg 60c1609ba9 Initial toggling of datasets from the legend.
Still need to do:
- clicking on text in legend
- toggling style of legend based on dataset style
- figure out if we need an
2015-11-22 22:31:08 -05:00
Evert Timberg a08f8b3015 Fix typo 2015-11-22 13:26:01 -05:00
Evert Timberg df13f819b5 Merge pull request #1669 from wcatron/basic-documentation
Update getting started documentation default options w/ table.
2015-11-22 13:12:31 -05:00
etimberg 0a17edd1ae Minor improvement to code that gets active elements 2015-11-21 22:44:11 -05:00
etimberg 2efb974189 ensure that fullwidth boxes are at very top / bottom 2015-11-21 22:10:39 -05:00
Evert Timberg 7b719e6432 Modify layout service to be able to place horizontal boxes as either full width or not full width. Currently the legend is the only full width box we have. Scales were modified so as not to be full width, however Core.Scale can handle boxes that are full width.
Updated unit tests to use correct 'boxes' property of chart instance. Tests did not require numerical updates!

Added a test to cover placing a full width box.
2015-11-21 10:51:32 -05:00
Evert Timberg 2a9b3e5221 Merge branch 'v2.0-dev' into v2.0-legend
Conflicts:
	src/core/core.controller.js
2015-11-21 09:23:33 -05:00
Evert Timberg a888aba61e Merge pull request #1670 from nnnick/fix/1643
Fixes scatter and bubble chart tooltips
2015-11-21 09:20:58 -05:00
Evert Timberg 800246660a Remove commented code 2015-11-19 21:20:04 -05:00
Evert Timberg ca2e017f80 Update default tooltip configs for scatter charts. Made scatter charts a first class chart type. 2015-11-19 21:15:59 -05:00
Evert Timberg 1471a61609 Update default tooltip callbacks for bubble charts 2015-11-19 21:12:23 -05:00
wcatron 1580d1ed4d Update line chart documentation options to table. 2015-11-19 19:55:12 -05:00
wcatron 34aaeac421 Update getting started documentation default options w/ table. 2015-11-19 16:14:13 -05:00
Evert Timberg 0c69c9a79c Merge pull request #1668 from wcatron/basic-documentation
Updates basic documentation for bar, radar, and doughnut.
2015-11-19 13:39:48 -05:00
wcatron 5400a61ff1 Update doughnut documentation for intiializer and data. 2015-11-19 11:47:47 -05:00
wcatron 942cf5e718 Update Rader initializer and data structure keys. 2015-11-19 11:43:00 -05:00
wcatron f32d62722a Update initializer documentation for Bar. 2015-11-19 11:35:38 -05:00
Evert Timberg 82a74701a7 Merge pull request #1667 from nnnick/fix/pie-legend
Pie and Polar area legend functions
2015-11-18 21:38:52 -05:00
Evert Timberg 09d2f1d900 Merge pull request #1662 from nnnick/fix/string-linear-data
Handle data as strings in numeric scales
2015-11-18 21:35:56 -05:00
etimberg 7edcc0659b Fix polar area legends 2015-11-18 21:30:16 -05:00
etimberg 673e5d59a5 fix pie & doughnut legend 2015-11-18 21:24:49 -05:00
Evert Timberg ead6247cd8 Make sure data is converted to a number in scales when determining min and max. Add tests for this condition to linear, radialLinear, and logarithmic scales. 2015-11-17 18:43:18 -05:00
Evert Timberg e00f9d5790 Fix tests 2015-11-17 18:38:19 -05:00
Tanner Linsley fe77f07c07 Merge pull request #1642 from nnnick/fix/1527
Doughnut, polar area, and radar samples should use the same canvas style
2015-11-16 16:10:24 -07:00
Tanner Linsley 5a80b9e501 Merge pull request #1645 from nnnick/fix/null-callback
Hide lines for which the tick label callback returns null or undefined
2015-11-16 16:10:16 -07:00
Tanner Linsley ae9db841f9 Merge pull request #1646 from nnnick/fix/1640
Can now replace entire chart data object on the fly
2015-11-16 16:10:01 -07:00
Tanner Linsley 937d866bd3 Merge pull request #1647 from nnnick/fix/1324
Fall back to line settings for points if necessary
2015-11-16 16:09:53 -07:00
Tanner Linsley 592414330b Merge pull request #1644 from nnnick/fix/touch-events
Do not bind to touchend events for tooltips
2015-11-16 16:09:41 -07:00
Tanner Linsley ac098b8b2f Merge pull request #1653 from nnnick/fix/1381
Fixes flickering during animations
2015-11-16 16:07:58 -07:00
Evert Timberg 3a193e2117 Update samples 2015-11-15 11:17:02 -05:00
Evert Timberg 0495e45ff7 Can now skip in all cases (start, mid, end) whether or not there is a look 2015-11-15 11:16:41 -05:00
Evert Timberg 045d8f6c2a Keep this as NaN so point._view.skip is set correctly 2015-11-15 11:16:17 -05:00
Evert Timberg 9c78de10ba Fix line tests. Still need to add tests of the skip code. 2015-11-14 23:16:07 -05:00
Evert Timberg 37249e4375 Fix an incorrect test setup 2015-11-14 22:52:10 -05:00
Evert Timberg d61745a311 Handle transitioning NaNs 2015-11-14 22:49:53 -05:00
Evert Timberg 55c7d6872a Prevent NaN results when previous, point, and next are all the same 2015-11-14 22:49:08 -05:00
Evert Timberg 3bd9120a3a some duplicate code cleanup 2015-11-14 22:06:37 -05:00
Evert Timberg 01fe535594 Refactor the lineToNextPoint functionality to give the correct draw line behaviour. Makes the code a little cleaner too. 2015-11-14 21:57:22 -05:00
Evert Timberg f6ac7d9369 Typo 2015-11-13 22:42:42 -05:00
Evert Timberg 0e02d216aa Cleanup 2015-11-13 22:42:33 -05:00
Evert Timberg 108c4fcd56 Simplify code for capping bezier control points. Cap the X direction as well. 2015-11-13 22:15:23 -05:00
Evert Timberg 05523b01b0 Refactor the line drawing code. Tests are broken. 2015-11-13 22:04:38 -05:00
Evert Timberg be07f052d9 Merge pull request #1649 from nnnick/fix/scale_fitting
Improve the fitting of vertical axes
2015-11-13 13:57:00 -05:00
Evert Timberg 7f34d8dd2f Always include padding to ensure that we can always see the tick labels of vertical axes 2015-11-13 13:24:22 -05:00
Evert Timberg f85ffbc09c Use the dataset backgroundColor, borderWidth, and borderColor, if specified, for points. Added tests for this case. 2015-11-13 11:21:44 -05:00
Evert Timberg 6d708a8f2c Update line sample to change the entire data object 2015-11-13 10:01:38 -05:00
Evert Timberg 66bc1dc492 Reference data from the main controller wherever possible. Updated tests to account for this. 2015-11-13 09:38:35 -05:00
Evert Timberg 8e3ba9d88e Update tooltip colour draw code 2015-11-13 08:20:39 -05:00
Evert Timberg 1e4894d625 Test for skipping drawing 2015-11-11 21:49:07 -05:00
Evert Timberg 14b6fdd51e Bail out, same as the x axis 2015-11-11 21:40:29 -05:00
Evert Timberg 3099d967da Do not bind to touchend events. This is the same as v1.x 2015-11-11 21:21:25 -05:00
etimberg 471a5f5aaa Doughnut, polar area, and radar samples should use the same canvas style 2015-11-11 19:06:36 -05:00
Evert Timberg fff13f2692 Merge pull request #1632 from pascoual/v2.0-dev
Fix: no tooltips when missing data for one or more dataset
2015-11-09 19:46:41 -05:00
Pascoual 234efc5267 Fix: tooltips checks indent 2015-11-10 01:00:30 +01:00
Pascoual c4d02a8f96 Fix: no tooltips when missing data for one or more dataset 2015-11-10 00:53:08 +01:00
Tanner Linsley 21efd50fb7 Merge pull request #1628 from nnnick/chrome-travis
Travis CI should also run tests on chrome
2015-11-07 14:00:34 -07:00
Evert Timberg 972ceb24e6 Fix tests 2015-11-07 09:40:41 -05:00
Evert Timberg 679ac764b1 Travis CI should also run tests on chrome 2015-11-07 09:34:07 -05:00
Evert Timberg 962b99e8d3 Merge pull request #1627 from pascoual/v2.0-dev
Add: options.ticks.maxTicksLimit
2015-11-06 19:56:29 -05:00
Pascal Richier 3d15e1ff54 Update doc for options.ticks.maxTicksLimit 2015-11-07 01:46:14 +01:00
Pascal Richier 178880bace Update doc for options.ticks.maxTicksLimit 2015-11-07 01:42:19 +01:00
Pascal Richier d5d63070c6 Add options.ticks.maxTicksLimit
To be able to change default '11' value
2015-11-07 01:39:30 +01:00
Pascal Richier 97da3347be Add options.ticks.maxTicksLimit
To be able to change default '11' value
2015-11-07 01:37:09 +01:00
Evert Timberg d6252df4cd Merge pull request #1601 from nnnick/fix/stacked-bar-line-scale
Fixed stacked scale calculation for combo charts
2015-11-03 18:14:37 -05:00
Evert Timberg 33308616af Merge pull request #1612 from enumag/patch-1
typo
2015-11-03 08:47:43 -05:00
Jáchym Toušek 68255893cf typo 2015-11-03 13:49:34 +01:00
Evert Timberg 57d8155bb0 Merge pull request #1606 from levithomason/patch-1
Fix getting started global chart config typo
2015-11-02 07:29:46 -05:00
Levi Thomason 92841cd38a fix getting started global chart config typo 2015-11-01 23:03:14 -08:00
Derek Perkins 29c3bd3746 Merge pull request #1603 from nnnick/fix-tooltips
Only call custom tooltips when elements have changed.  But be sure to call update internally any time that tooltips need to be redrawn.
2015-11-01 22:52:46 -07:00
Tanner Linsley b0380d4ede Check if dataset is visible when adding active elements to a tooltip 2015-11-01 22:50:16 -07:00
Tanner Linsley 28bc80e439 ElementsAtLabel now returns all datasets' elements at the found index 2015-11-01 22:44:31 -07:00
Tanner Linsley d46524aedc Tooltip's label mode now uses average position of all points 2015-11-01 22:43:44 -07:00
Evert Timberg 677c043a91 Built files 2015-11-01 20:42:13 -05:00
Tanner Linsley 50d9389dce Merge pull request #1604 from nnnick/fix/stacked-bar-x
Fixes bar charts when only Y scale is in stacked mode
2015-11-01 18:36:55 -07:00
Evert Timberg 2c04a816d7 Use correct option to detect stacked mode along x axis. 2015-11-01 20:26:58 -05:00
Tanner Linsley f4a5a30451 Only call custom tooltips when elements have changed. But be sure to call update internally any time that tooltips need to be redrawn. 2015-11-01 13:56:36 -07:00
Evert Timberg 4267d01bc2 Log scale + tests 2015-11-01 09:07:18 -05:00
Evert Timberg 8324b35506 Update linear scale + tests 2015-11-01 08:45:12 -05:00
Derek Perkins b823bae63e Merge pull request #1600 from nnnick/fix-line-stacked-area
Fix line stacked area
2015-10-31 22:48:29 -06:00
Tanner Linsley 334ba44e95 Allow line controller to calculate stacked values 2015-10-31 22:45:25 -06:00
Tanner Linsley e4d308f329 Stacked Area Example 2015-10-31 22:45:11 -06:00
Evert Timberg cf587122da Merge pull request #1586 from nnnick/fix/begin-at-zero-issue-with-constant-data
Scale expansion if min === max will only occur after ticks.beginAtZero is handled
2015-10-31 20:23:57 -04:00
Tanner Linsley 93a79ec470 Commit Built Files 2015-10-31 18:22:52 -06:00
Derek Perkins 3d862962f7 Merge pull request #1599 from nnnick/fix-more-custom-tooltips
Fix more custom tooltips
2015-10-31 18:21:54 -06:00
Tanner Linsley 69bff1183f Better Example 2015-10-31 18:17:52 -06:00
Tanner Linsley 93a923d38f Remove logs 2015-10-31 18:17:42 -06:00
Tanner Linsley 22aabdbfab Update tooltip only when things change (which will only trigger customTooltips when model changes) 2015-10-31 18:17:32 -06:00
Tanner Linsley 5ba1ec0d3b More concise change detection 2015-10-31 18:17:06 -06:00
Tanner Linsley 8398d26d10 Remove Tooltip opacity from core-controller 2015-10-31 18:16:35 -06:00
Tanner Linsley fa33f3158e Don't kill lastActives on chart hover exit 2015-10-31 18:15:58 -06:00
Tanner Linsley 0fa03fad24 Handle opacity in the tooltip update method 2015-10-31 18:14:56 -06:00
Tanner Linsley 91bacf8e51 Commit Built Files 2015-10-31 16:40:23 -06:00
Evert Timberg a848142274 Merge pull request #1597 from nnnick/fix-custom-tooltips
Fix custom tooltips
2015-10-31 18:16:08 -04:00
Tanner Linsley be50c63e72 commas to pass jshint 2015-10-31 16:09:11 -06:00
Tanner Linsley 0494d551b6 Custom Tooltip example now works with the basics 2015-10-31 16:08:55 -06:00
Tanner Linsley ecf5801787 call the custom callback in tooltip options 2015-10-31 16:07:57 -06:00
Tanner Linsley 753fd79bf3 Call tooltip update even when tooltip has no active elements 2015-10-31 16:07:36 -06:00
Tanner Linsley 2845d39311 Merge pull request #1596 from nnnick/fix/v2.0-beta0-tooltips
Improve v2.0.0-beta0 tooltips
2015-10-31 11:23:47 -06:00
Evert Timberg 29002b2efb Fix old scaleService tests that are now testing the layoutService 2015-10-31 13:10:06 -04:00
Evert Timberg e8f80ca211 Rename test file 2015-10-31 13:08:36 -04:00
Evert Timberg 07b052cfab Tests for suggestedMin and suggestedMax options 2015-10-31 11:40:51 -04:00
etimberg 3aaa3e27f3 suggestedMin and suggestedMax options for scales 2015-10-31 11:01:40 -04:00
etimberg c316f90999 Polar area tooltip improvements 2015-10-30 21:04:45 -04:00
etimberg b8e57144cc Doughnut chart tooltips work 2015-10-30 20:48:31 -04:00
etimberg 1017934dce tooltips for radar charts are working 2015-10-30 20:35:36 -04:00
etimberg 6716dbb7e5 Fix up arguments to tooltip callbacks. Simplified code in some places and removed old code. 2015-10-30 20:12:05 -04:00
etimberg 9bebedd967 Play around with tooltip to see if a better API is possible. No longer crashes for polar area / doughnut / radar charts 2015-10-28 22:52:43 -04:00
etimberg 988034cef6 Scale expansion if min === max will only occur after ticks.beginAtZero is handled 2015-10-27 20:04:21 -04:00
Tanner Linsley a1fb98c79f Line Sample Updated 2015-10-27 02:34:31 -06:00
Tanner Linsley 872b7b6161 Legend now centers labels and draws their box colors/styles 2015-10-27 02:34:23 -06:00
Tanner Linsley ab2c3ce4e9 Linear Scale now plays nice with full width 2015-10-27 02:33:45 -06:00
Tanner Linsley 2bc386ee81 Category Scale now plays nice with full width 2015-10-27 02:33:34 -06:00
Tanner Linsley 15ff3f9edc Core Scale now plays nice with layoutService and full width 2015-10-27 02:33:19 -06:00
Tanner Linsley 9ab505caec Layout Service readability & reorganization
The layout service now treats all horizontal boxes as full width.
Scales are expected to use the margins to know where to line up with
the chartArea.
2015-10-27 02:32:55 -06:00
Tanner Linsley 85572d7b67 element.line.js now passes tests 2015-10-26 19:40:52 -06:00
Tanner Linsley 74c04a354a Do not draw line up on first point of line 2015-10-26 19:24:48 -06:00
Tanner Linsley a91dba3e8a 50% Canvas Legend Support 2015-10-26 13:57:59 -06:00
Tanner Linsley dac859ec1c Rename 01-Scales to 01-Scales.md
Closes #1574
2015-10-26 12:47:37 -06:00
Tanner Linsley e8165348db Updated Readme, and versions for beta release 2015-10-24 17:17:13 -06:00
Tanner Linsley a4d11bd1a6 Built Distributables 2015-10-24 16:47:24 -06:00
Tanner Linsley 559ee6291e Merge pull request #1567 from nnnick/fix/rounding
Better linear scale tick formatter + small tick generation
2015-10-24 01:40:43 -06:00
Tanner Linsley 6dc651a79f Merge pull request #1566 from nnnick/v2.0-dev-skip-null-fixes
V2.0 dev skip null fixes
2015-10-24 01:35:42 -06:00
Tanner Linsley 4d009d116d Use the new travis CI docker framework (hopefully) 2015-10-24 01:31:08 -06:00
Tanner Linsley 6adf39e233 radialLinear scale tests now expect rounded values
The rounding problems compounded in a few areas (like the
distanceFromCenter function and drawingArea property).  Those are now
more accurate.
2015-10-24 01:25:00 -06:00
Tanner Linsley e7b71aa909 Line element and controller tests now coincide with the latest skipNull refactor 2015-10-24 01:23:51 -06:00
Tanner Linsley 2cd4b13135 radialLInear getPointPosition now rounds crazy decimals
This particular part of testing was succeeding in chrome, and failing
in firefox.  It should be rounded anyway.
2015-10-24 01:23:13 -06:00
Tanner Linsley 1c40d50097 recursive and accurate getRightValue 2015-10-24 01:22:12 -06:00
etimberg f22c0f3322 Fix tests affected by changes to default label formatter 2015-10-23 22:11:59 -04:00
etimberg 0c3d9ec5dd Improved number format function. Also improved the generation of small tick values 2015-10-23 22:00:59 -04:00
Tanner Linsley ea571003d9 Scale min/max calculations now disregard bad values 2015-10-23 16:41:11 -06:00
Tanner Linsley e50d2f7fc3 Point Skipping now draws properly and is easier to understand 2015-10-23 16:37:34 -06:00
Tanner Linsley 7b13e902ff Bad values for data are now converted to NaN 2015-10-23 16:36:59 -06:00
Tanner Linsley 9d540cebb6 SplineCurve function now graciously handles skipped points 2015-10-23 16:36:33 -06:00
Tanner Linsley afc40e7dbc Radar controller now skips non-numerical coordinates 2015-10-23 16:36:00 -06:00
Tanner Linsley ae0d9b0c68 Line controller now skips non-numerical coordinates 2015-10-23 16:35:52 -06:00
Tanner Linsley 8081e9c801 Bubble controller now skips on non-numerical coordinates 2015-10-23 16:34:40 -06:00
Tanner Linsley 3a20d1187e Merge pull request #1542 from nnnick/v2.0-dev-tooltip-refactor
V2.0 dev tooltip refactor
2015-10-23 13:02:57 -06:00
Tanner Linsley 60f2426774 Only use active datasets in the tooltip body 2015-10-23 12:41:21 -06:00
Tanner Linsley bc41909e7a Track lastTooltipActive for change animations
Since we split up the hover and tooltips modes, both changes need to be
tracked for visual updates between the two.
2015-10-23 12:41:21 -06:00
Tanner Linsley 7a042bc7eb Merge pull request #1559 from posgarou/bugfix/chart_undefined_in_core_helper
Fix mistaken variable assignment in core files
2015-10-22 12:04:16 -06:00
Ryan Mitchell 57979a2270 Fix similar typos in core.controller & element 2015-10-22 12:47:45 -04:00
Ryan Mitchell ef1c4fb0cb Fix typo in core.helpers.js 2015-10-22 12:41:03 -04:00
etimberg 965d74e34a Time scale test fix for optional labels 2015-10-21 21:00:13 -04:00
etimberg 854c1af45e test fix 2015-10-21 20:47:22 -04:00
etimberg 24e8fe3a4b Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev-tooltip-refactor 2015-10-21 20:18:23 -04:00
Tanner Linsley 511e82abb9 Merge pull request #1551 from nnnick/travis-unit-test
Unit tests work better with Travis
2015-10-20 18:38:27 -06:00
etimberg e46a2cb074 Fix JSHint errors 2015-10-20 20:33:51 -04:00
Evert Timberg 351ccaf2f2 Fix 2 test fails 2015-10-20 20:12:56 -04:00
Evert Timberg 2e77651dd2 Test in firefox on travis 2015-10-20 20:08:41 -04:00
Tanner Linsley 35011e5ae3 Support min and max dates on time scale 2015-10-19 21:23:01 -06:00
etimberg bfabac945f Labels are now optional for the time scale. 2015-10-19 19:20:08 -04:00
Evert Timberg 5495a34d02 Fix 2 fails due to a bug fix for the scale label colour. 2015-10-18 19:57:06 -04:00
Evert Timberg d0475b8052 Down to 3 test failures 2015-10-18 19:48:57 -04:00
Evert Timberg 86a52d0302 Fix some test failures 2015-10-18 19:34:56 -04:00
etimberg 2b057cf690 Merge remote-tracking branch 'origin/v2.0-dev' into v2.0-dev-tooltip-refactor 2015-10-18 18:17:39 -04:00
etimberg 082391e385 Update docs a bit for new items. Small updates for tooltip labels. 2015-10-18 18:14:56 -04:00
etimberg 7603b3cc36 Time scales now support passing in data as points. Added this to the time scale sample file. 2015-10-18 18:00:46 -04:00
etimberg ceaa4ff03f Add a helper function to reduce code size 2015-10-18 16:31:18 -04:00
etimberg 180209e55c Factor out getLabelForIndex into each scale so we can return appropriate data based on the scale type 2015-10-18 16:13:57 -04:00
etimberg f650445ddc Use correct function to get afterBody lines for tooltip. 2015-10-18 10:39:54 -04:00
Tanner Linsley 19a7c57e2f All tooltip callbacks support arrays for lines, and no drawing invisible tooltips.
Simply return a string for a single line tooltip, or return an array to
create multiple lines.
2015-10-17 15:53:33 -06:00
Evert Timberg 9526c77675 Merge pull request #1512 from nnnick/v2.0-dev-bubble-controller
Bubble Chart Type and Bubble Controller
2015-10-17 08:46:44 -04:00
Evert Timberg 3d6ff09847 Merge pull request #1541 from nnnick/v2.0-dev-testing-fixes
Testing fixes for time scale
2015-10-17 08:30:37 -04:00
Tanner Linsley e0918817ae Testing fixes for time scale 2015-10-16 21:14:07 -06:00
Tanner Linsley cb9860e9e0 Merge pull request #1540 from nnnick/fix/scale-tick-font-size
Draw scale ticks using correct font
2015-10-16 20:48:46 -06:00
etimberg 3699addf16 Use the correct font for the ticks. Ensure that scale labels fill in the correct colour. 2015-10-16 22:00:43 -04:00
Evert Timberg 04a0204119 Merge pull request #1538 from lpaluszk/v2.0-dev
Fix HTMLIframeElement remove/removeNode issue in removeResizeListener…
2015-10-16 21:25:34 -04:00
Lucas Styles 4a48e19cac Fix HTMLIframeElement remove/removeNode issue in removeResizeListener method 2015-10-17 00:35:47 +01:00
Tanner Linsley 6c4c4695d9 Merge pull request #1526 from etimberg/fix/responsive-config-setting
Use the correct merged responsive setting in the resize listener
2015-10-13 11:46:14 -06:00
Evert Timberg e39298db3c Before labels can rotate, we need the appropriate left, right, top, & bottom attributes of the scale set with default values so that tick spacing can be determined. After ensuring that this happens, tests needed to be updated. Added unit testing for the scale service. 2015-10-13 11:43:00 -04:00
Evert Timberg 6001a1e4e7 Fix JSHint task 2015-10-13 10:33:59 -04:00
Tanner Linsley b835d5f209 Tooltip Hooks 2015-10-12 14:51:00 -06:00
Tanner Linsley 3da66ba42e Merge pull request #1525 from etimberg/fix/scale-merge
Merge scale settings at the correct time
2015-10-12 11:51:21 -06:00
Evert Timberg 93ee8f85f6 Put comment back in correct spot 2015-10-12 09:19:14 -04:00
Evert Timberg 1232ca53f0 Fix a race condition in the resize listener & use the correct merged config object for the responsive setting 2015-10-12 09:16:49 -04:00
Evert Timberg a756e0de15 Only merge scale defaults with the global scale defaults when getting the scale defaults. Otherwise, the user does not have the ability to change them via the global settings since registration occurs when the library is loaded. 2015-10-12 08:58:03 -04:00
Tanner Linsley 81095e777a Merge pull request #1517 from nnnick/feature/hide-datasets
Now allows hiding individual datasets
2015-10-07 21:51:15 -06:00
Evert Timberg 0d2fa807da Update samples with some hidden datasets 2015-10-07 19:54:53 -04:00
Evert Timberg b36c8ff788 Update controllers to handle datasets that are not visible 2015-10-07 19:54:11 -04:00
Evert Timberg aaec5efd52 Scales will only consider visible datasets when calculating data max and min values 2015-10-07 19:37:53 -04:00
Evert Timberg 22e7934804 Helper to determine if a dataset is visible or not 2015-10-07 19:10:10 -04:00
Tanner Linsley ef5cec7f5e Tooltips now using new lineArray format 2015-10-06 20:40:25 -06:00
Tanner Linsley 65f9ee8a4a Bubble Chart Type and Bubble Controller 2015-10-05 12:40:28 -06:00
Tanner Linsley 0ac59b8a42 Update README.md 2015-09-30 15:32:16 -06:00
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
Tanner Linsley 4b34bbadf9 Merge pull request #1098 from WouterSioen/fix-typo
Fix typo
2015-05-05 16:01:30 -06: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
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 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
127 arquivos alterados com 48657 adições e 9247 exclusões
+19
Ver Arquivo
@@ -0,0 +1,19 @@
---
engines:
duplication:
enabled: true
config:
languages:
- javascript
eslint:
enabled: true
fixme:
enabled: true
ratings:
paths:
- "**.js"
exclude_paths:
- dist/
- node_modules/
- test/
- coverage/
+1
Ver Arquivo
@@ -0,0 +1 @@
**/*{.,-}min.js
+213
Ver Arquivo
@@ -0,0 +1,213 @@
ecmaFeatures:
modules: true
jsx: true
env:
amd: true
browser: true
es6: true
jquery: true
node: true
# http://eslint.org/docs/rules/
rules:
# Possible Errors
comma-dangle: [2, never]
no-cond-assign: 2
no-console: 0
no-constant-condition: 2
no-control-regex: 2
no-debugger: 2
no-dupe-args: 2
no-dupe-keys: 2
no-duplicate-case: 2
no-empty: 2
no-empty-character-class: 2
no-ex-assign: 2
no-extra-boolean-cast: 2
no-extra-parens: 0
no-extra-semi: 2
no-func-assign: 2
no-inner-declarations: [2, functions]
no-invalid-regexp: 2
no-irregular-whitespace: 2
no-negated-in-lhs: 2
no-obj-calls: 2
no-regex-spaces: 2
no-sparse-arrays: 2
no-unexpected-multiline: 2
no-unreachable: 2
use-isnan: 2
valid-jsdoc: 0
valid-typeof: 2
# Best Practices
accessor-pairs: 2
block-scoped-var: 0
complexity: [2, 6]
consistent-return: 0
curly: 0
default-case: 0
dot-location: 0
dot-notation: 0
eqeqeq: 2
guard-for-in: 2
no-alert: 2
no-caller: 2
no-case-declarations: 2
no-div-regex: 2
no-else-return: 0
no-empty-label: 2
no-empty-pattern: 2
no-eq-null: 2
no-eval: 2
no-extend-native: 2
no-extra-bind: 2
no-fallthrough: 2
no-floating-decimal: 0
no-implicit-coercion: 0
no-implied-eval: 2
no-invalid-this: 0
no-iterator: 2
no-labels: 0
no-lone-blocks: 2
no-loop-func: 2
no-magic-number: 0
no-multi-spaces: 0
no-multi-str: 0
no-native-reassign: 2
no-new-func: 2
no-new-wrappers: 2
no-new: 2
no-octal-escape: 2
no-octal: 2
no-proto: 2
no-redeclare: 2
no-return-assign: 2
no-script-url: 2
no-self-compare: 2
no-sequences: 0
no-throw-literal: 0
no-unused-expressions: 2
no-useless-call: 2
no-useless-concat: 2
no-void: 2
no-warning-comments: 0
no-with: 2
radix: 2
vars-on-top: 0
wrap-iife: 2
yoda: 0
# Strict
strict: 0
# Variables
init-declarations: 0
no-catch-shadow: 2
no-delete-var: 2
no-label-var: 2
no-shadow-restricted-names: 2
no-shadow: 0
no-undef-init: 2
no-undef: 0
no-undefined: 0
no-unused-vars: 0
no-use-before-define: 0
# Node.js and CommonJS
callback-return: 2
global-require: 2
handle-callback-err: 2
no-mixed-requires: 0
no-new-require: 0
no-path-concat: 2
no-process-exit: 2
no-restricted-modules: 0
no-sync: 0
# Stylistic Issues
array-bracket-spacing: 0
block-spacing: 0
brace-style: 0
camelcase: 0
comma-spacing: 0
comma-style: 0
computed-property-spacing: 0
consistent-this: 0
eol-last: 0
func-names: 0
func-style: 0
id-length: 0
id-match: 0
indent: 0
jsx-quotes: 0
key-spacing: 0
linebreak-style: 0
lines-around-comment: 0
max-depth: 0
max-len: 0
max-nested-callbacks: 0
max-params: 0
max-statements: [2, 30]
new-cap: 0
new-parens: 0
newline-after-var: 0
no-array-constructor: 0
no-bitwise: 0
no-continue: 0
no-inline-comments: 0
no-lonely-if: 0
no-mixed-spaces-and-tabs: 0
no-multiple-empty-lines: 0
no-negated-condition: 0
no-nested-ternary: 0
no-new-object: 0
no-plusplus: 0
no-restricted-syntax: 0
no-spaced-func: 0
no-ternary: 0
no-trailing-spaces: 0
no-underscore-dangle: 0
no-unneeded-ternary: 0
object-curly-spacing: 0
one-var: 0
operator-assignment: 0
operator-linebreak: 0
padded-blocks: 0
quote-props: 0
quotes: 0
require-jsdoc: 0
semi-spacing: 0
semi: 0
sort-vars: 0
space-after-keywords: 0
space-before-blocks: 0
space-before-function-paren: 0
space-before-keywords: 0
space-in-parens: 0
space-infix-ops: 0
space-return-throw-case: 0
space-unary-ops: 0
spaced-comment: 0
wrap-regex: 0
# ECMAScript 6
arrow-body-style: 0
arrow-parens: 0
arrow-spacing: 0
constructor-super: 0
generator-star-spacing: 0
no-arrow-condition: 0
no-class-assign: 0
no-const-assign: 0
no-dupe-class-members: 0
no-this-before-super: 0
no-var: 0
object-shorthand: 0
prefer-arrow-callback: 0
prefer-const: 0
prefer-reflect: 0
prefer-spread: 0
prefer-template: 0
require-yield: 0
+6
Ver Arquivo
@@ -5,3 +5,9 @@ node_modules/*
custom/*
docs/index.md
bower_components/
coverage/*
nbproject/*
+18 -2
Ver Arquivo
@@ -1,13 +1,29 @@
language: node_js
node_js:
- "0.11"
- "0.10"
- "5.6"
- "4.3"
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- "sudo apt-get update"
- "sudo apt-get install -y libappindicator1 fonts-liberation"
- "wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
- "sudo dpkg -i google-chrome*.deb"
- "export CHROME_BIN=/usr/bin/google-chrome"
before_script:
- npm install
script:
- gulp test
- gulp coverage
- cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
notifications:
slack: chartjs:pcfCZR6ugg5TEcaLtmIfQYuA
sudo: required
addons:
firefox: latest
+6
Ver Arquivo
@@ -30,6 +30,12 @@ Guidlines for reporting bugs:
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.
Local development
-----------------
Run `npm install` to install all the libraries, then run `gulp dev --test` to build and run tests as you make changes.
Pull requests
-------------
externo
-3477
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-11
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+26 -1
Ver Arquivo
@@ -1,10 +1,35 @@
# Chart.js
[![Build Status](https://travis-ci.org/nnnick/Chart.js.svg?branch=master)](https://travis-ci.org/nnnick/Chart.js) [![Code Climate](https://codeclimate.com/github/nnnick/Chart.js/badges/gpa.svg)](https://codeclimate.com/github/nnnick/Chart.js)
[![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)[![Coverage Status](https://coveralls.io/repos/nnnick/Chart.js/badge.svg?branch=v2.0-dev)](https://coveralls.io/r/nnnick/Chart.js?branch=v2.0-dev)
*Simple HTML5 Charts using the canvas element* [chartjs.org](http://www.chartjs.org)
## v2.0 Beta
Current Release: [2.0.0-beta2](https://github.com/nnnick/Chart.js/releases/tag/2.0.0-beta2)
The next generation and release of Chart.js has been well under way this year and we are very close to releasing some amazing new features including, but not limited to:
- Rewritten, optimized, and unit-tested
- New and improved scales (log, time, linear, category, multiple scales)
- Improved responsiveness and resizing
- Powerful support for adding, removing, changing, and updating data on the fly
- Animations on all elements, colors and tooltips
- Powerful customization when you need it. Automatic and dynamic when you don't.
- Excellent support for modern frameworks and modular build systems.
- Even more extensible via new element controllers, combo chart support, and hook system
- Bug fixes not addressed in 1.x, and much, much more...
#####Contributing to 2.0
Submit PR's to the v2.0-dev branch.
#####Building and Testing
`gulp build`, `gulp test`
## v1.x Status: Feature Complete
We are now treating v1.x as feature complete. PR's for bug fixes are welcome, but we urge any open PR's for v1.x features to be refactored and resubmitted for v2.x (if the feature has not already been implemented).
## 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.
+6 -4
Ver Arquivo
@@ -1,11 +1,13 @@
{
"name": "Chart.js",
"version": "1.0.2",
"version": "2.0.0",
"description": "Simple HTML5 Charts using the canvas element",
"homepage": "https://github.com/nnnick/Chart.js",
"author": "nnnick",
"main": [
"Chart.js"
"dist/Chart.js"
],
"dependencies": {}
}
"devDependencies": {
"jquery": "~2.1.4"
}
}
+26
Ver Arquivo
@@ -0,0 +1,26 @@
{
"name": "nnnick/chartjs",
"type": "library",
"description": "Simple HTML5 charts using the canvas element.",
"keywords": [
"chart",
"js"
],
"homepage": "http://www.chartjs.org/",
"license": "MIT",
"authors": [
{
"name": "NICK DOWNIE",
"email": "hello@nickdownie.com"
}
],
"require": {
"php": ">=5.3.3"
},
"minimum-stability": "stable",
"extra": {
"branch-alias": {
"release/2.0": "v2.0-dev"
}
}
}
+4
Ver Arquivo
@@ -0,0 +1,4 @@
{
"node": true,
"predef": [ "require", "module" ]
}
+12749
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+15
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+9144
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+14
Ver Arquivo
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
+197 -164
Ver Arquivo
@@ -3,208 +3,241 @@ title: Getting started
anchor: getting-started
---
###Include Chart.js
### Download Chart.js
First we need to include the Chart.js library on the page. The library occupies a global variable of `Chart`.
To download a zip, go to [Chart.js on Github](https://github.com/nnnick/Chart.js) and choose the version that is right for your application.
* [Standard build](https://raw.githubusercontent.com/nnnick/Chart.js/v2.0-dev/dist/Chart.js) (~31kB gzipped)
* [Bundled with Moment.js](https://raw.githubusercontent.com/nnnick/Chart.js/v2.0-dev/dist/Chart.bundle.js) (~45kB gzipped)
* [CDN Versions](https://cdnjs.com/libraries/Chart.js)
```html
<script src="Chart.js"></script>
To install via npm / bower:
```bash
npm install chart.js --save
```
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:
```bash
bower install Chart.js --save
```
Also, Chart.js is available from CDN:
### Installation
https://cdnjs.com/libraries/chart.js
To import Chart.js using an old-school script tag:
###Creating a chart
```html
<script src="Chart.js"></script>
<script>
var myChart = new Chart({...})
</script>
```
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.
To import Chart.js using an awesome module loader:
```javascript
// Using CommonJS
var Chart = require('src/chart.js')
var myChart = new Chart({...})
// ES6
import Chart from 'src/chart.js'
let myChart = new Chart({...})
// Using requirejs
require(['path/to/Chartjs'], function(Chart){
var myChart = new Chart({...})
})
```
### 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
// Get the context of the canvas element we want to select
// Any of the following formats may be used
var ctx = document.getElementById("myChart");
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).PolarArea(data);
var ctx = $("#myChart");
```
We can also get the context of our canvas with jQuery. To do this, we need to get the DOM node out of the jQuery collection, and call the `getContext("2d")` method on that.
Once you have the element or context, you're ready to instantiate a pre-defined chart-type or create your own!
```javascript
// Get context with jQuery - using jQuery's .get() method.
var ctx = $("#myChart").get(0).getContext("2d");
// This will get the first returned node in the jQuery collection.
var myNewChart = new Chart(ctx);
The following example instantiates a bar chart showing the number of votes for different colors and the y-axis starting at 0.
```html
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
```
After we've instantiated the Chart class on the canvas we want to draw on, Chart.js will handle the scaling for retina displays.
It's that easy to get started using Chart.js! From here you can explore the many options that can help you customise your charts with scales, tooltips, labels, colors, custom actions, and much more.
With the Chart class set up, we can go on to create one of the charts Chart.js has available. In the example below, we would be drawing a Polar area chart.
```javascript
new Chart(ctx).PolarArea(data, options);
```
We call a method of the name of the chart we want to create. We pass in the data for that chart type, and the options for that chart as parameters. Chart.js will merge the global defaults with chart type specific defaults, then merge any options passed in as a second argument after data.
###Global chart configuration
### 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.
```javascript
Chart.defaults.global = {
// Boolean - Whether to animate the chart
animation: true,
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.
// Number - Number of animation steps
animationSteps: 60,
The global options are defined in `Chart.defaults.global`.
// String - Animation easing effect
// Possible effects are:
// [easeInOutQuart, linear, easeOutBounce, easeInBack, easeInOutQuad,
// easeOutQuart, easeOutQuad, easeInOutBounce, easeOutSine, easeInOutCubic,
// easeInExpo, easeInOutBack, easeInCirc, easeInOutElastic, easeOutBack,
// easeInQuad, easeInOutExpo, easeInQuart, easeOutQuint, easeInOutCirc,
// easeInSine, easeOutExpo, easeOutCirc, easeOutCubic, easeInQuint,
// easeInElastic, easeInOutSine, easeInOutQuint, easeInBounce,
// easeOutElastic, easeInCubic]
animationEasing: "easeOutQuart",
Name | Type | Default | Description
--- | --- | --- | ---
responsive | Boolean | true | Resizes when the canvas container does.
responsiveAnimationDuration | Number | 0 | Duration in milliseconds it takes to animate to new size after a resize event.
maintainAspectRatio | Boolean | true | Maintain the original canvas aspect ratio `(width / height)` when resizing
events | Array[String] | `["mousemove", "mouseout", "click", "touchstart", "touchmove", "touchend"]` | Events that the chart should listen to for tooltips and hovering
hover |-|-|-
*hover*.onHover | Function | null | Called when any of the events fire. Called in the context of the chart and passed an array of active elements (bars, points, etc)
*hover*.mode | String | 'single' | Sets which elements hover. Acceptable options are `'single'`, `'label'`, or `'dataset'`. `single` highlights the closest element. `label` highlights elements in all datasets at the same `X` value. `dataset` highlights the closest dataset.
*hover*.animationDuration | Number | 400 | Duration in milliseconds it takes to animate hover style changes
onClick | Function | null | Called if the event is of type 'mouseup' or 'click'. Called in the context of the chart and passed an array of active elements
defaultColor | Color | 'rgba(0,0,0,0.1)' |
defaultFontColor | Color | '#666' | Default font color for all text
defaultFontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | Default font family for all text
defaultFontSize | Number | 12 | Default font size (in px) for text. Does not apply to radialLinear scale point labels
defaultFontStyle | String | 'normal' | Default font style. Does not apply to tooltip title or footer. Does not apply to chart title
legendCallback | Function | ` function (chart) { }` | Function to generate a legend. Receives the chart object to generate a legend from. Default implementation returns an HTML string.
// Boolean - If we should show the scale at all
showScale: true,
The global options for the chart title is defined in `Chart.defaults.global.title`
// Boolean - If we want to override with a hard coded scale
scaleOverride: false,
Name | Type | Default | Description
--- | --- | --- | ---
display | Boolean | true | Show the title block
position | String | 'top' | Position of the title. 'top' or 'bottom' are allowed
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
fontColor | Color | '#666' | Text color
fontFamily | String | 'Helvetica Neue' |
fontSize | Number | 12 |
fontStyle | String | 'bold' |
padding | Number | 10 | Number of pixels to add above and below the title text
text | String | '' | Title text
// ** 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,
The global options for the chart legend is defined in `Chart.defaults.global.legend`
// String - Colour of the scale line
scaleLineColor: "rgba(0,0,0,.1)",
Name | Type | Default | Description
--- | --- | --- | ---
display | Boolean | true | Is the legend displayed
position | String | 'top' | Position of the legend. Options are 'top' or 'bottom'
fullWidth | Boolean | true | Marks that this box should take the full width of the canvas (pushing down other boxes)
onClick | Function | `function(event, legendItem) {}` | A callback that is called when a click is registered on top of a label item
labels |-|-|-
*labels*boxWidth | Number | 40 | Width of coloured box
*labels*fontSize | Number | 12 | Font size
*labels*fontStyle | String | "normal" |
*labels*fontColor | Color | "#666" |
*labels*fontFamily | String | "Helvetica Neue" |
*labels*padding | Number | 10 | Padding between rows of colored boxes
*labels*generateLabels: | Function | `function(data) { }` | Generates legend items for each thing in the legend. Default implementation returns the text + styling for the color box. Styles that can be returned are `fillStyle`, `strokeStyle`, `lineCap`, `lineDash`, `lineDashOffset`, `lineWidth`, `lineJoin`. Return a `hidden` attribute to indicate that the label refers to something that is not visible. A strikethrough style will be given to the text in this case.
// Number - Pixel width of the scale line
scaleLineWidth: 1,
The global options for tooltips are defined in `Chart.defaults.global.tooltips`.
// Boolean - Whether to show labels on the scale
scaleShowLabels: true,
Name | Type | Default | Description
--- |:---:| --- | ---
enabled | Boolean | true |
custom | | null |
mode | String | 'single' | Sets which elements appear in the tooltip. Acceptable options are `'single'` or `'label'`. `single` highlights the closest element. `label` highlights elements in all datasets at the same `X` value.
backgroundColor | Color | 'rgba(0,0,0,0.8)' | Background color of the tooltip
| | |
Label | | | There are three labels you can control. `title`, `body`, `footer` the star (\*) represents one of these three. *(i.e. titleFontFamily, footerSpacing)*
\*FontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" |
\*FontSize | Number | 12 |
\*FontStyle | String | title - "bold", body - "normal", footer - "bold" |
\*Spacing | Number | 2 |
\*Color | Color | "#fff" |
\*Align | String | "left" | text alignment. See [MDN Canvas Documentation](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign)
titleMarginBottom | Number | 6 | Margin to add on bottom of title section
footerMarginTop | Number | 6 | Margin to add before drawing the footer
xPadding | Number | 6 | Padding to add on left and right of tooltip
yPadding | Number | 6 | Padding to add on top and bottom of tooltip
caretSize | Number | 5 | Size, in px, of the tooltip arrow
cornerRadius | Number | 6 | Radius of tooltip corner curves
multiKeyBackground | Color | "#fff" | Color to draw behind the colored boxes when multiple items are in the tooltip
| | |
callbacks | - | - | V2.0 introduces callback functions as a replacement for the template engine in v1. The tooltip has the following callbacks for providing text. For all functions, 'this' will be the tooltip object create from the Chart.Tooltip constructor
**Callback Functions** | | | All functions are called with the same arguments
xLabel | String or Array[Strings] | | This is the xDataValue for each item to be displayed in the tooltip
yLabel | String or Array[Strings] | | This is the yDataValue for each item to be displayed in the tooltip
index | Number | | Data index.
data | Object | | Data object passed to chart.
`return`| String or Array[Strings] | | All functions must return either a string or an array of strings. Arrays of strings are treated as multiple lines of text.
| | |
*callbacks*.beforeTitle | Function | none | Text to render before the title
*callbacks*.title | Function | `function(tooltipItems, data) { //Pick first xLabel }` | Text to render as the title
*callbacks*.afterTitle | Function | none | Text to render after the ttiel
*callbacks*.beforeBody | Function | none | Text to render before the body section
*callbacks*.beforeLabel | Function | none | Text to render before an individual label
*callbacks*.label | Function | `function(tooltipItem, data) { // Returns "datasetLabel: tooltipItem.yLabel" }` | Text to render as label
*callbacks*.afterLabel | Function | none | Text to render after an individual label
*callbacks*.afterBody | Function | none | Text to render after the body section
*callbacks*.beforeFooter | Function | none | Text to render before the footer section
*callbacks*.footer | Function | none | Text to render as the footer
*callbacks*.afterFooter | Function | none | Text to render after the footer section
// Interpolated JS string - can access value
scaleLabel: "<%=value%>",
The global options for animations are defined in `Chart.defaults.global.animation`.
// Boolean - Whether the scale should stick to integers, not floats even if drawing space is there
scaleIntegersOnly: true,
Name | Type | Default | Description
--- |:---:| --- | ---
duration | Number | 1000 | The number of milliseconds an animation takes.
easing | String | "easeOutQuart" | Easing function to use.
onProgress | Function | none | Callback called on each step of an animation. Passed a single argument, an object, containing the chart instance and an object with details of the animation.
onComplete | Function | none | Callback called at the end of an animation. Passed the same arguments as `onProgress`
// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero: false,
The global options for elements are defined in `Chart.defaults.global.elements`.
// String - Scale label font declaration for the scale label
scaleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Scale label font size in pixels
scaleFontSize: 12,
// String - Scale label font weight style
scaleFontStyle: "normal",
// String - Scale label font colour
scaleFontColor: "#666",
// Boolean - whether or not the chart should be responsive and resize when the browser does.
responsive: false,
// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container
maintainAspectRatio: true,
// Boolean - Determines whether to draw tooltips on the canvas or not
showTooltips: true,
// Function - Determines whether to execute the customTooltips function instead of drawing the built in tooltips (See [Advanced - External Tooltips](#advanced-usage-custom-tooltips))
customTooltips: false,
// Array - Array of string names to attach tooltip events
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
// String - Tooltip background colour
tooltipFillColor: "rgba(0,0,0,0.8)",
// String - Tooltip label font declaration for the scale label
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Tooltip label font size in pixels
tooltipFontSize: 14,
// String - Tooltip font weight style
tooltipFontStyle: "normal",
// String - Tooltip label font colour
tooltipFontColor: "#fff",
// String - Tooltip title font declaration for the scale label
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
// Number - Tooltip title font size in pixels
tooltipTitleFontSize: 14,
// String - Tooltip title font weight style
tooltipTitleFontStyle: "bold",
// String - Tooltip title font colour
tooltipTitleFontColor: "#fff",
// Number - pixel width of padding around tooltip text
tooltipYPadding: 6,
// Number - pixel width of padding around tooltip text
tooltipXPadding: 6,
// Number - Size of the caret on the tooltip
tooltipCaretSize: 8,
// Number - Pixel radius of the tooltip border
tooltipCornerRadius: 6,
// Number - Pixel offset from point x to tooltip edge
tooltipXOffset: 10,
{% raw %}
// String - Template string for single tooltips
tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>",
{% endraw %}
// String - Template string for multiple tooltips
multiTooltipTemplate: "<%= value %>",
// Function - Will fire on animation progression.
onAnimationProgress: function(){},
// Function - Will fire on animation completion.
onAnimationComplete: function(){}
}
```
Name | Type | Default | Description
--- |:---:| --- | ---
arc | - | - | -
*arc*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default fill color for arcs
*arc*.borderColor | Color | "#fff" | Default stroke color for arcs
*arc*.borderWidth | Number | 2 | Default stroke width for arcs
line | - | - | -
*line*.tension | Number | 0.4 | Default bezier curve tension. Set to `0` for no bezier curves.
*line*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default line fill color
*line*.borderWidth | Number | 3 | Default line stroke width
*line*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default line stroke color
*line*.borderCapStyle | String | 'butt' | Default line cap style. See [MDN](https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/lineCap)
*line*.borderDash | Array | `[]` | Default line dash. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)
*line*.borderDashOffset | Number | 0.0 | Default line dash offset. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
*line*.borderJoinStyle | String | 'miter' | Default line join style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
*line*.fill | Boolean | true |
point | - | - | -
*point*.radius | Number | 3 | Default point radius
*point*.pointStyle | String | 'circle' | Default point style
*point*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default point fill color
*point*.borderWidth | Number | 1 | Default point stroke width
*point*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default point stroke color
*point*.hitRadius | Number | 1 | Extra radius added to point radius for hit detection
*point*.hoverRadius | Number | 4 | Default point radius when hovered
*point*.hoverBorderWidth | Number | 1 | Default stroke width when hovered
rectangle | - | - | -
*rectangle*.backgroundColor | Color | `Chart.defaults.global.defaultColor` | Default bar fill color
*rectangle*.borderWidth | Number | 0 | Default bar stroke width
*rectangle*.borderColor | Color | `Chart.defaults.global.defaultColor` | Default bar stroke color
*rectangle*.borderSkipped | String | 'bottom' | Default skipped (excluded) border for rectangle. Can be one of `bottom`, `left`, `top`, `right`
If for example, you wanted all charts created to be responsive, and resize when the browser window does, the following setting can be changed:
-169
Ver Arquivo
@@ -1,169 +0,0 @@
---
title: Line Chart
anchor: line-chart
---
###Introduction
A line chart is a way of plotting data points on a line.
Often, it is used to show trend data, and the comparison of two data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
###Example usage
```javascript
var myLineChart = new Chart(ctx).Line(data, options);
```
###Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The line chart requires an array of labels 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 - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - Whether the line is curved between points
bezierCurve : true,
//Number - Tension of the bezier curve between points
bezierCurveTension : 0.4,
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 4,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
{% endraw %}
//Boolean - Whether to horizontally center the label and point dot inside the grid
offsetGridLines : false
};
```
You can override these for your `Chart` instance by passing a second argument into the `Line` method as an object with the keys you want to override.
For example, we could have a line chart without bezier curves between points by doing the following:
```javascript
new Chart(ctx).Line(data, {
bezierCurve: false
});
// This will create a chart with all of the default options, merged from the global config,
// and the Line chart defaults, but this particular instance will have `bezierCurve` set to false.
```
We can also change these defaults values for each Line type that is created, this object is available at `Chart.defaults.Line`.
### Prototype methods
#### .getPointsAtEvent( event )
Calling `getPointsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
```javascript
canvas.onclick = function(evt){
var activePoints = myLineChart.getPointsAtEvent(evt);
// => activePoints is an array of points on the canvas that are at the same position as the click event.
};
```
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
#### .update( )
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
```javascript
myLineChart.datasets[0].points[2].value = 50;
// Would update the first dataset's value of 'March' to be 50
myLineChart.update();
// Calling update now animates the position of March from 90 to 50.
```
#### .addData( valuesArray, label )
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those points.
```javascript
// The values array passed into addData should be one for each dataset in the chart
myLineChart.addData([40, 60], "August");
// This new data will now animate at the end of the chart.
```
#### .removeData( )
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
```javascript
myLineChart.removeData();
// The chart will remove the first point and animate other points into place
```
+299
Ver Arquivo
@@ -0,0 +1,299 @@
---
title: Scales
anchor: scales
---
Scales in v2.0 of Chart.js are significantly more powerful, but also different than those of v1.0.
* Multiple x & y axes are now supported.
* A built-in label auto-skip feature now detects would-be overlapping ticks and labels and removes every nth label to keep things displaying normally.
* Scale titles are now supported
* New scale types can be extended without writing an entirely new chart type
Every scale extends a core scale class with the following options:
Name | Type | Default | Description
--- |:---:| --- | ---
type | String | Chart specific. | Type of scale being employed. Custom scales can be created and registered with a string key. Options: ["category"](#scales-category-scale), ["linear"](#scales-linear-scale), ["logarithmic"](#scales-logarithmic-scale), ["time"](#scales-time-scale), ["radialLinear"](#scales-radial-linear-scale)
display | Boolean | true | If true, show the scale including gridlines, ticks, and labels. Overrides *gridLines.display*, *scaleLabel.display*, and *ticks.display*.
beforeUpdate | Function | undefined | Callback called before the update process starts. Passed a single argument, the scale instance.
beforeSetDimensions | Function | undefined | Callback that runs before dimensions are set. Passed a single argument, the scale instance.
afterSetDimensions | Function | undefined | Callback that runs after dimensions are set. Passed a single argument, the scale instance.
beforeDataLimits | Function | undefined | Callback that runs before data limits are determined. Passed a single argument, the scale instance.
afterDataLimits | Function | undefined | Callback that runs after data limits are determined. Passed a single argument, the scale instance.
beforeBuildTicks | Function | undefined | Callback that runs before ticks are created. Passed a single argument, the scale instance.
afterBuildTicks | Function | undefined | Callback that runs after ticks are created. Useful for filtering ticks. Passed a single argument, the scale instance.
beforeTickToLabelConversion | Function | undefined | Callback that runs before ticks are converted into strings. Passed a single argument, the scale instance.
afterTickToLabelConversion | Function | undefined | Callback that runs after ticks are converted into strings. Passed a single argument, the scale instance.
beforeCalculateTickRotation | Function | undefined | Callback that runs before tick rotation is determined. Passed a single argument, the scale instance.
afterCalculateTickRotation | Function | undefined | Callback that runs after tick rotation is determined. Passed a single argument, the scale instance.
beforeFit | Function | undefined | Callback that runs before the scale fits to the canvas. Passed a single argument, the scale instance.
afterFit | Function | undefined | Callback that runs after the scale fits to the canvas. Passed a single argument, the scale instance.
afterUpdate | Function | undefined | Callback that runs at the end of the update process. Passed a single argument, the scale instance.
**gridLines** | Array | - | Options for the grid lines that run perpendicular to the axis.
*gridLines*.display | Boolean | true |
*gridLines*.color | Color | "rgba(0, 0, 0, 0.1)" | Color of the grid lines.
*gridLines*.lineWidth | Number | 1 | Stroke width of grid lines
*gridLines*.drawOnChartArea | Boolean | true | If true, draw lines on the chart area inside the axis lines. This is useful when there are multiple axes and you need to control which grid lines are drawn
*gridLines*.drawTicks | Boolean | true | If true, draw lines beside the ticks in the axis area beside the chart.
*gridLines*.zeroLineWidth | Number | 1 | Stroke width of the grid line for the first index (index 0).
*gridLines*.zeroLineColor | Color | "rgba(0, 0, 0, 0.25)" | Stroke color of the grid line for the first index (index 0).
*gridLines*.offsetGridLines | Boolean | false | If true, offset labels from grid lines.
**scaleLabel** | Array | | Title for the entire axis.
*scaleLabel*.display | Boolean | false |
*scaleLabel*.labelString | String | "" | The text for the title. (i.e. "# of People", "Response Choices")
*scaleLabel*.fontColor | Color | "#666" | Font color for the scale title.
*scaleLabel*.fontFamily| String | "Helvetica Neue" | Font family for the scale title, follows CSS font-family options.
*scaleLabel*.fontSize | Number | 12 | Font size for the scale title.
*scaleLabel*.fontStyle | String | "normal" | Font style for the scale title, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
**ticks** | Array | | Settings for the labels that run along the axis.
*ticks*.beginAtZero | Boolean | false | If true the scale will be begin at 0, if false the ticks will begin at your smallest data value.
*ticks*.fontColor | Color | "#666" | Font color for the tick labels.
*ticks*.fontFamily | String | "Helvetica Neue" | Font family for the tick labels, follows CSS font-family options.
*ticks*.fontSize | Number | 12 | Font size for the tick labels.
*ticks*.fontStyle | String | "normal" | Font style for the tick labels, follows CSS font-style options (i.e. normal, italic, oblique, initial, inherit).
*ticks*.maxRotation | Number | 90 | Maximum rotation for tick labels when rotating to condense labels. Note: Rotation doesn't occur until necessary. *Note: Only applicable to horizontal scales.*
*ticks*.minRotation | Number | 20 | *currently not-implemented* Minimum rotation for tick labels when condensing is necessary. *Note: Only applicable to horizontal scales.*
*ticks*.maxTicksLimit | Number | 11 | Maximum number of ticks and gridlines to show. If not defined, it will limit to 11 ticks but will show all gridlines.
*ticks*.padding | Number | 10 | Padding between the tick label and the axis. *Note: Only applicable to horizontal scales.*
*ticks*.mirror | Boolean | false | Flips tick labels around axis, displaying the labels inside the chart instead of outside. *Note: Only applicable to vertical scales.*
*ticks*.reverse | Boolean | false | Reverses order of tick labels.
*ticks*.display | Boolean | true | If true, show the ticks.
*ticks*.suggestedMin | Number | - | User defined minimum number for the scale, overrides minimum value *except for if* it is higher than the minimum value.
*ticks*.suggestedMax | Number | - | User defined maximum number for the scale, overrides maximum value *except for if* it is lower than the maximum value.
*ticks*.min | Number | - | User defined minimum number for the scale, overrides minimum value.
*ticks*.max | Number | - | User defined minimum number for the scale, overrides maximum value
*ticks*.autoSkip | Boolean | true | If true, automatically calculates how many labels that can be shown and hides labels accordingly. Turn it off to show all labels no matter what
*ticks*.callback | Function | `function(value) { return '' + value; } ` | Returns the string representation of the tick value as it should be displayed on the chart.
The `callback` method may be used for advanced tick customization. The following callback would display every label in scientific notation
```javascript
{
scales: {
xAxes: [{
ticks: {
// Return an empty string to draw the tick line but hide the tick label
// Return `null` or `undefined` to hide the tick line entirely
userCallback: function(value, index, values) {
return value.toExponential();
}
}
}]
}
}
```
### Category Scale
The category scale will be familiar to those who have used v1.0. Labels are drawn in from the labels array included in the chart data.
The category scale extends the core scale class with the following tick template:
```javascript
{
position: "bottom",
}
```
The `ticks.min` and `ticks.max` attributes may be used with the category scale. Unlike other scales, the value of these attributes must simply be something that can be found in the `labels` array of the data object.
### Linear Scale
The linear scale can be used to display numerical data. It can be placed on either the x or y axis. The scatter chart type automatically configures a line chart to use one of these scales for the x axis.
The linear scale extends the core scale class with the following tick template:
```javascript
{
position: "left",
ticks: {
callback: function(tickValue, index, ticks) {
var delta = ticks[1] - ticks[0];
// If we have a number like 2.5 as the delta, figure out how many decimal places we need
if (Math.abs(delta) > 1) {
if (tickValue !== Math.floor(tickValue)) {
// not an integer
delta = tickValue - Math.floor(tickValue);
}
}
var logDelta = helpers.log10(Math.abs(delta));
var tickString = '';
if (tickValue !== 0) {
var numDecimal = -1 * Math.floor(logDelta);
numDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places
tickString = tickValue.toFixed(numDecimal);
} else {
tickString = '0'; // never show decimal places for 0
}
return tickString;
}
}
}
```
It also provides additional configuration options:
Name | Type | Default | Description
--- |:---:| --- | ---
*ticks*.stepSize | Number | - | User defined fixed step size for the scale. If set, the scale ticks will be enumerated by multiple of stepSize, having one tick per increment. If not set, the ticks are labeled automatically using the nice numbers algorithm.
### Logarithmic Scale
The logarithmic scale is used to display logarithmic data of course. It can be placed on either the x or y axis.
The log scale extends the core scale class with the following tick template:
```javascript
{
position: "left",
ticks: {
callback: function(value) {
var remain = value / (Math.pow(10, Math.floor(Chart.helpers.log10(value))));
if (remain === 1 || remain === 2 || remain === 5) {
return value.toExponential();
} else {
return '';
}
}
}
}
```
### Time Scale
The time scale is used to display times and dates. It can be placed on the x axis. When building its ticks, it will automatically calculate the most comfortable unit base on the size of the scale.
The time scale extends the core scale class with the following tick template:
```javascript
{
position: "bottom",
time: {
// string/callback - By default, date objects are expected. You may use a pattern string from http://momentjs.com/docs/#/parsing/string-format/ to parse a time string format, or use a callback function that is passed the label, and must return a moment() instance.
parser: false,
// string - By default, unit will automatically be detected. Override with 'week', 'month', 'year', etc. (see supported time measurements)
unit: false,
// Number - The number of steps of the above unit between ticks
unitStepSize: 1
// string - By default, no rounding is applied. To round, set to a supported time unit eg. 'week', 'month', 'year', etc.
round: false,
// Moment js for each of the units. Replaces `displayFormat`
// To override, use a pattern string from http://momentjs.com/docs/#/displaying/format/
displayFormats: {
'millisecond': 'SSS [ms]',
'second': 'h:mm:ss a', // 11:20:01 AM
'minute': 'h:mm:ss a', // 11:20:01 AM
'hour': 'MMM D, hA', // Sept 4, 5PM
'day': 'll', // Sep 4 2015
'week': 'll', // Week 46, or maybe "[W]WW - YYYY" ?
'month': 'MMM YYYY', // Sept 2015
'quarter': '[Q]Q - YYYY', // Q3
'year': 'YYYY', // 2015
},
// Sets the display format used in tooltip generation
tooltipFormat: ''
},
}
```
The following time measurements are supported:
```javascript
{
'millisecond': {
display: 'SSS [ms]', // 002 ms
maxStep: 1000,
},
'second': {
display: 'h:mm:ss a', // 11:20:01 AM
maxStep: 60,
},
'minute': {
display: 'h:mm:ss a', // 11:20:01 AM
maxStep: 60,
},
'hour': {
display: 'MMM D, hA', // Sept 4, 5PM
maxStep: 24,
},
'day': {
display: 'll', // Sep 4 2015
maxStep: 7,
},
'week': {
display: 'll', // Week 46, or maybe "[W]WW - YYYY" ?
maxStep: 4.3333,
},
'month': {
display: 'MMM YYYY', // Sept 2015
maxStep: 12,
},
'quarter': {
display: '[Q]Q - YYYY', // Q3
maxStep: 4,
},
'year': {
display: 'YYYY', // 2015
maxStep: false,
},
}
```
### Radial Linear Scale
The radial linear scale is used specifically for the radar chart type.
The radial linear scale extends the core scale class with the following tick template:
```javascript
{
animate: true,
lineArc: false,
position: "chartArea",
angleLines: {
display: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1
},
// label settings
ticks: {
//Boolean - Show a backdrop to the scale label
showLabelBackdrop: true,
//String - The colour of the label backdrop
backdropColor: "rgba(255,255,255,0.75)",
//Number - The backdrop padding above & below the label in pixels
backdropPaddingY: 2,
//Number - The backdrop padding to the side of the label in pixels
backdropPaddingX: 2,
//Number - Limit the maximum number of ticks and gridlines
maxTicksLimit: 11,
},
pointLabels: {
//String - Point label font declaration
fontFamily: "'Arial'",
//String - Point label font weight
fontStyle: "normal",
//Number - Point label font size in pixels
fontSize: 10,
//String - Point label font colour
fontColor: "#666",
//Function - Used to determine point labels to show in scale
callback: function(pointLabel) {
return pointLabel;
}
},
}
```
-149
Ver Arquivo
@@ -1,149 +0,0 @@
---
title: Bar Chart
anchor: bar-chart
---
### Introduction
A bar chart is a way of showing data as bars.
It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myBarChart = new Chart(ctx).Bar(data, options);
```
### Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
```javascript
{
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero : true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 1,
{% raw %}
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></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 `Bar` method as an object with the keys you want to override.
For example, we could have a bar chart without a stroke on each bar by doing the following:
```javascript
new Chart(ctx).Bar(data, {
barShowStroke: false
});
// This will create a chart with all of the default options, merged from the global config,
// and the Bar chart defaults but this particular instance will have `barShowStroke` set to false.
```
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
### Prototype methods
#### .getBarsAtEvent( event )
Calling `getBarsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the bar elements that are at that the same position of that event.
```javascript
canvas.onclick = function(evt){
var activeBars = myBarChart.getBarsAtEvent(evt);
// => activeBars is an array of bars on the canvas that are at the same position as the click event.
};
```
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
#### .update( )
Calling `update()` on your Chart instance will re-render the chart with any updated values, allowing you to edit the value of multiple existing points, then render those in one animated render loop.
```javascript
myBarChart.datasets[0].bars[2].value = 50;
// Would update the first dataset's value of 'March' to be 50
myBarChart.update();
// Calling update now animates the position of March from 90 to 50.
```
#### .addData( valuesArray, label )
Calling `addData(valuesArray, label)` on your Chart instance passing an array of values for each dataset, along with a label for those bars.
```javascript
// The values array passed into addData should be one for each dataset in the chart
myBarChart.addData([40, 60], "August");
// The new data will now animate at the end of the chart.
```
#### .removeData( )
Calling `removeData()` on your Chart instance will remove the first value for all datasets on the chart.
```javascript
myBarChart.removeData();
// The chart will now animate and remove the first bar
```
+161
Ver Arquivo
@@ -0,0 +1,161 @@
---
title: Line Chart
anchor: line-chart
---
### Introduction
A line chart is a way of plotting data points on a line.
Often, it is used to show trend data, and the comparison of two data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myLineChart = new Chart(ctx, {
type: 'line',
data: data,
options: options
});
```
Alternatively a line chart can be created using syntax similar to the v1.0 syntax
```javascript
var myLineChart = Chart.Line(ctx, {
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
// Boolean - if true fill the area under the line
fill: false,
// String - the color to fill the area under the line with if fill is true
backgroundColor: "rgba(220,220,220,0.2)",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - Line color
borderColor: "rgba(220,220,220,1)",
// String - cap style of the line. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap
borderCapStyle: 'butt',
// Array - Length and spacing of dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash
borderDash: [],
// Number - Offset for line dashes. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
borderDashOffset: 0.0,
// String - line join style. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin
borderJoinStyle: 'miter',
// String or array - Point stroke color
pointBorderColor: "rgba(220,220,220,1)",
// String or array - Point fill color
pointBackgroundColor: "#fff",
// Number or array - Stroke width of point border
pointBorderWidth: 1,
// Number or array - Radius of point when hovered
pointHoverRadius: 5,
// String or array - point background color when hovered
pointHoverBackgroundColor: "rgba(220,220,220,1)",
// Point border color when hovered
pointHoverBorderColor: "rgba(220,220,220,1)",
// Number or array - border width of point when hovered
pointHoverBorderWidth: 2,
// Tension - bezier curve tension of the line. Set to 0 to draw straight Wlines connecting points
tension: 0.1,
// Number - the pixel size of the point shape. Can be set to 0 to not render a circle over the point
radius: 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. First id is y-axis-0
yAxisID: "y-axis-0",
},
{
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. This labels are shown on the X axis. There must be one label for each data point. More labels than datapoints are allowed, in which case the line ends at the last data point.
The data for line charts is broken up into an array of datasets. Each dataset has a colour for the fill, a colour for the line and colours for the points and strokes of the points. These colours are strings just like CSS. You can use RGBA, RGB, HEX or HSL notation.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart options
These are the customisation options specific to Line charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for line chart are defined in `Chart.defaults.Line`.
Name | Type | Default | Description
--- | --- | --- | ---
showLines | Boolean | true | If false, the lines between points are not drawn
stacked | Boolean | false | If true, lines stack on top of each other along the y axis.
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
elements | - | - | -
*elements*.point | - | - | -
*elements.point*.radius | Number | `3` | Defines the size of the Point shape. Can be set to zero to skip rendering a point.
scales | - | - | -
*scales*.xAxes | Array | `[{type:"category","id":"x-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
*Options for xAxes* | | |
type | String | "category" | As defined in ["Category"](#scales-category-scale).
id | String | "x-axis-1" | Id of the axis so that data can bind to it.
| | |
*scales*.yAxes | Array | `[{type:"linear","id":"y-axis-1"}]` | Defines all of the x axes used in the chart. See the [scale documentation](#getting-started-scales) for details on the available options.
*Options for yAxes* | | |
type | String | "linear" | As defined in ["Linear"](#scales-linear-scale).
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
You can override these for your `Chart` instance by passing a member `options` into the `Line` method.
For example, we could have a line chart display without an x axis by doing the following. The config merge is smart enough to handle arrays so that you do not need to specify all axis settings to change one thing.
```javascript
new Chart(ctx, {
type: 'line',
data: data,
options: {
xAxes: [{
display: false
}]
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Line chart defaults, but this particular instance will have the x axis not displaying.
```
We can also change these defaults values for each Line type that is created, this object is available at `Chart.defaults.line`.
+155
Ver Arquivo
@@ -0,0 +1,155 @@
---
title: Bar Chart
anchor: bar-chart
---
### Introduction
A bar chart is a way of showing data as bars.
It is sometimes used to show trend data, and the comparison of multiple data sets side by side.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myBarChart = new Chart(ctx, {
type: 'bar',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
// The properties below allow an array to be specified to change the value of the item at the given index
// String or array - the bar color
backgroundColor: "rgba(220,220,220,0.2)",
// String or array - bar stroke color
borderColor: "rgba(220,220,220,1)",
// Number or array - bar border width
borderWidth: 1,
// String or array - fill color when hovered
hoverBackgroundColor: "rgba(220,220,220,0.2)",
// String or array - border color when hovered
hoverBorderColor: "rgba(220,220,220,1)",
// The actual data
data: [65, 59, 80, 81, 56, 55, 40],
// String - If specified, binds the dataset to a certain y-axis. If not specified, the first y-axis is used.
yAxisID: "y-axis-0",
},
{
label: "My Second dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
borderWidth: 1,
hoverBackgroundColor: "rgba(220,220,220,0.2)",
hoverBorderColor: "rgba(220,220,220,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
```
The bar chart has the a very similar data structure to the line chart, and has an array of datasets, each with colours and an array of data. Again, colours are in CSS format.
We have an array of labels too for display. In the example, we are showing the same data as the previous line chart example.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Bar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for bar chart are defined in `Chart.defaults.Bar`.
Name | Type | Default | Description
--- |:---:| --- | ---
stacked | Boolean | false |
*hover*.mode | String | "label" | Label's hover mode. "label" is used since the x axis displays data by the index in the dataset.
scales | Array | - | -
*scales*.xAxes | Array | | The bar chart officially supports only 1 x-axis but uses an array to keep the API consistent. Use a scatter chart if you need multiple x axes.
*Options for xAxes* | | |
type | String | "Category" | As defined in [Scales](#scales-category-scale).
display | Boolean | true | If true, show the scale.
position | String | "bottom" | Position of the scale. Options are "top" and "bottom" for dataset scales.
id | String | "x-axis-1" | Id of the axis so that data can bind to it
categoryPercentage | Number | 0.8 | Percent (0-1) of the available width (the space between the gridlines for small datasets) for each data-point to use for the bars. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
barPercentage | Number | 0.9 | Percent (0-1) of the available width each bar should be within the category percentage. 1.0 will take the whole category width and put the bars right next to each other. [Read More](#bar-chart-barpercentage-vs-categorypercentage)
gridLines | Array | [See Scales](#scales) |
*gridLines*.offsetGridLines | Boolean | true | If true, the bars for a particular data point fall between the grid lines. If false, the grid line will go right down the middle of the bars.
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
| | |
*scales*.yAxes | Array | `[{ type: "linear" }]` |
*Options for xAxes* | | |
type | String | "linear" | As defined in [Scales](#scales-linear-scale).
display | Boolean | true | If true, show the scale.
position | String | "left" | Position of the scale. Options are "left" and "right" for dataset scales.
id | String | "y-axis-1" | Id of the axis so that data can bind to it.
gridLines | Array | [See Scales](#scales) |
scaleLabel | Array | [See Scales](#scales) |
ticks | Array | [See Scales](#scales) |
You can override these for your `Chart` instance by passing a second argument into the `Bar` method as an object with the keys you want to override.
For example, we could have a bar chart without a stroke on each bar by doing the following:
```javascript
new Chart(ctx, {
type: "bar",
data: data,
options: {
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true
}]
}
}
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Bar chart defaults but this particular instance will have `stacked` set to true
// for both x and y axes.
```
We can also change these defaults values for each Bar type that is created, this object is available at `Chart.defaults.Bar`.
#### barPercentage vs categoryPercentage
The following shows the relationship between the bar percentage option and the category percentage option.
```text
// categoryPercentage: 1.0
// barPercentage: 1.0
Bar: | 1.0 | 1.0 |
Category: | 1.0 |
Sample: |===========|
// categoryPercentage: 1.0
// barPercentage: 0.5
Bar: |.5| |.5|
Category: | 1.0 |
Sample: |==============|
// categoryPercentage: 0.5
// barPercentage: 1.0
Bar: |1.||1.|
Category: | .5 |
Sample: |==============|
```
-177
Ver Arquivo
@@ -1,177 +0,0 @@
---
title: Radar Chart
anchor: radar-chart
---
###Introduction
A radar chart is a way of showing multiple data points and the variation between them.
They are often useful for comparing the points of two or more different data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
###Example usage
```javascript
var myRadarChart = new Chart(ctx).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
@@ -1,172 +0,0 @@
---
title: Polar Area Chart
anchor: polar-area-chart
---
### Introduction
Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
This type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
new Chart(ctx).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.
```
+93
Ver Arquivo
@@ -0,0 +1,93 @@
---
title: Radar Chart
anchor: radar-chart
---
### Introduction
A radar chart is a way of showing multiple data points and the variation between them.
They are often useful for comparing the points of two or more different data sets.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "rgba(220,220,220,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointBorderColor: "#fff",
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
};
```
For a radar chart, to provide context of what each point means, we include an array of strings that show around each point in the chart.
For the radar chart data, we have an array of datasets. Each of these is an object, with a fill colour, a stroke colour, a colour for the fill of each point, and a colour for the stroke of each point. We also have an array of data values.
The label key on each dataset is optional, and can be used when generating a scale for the chart.
### Chart Options
These are the customisation options specific to Radar charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
The default options for radar chart are defined in `Chart.defaults.radar`.
Name | Type | Default | Description
--- | --- | --- | ---
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#scales-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid lines.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*elements*.line | Array | | Options for all line elements used on the chart, as defined in the global elements, duplicated here to show Radar chart specific defaults.
*elements.line*.tension | Number | 0 | Tension exhibited by lines when calculating splineCurve. Setting to 0 creates straight lines.
You can override these for your `Chart` instance by passing a second argument into the `Radar` method as an object with the keys you want to override.
For example, we could have a radar chart without a point for each on piece of data by doing the following:
```javascript
new Chart(ctx, {
type: "radar",
data: data,
options: {
scale: {
reverse: true,
ticks: {
beginAtZero: true
}
}
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Radar chart defaults but this particular instance's scale will be reversed as
// well as the ticks beginning at zero.
```
We can also change these defaults values for each Radar type that is created, this object is available at `Chart.defaults.radar`.
-158
Ver Arquivo
@@ -1,158 +0,0 @@
---
title: Pie & Doughnut Charts
anchor: doughnut-pie-chart
---
###Introduction
Pie and doughnut charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
They are excellent at showing the relational proportions between data.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
// For a pie chart
var myPieChart = new Chart(ctx[0]).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.
```
+91
Ver Arquivo
@@ -0,0 +1,91 @@
---
title: Polar Area Chart
anchor: polar-area-chart
---
### Introduction
Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value.
This type of chart is often useful when we want to show a comparison data similar to a pie chart, but also show a scale of values for context.
<div class="canvas-holder">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
new Chart(ctx, {
data: data,
type: 'polarArea',
options: options
});
```
### Data structure
```javascript
var data = {
datasets: [{
data: [
10,
32,
53,
14,
22,
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
};
```
As you can see, for the chart data you pass in an array of objects, with a value and a colour. The value attribute should be a number, while the color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
### Chart options
These are the customisation options specific to Polar Area charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
Name | Type | Default | Description
--- | --- | --- | ---
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#getting-started-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*scale*.lineArc | Boolean | true | When true, lines are circular.
animateRotate | Boolean |true | If true, will animate the rotation of the chart.
animateScale | Boolean | true | If true, will animate scaling the chart.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
*legend*.onClick | Function | function(event, legendItem) {} ` | Handles clicking an individual legend item
legendCallback | Function | `function(chart) ` | Generates the HTML legend via calls to `generateLegend`
You can override these for your `Chart` instance by passing a second argument into the `PolarArea` method as an object with the keys you want to override.
For example, we could have a polar area chart with a black stroke on each segment like so:
```javascript
new Chart(ctx, {
data: data,
type: "polarArea",
options: {
elements: {
arc: {
borderColor: "#000000"
}
}
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the PolarArea chart defaults but this particular instance will have `elements.arc.borderColor` set to `"#000000"`.
```
We can also change these defaults values for each PolarArea type that is created, this object is available at `Chart.defaults.polarArea`.
-187
Ver Arquivo
@@ -1,187 +0,0 @@
---
title: Advanced usage
anchor: advanced-usage
---
### Prototype methods
For each chart, there are a set of global prototype methods on the shared `ChartType` which you may find useful. These are available on all charts created with Chart.js, but for the examples, let's use a line chart we've made.
```javascript
// For example:
var myLineChart = new Chart(ctx).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.
+99
Ver Arquivo
@@ -0,0 +1,99 @@
---
title: Pie & Doughnut Charts
anchor: doughnut-pie-chart
---
### Introduction
Pie and doughnut charts are probably the most commonly used chart there are. They are divided into segments, the arc of each segment shows the proportional value of each piece of data.
They are excellent at showing the relational proportions between data.
Pie and doughnut charts are effectively the same class in Chart.js, but have one different default value - their `percentageInnerCutout`. This equates what percentage of the inner should be cut out. This defaults to `0` for pie charts, and `50` for doughnuts.
They are also registered under two aliases in the `Chart` core. Other than their different default value, and different alias, they are exactly the same.
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
<div class="canvas-holder half">
<canvas width="250" height="125"></canvas>
</div>
### Example usage
```javascript
// For a pie chart
var myPieChart = new Chart(ctx[0],{
type:'pie',
data: data,
options: options
});
// And for a doughnut chart
var myDoughnutChart = new Chart(ctx[1], {
type:'doughnut',
data: data,
options: options
});
```
### Data structure
```javascript
var data = {
labels: [
"Red",
"Green",
"Yellow"
],
datasets: [
{
data: [300, 50, 100],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C"
],
hoverBackgroundColor: [
"#FF5A5E",
"#5AD3D1",
"#FFC870"
]
}]
};
```
For a pie chart, you must pass in an array of objects with a value and an optional color property. The value attribute should be a number, Chart.js will total all of the numbers and calculate the relative proportion of each. The color attribute should be a string. Similar to CSS, for this string you can use HEX notation, RGB, RGBA or HSL.
### Chart options
These are the customisation options specific to Pie & Doughnut charts. These options are merged with the [global chart configuration options](#getting-started-global-chart-configuration), and form the options of the chart.
Name | Type | Default | Description
--- | --- | --- | ---
cutoutPercentage | Number | 50 - for doughnut, 0 - for pie | The percentage of the chart that is cut out of the middle.
scale | Array | [See Scales](#scales) and [Defaults for Radial Linear Scale](#getting-started-radial-linear-scale) | Options for the one scale used on the chart. Use this to style the ticks, labels, and grid.
*scale*.type | String |"radialLinear" | As defined in ["Radial Linear"](#scales-radial-linear-scale).
*scale*.lineArc | Boolean | true | When true, lines are arced compared to straight when false.
*animation*.animateRotate | Boolean |true | If true, will animate the rotation of the chart.
*animation*.animateScale | Boolean | false | If true, will animate scaling the Doughnut from the centre.
*legend*.*labels*.generateLabels | Function | `function(data) {} ` | Returns labels for each the legend
*legend*.onClick | Function | function(event, legendItem) {} ` | Handles clicking an individual legend item
You can override these for your `Chart` instance by passing a second argument into the `Doughnut` method as an object with the keys you want to override.
For example, we could have a doughnut chart that animates by scaling out from the centre like so:
```javascript
new Chart(ctx,{
type:"doughnut",
animation:{
animateScale:true
}
});
// This will create a chart with all of the default options, merged from the global config,
// and the Doughnut chart defaults but this particular instance will have `animateScale` set to `true`.
```
We can also change these default values for each Doughnut type that is created, this object is available at `Chart.defaults.doughnut`. Pie charts also have a clone of these defaults available to change at `Chart.defaults.pie`, with the only difference being `percentageInnerCutout` being set to 0.
+386
Ver Arquivo
@@ -0,0 +1,386 @@
---
title: Advanced usage
anchor: advanced-usage
---
### Prototype methods
For each chart, there are a set of global prototype methods on the shared `ChartType` which you may find useful. These are available on all charts created with Chart.js, but for the examples, let's use a line chart we've made.
```javascript
// For example:
var myLineChart = new Chart(ctx, config);
```
#### .destroy()
Use this to destroy any chart instances that are created. This will clean up any references stored to the chart object within Chart.js, along with any associated event listeners attached by Chart.js.
This must be called before the canvas is reused for a new chart.
```javascript
// Destroys a specific chart instance
myLineChart.destroy();
```
#### .update(duration, lazy)
Triggers an update of the chart. This can be safely called after replacing the entire data object. This will update all scales, legends, and then re-render the chart.
```javascript
// duration is the time for the animation of the redraw in miliseconds
// lazy is a boolean. if true, the animation can be interupted by other animations
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
```
#### .render(duration, lazy)
Triggers a redraw of all chart elements. Note, this does not update elements for new data. Use `.update()` in that case.
```javascript
// duration is the time for the animation of the redraw in miliseconds
// lazy is a boolean. if true, the animation can be interupted by other animations
myLineChart.render(duration, lazy);
```
#### .stop()
Use this to stop any current animation loop. This will pause the chart during any current animation frame. Call `.render()` to re-animate.
```javascript
// Stops the charts animation loop at its current frame
myLineChart.stop();
// => returns 'this' for chainability
```
#### .resize()
Use this to manually resize the canvas element. This is run each time the canvas container is resized, but you can call this method manually if you change the size of the canvas nodes container element.
```javascript
// Resizes & redraws to fill its container element
myLineChart.resize();
// => returns 'this' for chainability
```
#### .clear()
Will clear the chart canvas. Used extensively internally between animation frames, but you might find it useful.
```javascript
// Will clear the canvas that myLineChart is drawn on
myLineChart.clear();
// => returns 'this' for chainability
```
#### .toBase64Image()
This returns a base 64 encoded string of the chart in it's current state.
```javascript
myLineChart.toBase64Image();
// => returns png data url of the image on the canvas
```
#### .generateLegend()
Returns an HTML string of a legend for that chart. The legend is generated from the `legendCallback` in the options.
```javascript
myLineChart.generateLegend();
// => returns HTML string of a legend for this chart
```
#### .getElementAtEvent(e)
Calling `getElementAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the single element at the event position. If there are multiple items within range, only the first is returned
```javascript
myLineChart.getElementAtEvent(e);
// => returns the first element at the event point.
```
#### .getElementsAtEvent(e)
Looks for the element under the event point, then returns all elements at the same data index. This is used internally for 'label' mode highlighting.
Calling `getElementsAtEvent(event)` on your Chart instance passing an argument of an event, or jQuery event, will return the point elements that are at that the same position of that event.
```javascript
canvas.onclick = function(evt){
var activePoints = myLineChart.getElementsAtEvent(evt);
// => activePoints is an array of points on the canvas that are at the same position as the click event.
};
```
This functionality may be useful for implementing DOM based tooltips, or triggering custom behaviour in your application.
#### .getDatasetAtEvent(e)
Looks for the element under the event point, then returns all elements from that dataset. This is used internally for 'dataset' mode highlighting
```javascript
myLineChart.getDatasetAtEvent(e);
// => returns an array of elements
```
### External Tooltips
You can enable custom tooltips in the global or chart configuration like so:
```javascript
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
custom: function(tooltip) {
// tooltip will be false if tooltip is not visible or should be hidden
if (!tooltip) {
return;
}
// Otherwise, tooltip will be an object with all tooltip properties like:
// tooltip.caretHeight
// tooltip.caretPadding
// tooltip.chart
// tooltip.cornerRadius
// tooltip.fillColor
// tooltip.font...
// tooltip.text
// tooltip.x
// tooltip.y
// etc...
}
}
}
});
```
See `sample/line-customTooltips.html` for examples on how to get started.
### Writing new scale types
Starting with Chart.js 2.0 scales can be individually extended. Scales should always derive from Chart.Scale.
```javascript
var MyScale = Chart.Scale.extend({
/* extensions ... */
});
// MyScale is now derived from Chart.Scale
```
Once you have created your scale class, you need to register it with the global chart object so that it can be used. A default config for the scale may be provided when registering the constructor. The first parameter to the register function is a string key that is used later to identify which scale type to use for a chart.
```javascript
Chart.scaleService.registerScaleType('myScale', MyScale, defaultConfigObject);
```
To use the new scale, simply pass in the string key to the config when creating a chart.
```javascript
var lineChart = new Chart(ctx, {
data: data,
type: 'line',
options: {
scales: {
yAxes: [{
type: 'myScale' // this is the same key that was passed to the registerScaleType function
}]
}
}
})
```
#### Scale Properties
Scale instances are given the following properties during the fitting process.
```javascript
{
left: Number, // left edge of the scale bounding box
right: Number, // right edge of the bounding box'
top: Number,
bottom: Number,
width: Number, // the same as right - left
height: Number, // the same as bottom - top
// Margin on each side. Like css, this is outside the bounding box.
margins: {
left: Number,
right: Number,
top: Number,
bottom: Number,
},
// Amount of padding on the inside of the bounding box (like CSS)
paddingLeft: Number,
paddingRight: Number,
paddingTop: Number,
paddingBottom: Number,
}
```
#### Scale Interface
To work with Chart.js, custom scale types must implement the following interface.
```javascript
{
// Determines the data limits. Should set this.min and this.max to be the data max/min
determineDataLimits: function() {},
// Generate tick marks. this.chart is the chart instance. The data object can be accessed as this.chart.data
// buildTicks() should create a ticks array on the scale instance, if you intend to use any of the implementations from the base class
buildTicks: function() {},
// Get the value to show for the data at the given index of the the given dataset, ie this.chart.data.datasets[datasetIndex].data[index]
getLabelForIndex: function(index, datasetIndex) {},
// Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
// @param index: index into the ticks array
// @param includeOffset: if true, get the pixel halway between the given tick and the next
getPixelForTick: function(index, includeOffset) {},
// Get the pixel (x coordinate for horizontal scale, y coordinate for vertical scales) for a given value
// @param value : the value to get the pixel for
// @param index : index into the data array of the value
// @param datasetIndex : index of the dataset the value comes from
// @param includeOffset : if true, get the pixel halway between the given tick and the next
getPixelForValue: function(value, index, datasetIndex, includeOffset) {}
}
```
Optionally, the following methods may also be overwritten, but an implementation is already provided by the `Chart.Scale` base class.
```javascript
// Transform the ticks array of the scale instance into strings. The default implementation simply calls this.options.ticks.callback(numericalTick, index, ticks);
convertTicksToLabels: function() {},
// Determine how much the labels will rotate by. The default implementation will only rotate labels if the scale is horizontal.
calculateTickRotation: function() {},
// Fits the scale into the canvas.
// this.maxWidth and this.maxHeight will tell you the maximum dimensions the scale instance can be. Scales should endeavour to be as efficient as possible with canvas space.
// this.margins is the amount of space you have on either side of your scale that you may expand in to. This is used already for calculating the best label rotation
// You must set this.minSize to be the size of your scale. It must be an object containing 2 properties: width and height.
// You must set this.width to be the width and this.height to be the height of the scale
fit: function() {},
// Draws the scale onto the canvas. this.(left|right|top|bottom) will have been populated to tell you the area on the canvas to draw in
// @param chartArea : an object containing four properties: left, right, top, bottom. This is the rectangle that lines, bars, etc will be drawn in. It may be used, for example, to draw grid lines.
draw: function(chartArea) {},
```
The Core.Scale base class also has some utility functions that you may find useful.
```javascript
{
// Returns true if the scale instance is horizontal
isHorizontal: function() {},
// Get the correct value from the value from this.chart.data.datasets[x].data[]
// If dataValue is an object, returns .x or .y depending on the return of isHorizontal()
// If the value is undefined, returns NaN
// Otherwise returns the value.
// Note that in all cases, the returned value is not guaranteed to be a Number
getRightValue: function(dataValue) {},
}
```
### Writing new chart types
Chart.js 2.0 introduces the concept of controllers for each dataset. Like scales, new controllers can be written as needed.
```javascript
Chart.controllers.MyType = Chart.DatasetController.extend({
});
// Now we can create a new instance of our chart, using the Chart.js API
new Chart(ctx, {
// this is the string the constructor was registered at, ie Chart.controllers.MyType
type: 'MyType',
data: data,
options: options
});
```
#### Dataset Controller Interface
Dataset controllers must implement the following interface.
```javascript
{
// Create elements for each piece of data in the dataset. Store elements in an array on the dataset as dataset.metaData
addElements: function() {},
// Create a single element for the data at the given index and reset its state
addElementAndReset: function(index) {},
// Draw the representation of the dataset
// @param ease : if specified, this number represents how far to transition elements. See the implementation of draw() in any of the provided controllers to see how this should be used
draw: function(ease) {},
// Remove hover styling from the given element
removeHoverStyle: function(element) {},
// Add hover styling to the given element
setHoverStyle: function(element) {},
// Update the elements in response to new data
// @param reset : if true, put the elements into a reset state so they can animate to their final values
update: function(reset) {},
}
```
The following methods may optionally be overridden by derived dataset controllers
```javascript
{
// Initializes the controller
initialize: function(chart, datasetIndex) {},
// Ensures that the dataset represented by this controller is linked to a scale. Overridden to helpers.noop in the polar area and doughnut controllers as these
// chart types using a single scale
linkScales: function() {},
// Called by the main chart controller when an update is triggered. The default implementation handles the number of data points changing and creating elements appropriately.
buildOrUpdateElements: function() {}
}
```
### Extending existing chart types
Extending or replacing an existing controller type is easy. Simply replace the constructor for one of the built in types with your own.
The built in controller types are:
* `Chart.controllers.line`
* `Chart.controllers.bar`
* `Chart.controllers.radar`
* `Chart.controllers.doughnut`
* `Chart.controllers.polarArea`
* `Chart.controllers.bubble`
#### Bar Controller
The bar controller has a special property that you should be aware of. To correctly calculate the width of a bar, the controller must determine the number of datasets that map to bars. To do this, the bar controller attaches a property `bar` to the dataset during initialization. If you are creating a replacement or updated bar controller, you should do the same. This will ensure that charts with regular bars and your new derived bars will work seamlessly.
### Building Chart.js
Chart.js uses <a href="http://gulpjs.com/" target="_blank">gulp</a> to build the library into a single JavaScript file.
Firstly, we need to ensure development dependencies are installed. With node and npm installed, after cloning the Chart.js repo to a local directory, and navigating to that directory in the command line, we can run the following:
```bash
npm install
npm install -g gulp
```
This will install the local development dependencies for Chart.js, along with a CLI for the JavaScript task runner <a href="http://gulpjs.com/" target="_blank">gulp</a>.
Now, we can run the `gulp build` task.
```bash
gulp build
```
Ver Arquivo
+194 -124
Ver Arquivo
@@ -1,137 +1,207 @@
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');
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'),
browserify = require('browserify'),
streamify = require('gulp-streamify'),
source = require('vinyl-source-stream'),
merge = require('merge-stream');
var srcDir = './src/';
/*
* 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 outDir = './dist/';
var testDir = './test/';
gulp.task('build', function(){
var preTestFiles = [
'./node_modules/moment/min/moment.min.js',
];
// Default to all of the chart types, with Chart.Core first
var srcFiles = [FileName('Core')],
isCustom = !!(util.env.types),
outputDir = (isCustom) ? 'custom' : '.';
if (isCustom){
util.env.types.split(',').forEach(function(type){ return srcFiles.push(FileName(type));});
}
else{
// Seems gulp-concat remove duplicates - nice!
// So we can use this to sort out dependency order - aka include Core first!
srcFiles.push(srcDir+'*');
}
return gulp.src(srcFiles)
.pipe(concat('Chart.js'))
.pipe(replace('{{ version }}', package.version))
.pipe(gulp.dest(outputDir))
.pipe(uglify({preserveComments:'some'}))
.pipe(concat('Chart.min.js'))
.pipe(gulp.dest(outputDir));
function FileName(moduleName){
return srcDir+'Chart.'+moduleName+'.js';
}
});
/*
* Usage : gulp bump
* Prompts: Version increment to bump
* Output: - New version number written into package.json & bower.json
*/
gulp.task('bump', function(complete){
util.log('Current version:', util.colors.cyan(package.version));
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType){
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();
});
});
gulp.task('release', ['build'], function(){
exec('git tag -a v' + package.version);
});
gulp.task('jshint', function(){
return gulp.src(srcDir + '*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('valid', function(){
return gulp.src('samples/*.html')
.pipe(htmlv());
});
gulp.task('library-size', function(){
return gulp.src('Chart.min.js')
.pipe(size({
gzip: true
}));
});
gulp.task('module-sizes', function(){
return gulp.src(srcDir + '*.js')
.pipe(uglify({preserveComments:'some'}))
.pipe(size({
showFiles: true,
gzip: true
}));
});
gulp.task('watch', function(){
gulp.watch('./src/*', ['build']);
});
gulp.task('test', ['jshint', 'valid']);
var testFiles = [
'./test/mockContext.js',
'./test/*.js'
];
gulp.task('build', buildTask);
gulp.task('coverage', coverageTask);
gulp.task('watch', watchTask);
gulp.task('bump', bumpTask);
gulp.task('release', ['build'], releaseTask);
gulp.task('jshint', jshintTask);
gulp.task('test', ['jshint', 'validHTML', 'unittest']);
gulp.task('size', ['library-size', 'module-sizes']);
gulp.task('server', serverTask);
gulp.task('validHTML', validHTMLTask);
gulp.task('unittest', unittestTask);
gulp.task('unittestWatch', unittestWatchTask);
gulp.task('library-size', librarySizeTask);
gulp.task('module-sizes', moduleSizesTask);
gulp.task('_open', _openTask);
gulp.task('dev', ['server', 'default']);
gulp.task('default', ['build', 'watch']);
gulp.task('server', function(){
connect.server({
port: 8000
});
});
function buildTask() {
var bundled = browserify('./src/Chart.js')
.bundle()
.pipe(source('Chart.bundle.js'))
.pipe(streamify(replace('{{ version }}', package.version)))
.pipe(gulp.dest(outDir))
.pipe(streamify(uglify({
preserveComments: 'some'
})))
.pipe(streamify(concat('Chart.bundle.min.js')))
.pipe(gulp.dest(outDir));
var nonBundled = browserify('./src/Chart.js')
.ignore('moment')
.bundle()
.pipe(source('Chart.js'))
.pipe(streamify(replace('{{ version }}', package.version)))
.pipe(gulp.dest(outDir))
.pipe(streamify(uglify({
preserveComments: 'some'
})))
.pipe(streamify(concat('Chart.min.js')))
.pipe(gulp.dest(outDir));
return merge(bundled, nonBundled);
}
/*
* 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('config.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'))
.pipe(jshint.reporter('fail'));
}
function validHTMLTask() {
return gulp.src('samples/*.html')
.pipe(htmlv());
}
function unittestTask() {
var files = ['./src/**/*.js'];
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.conf.ci.js',
action: 'run'
}));
}
function unittestWatchTask() {
var files = ['./src/**/*.js'];
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.conf.js',
action: 'watch'
}));
}
function coverageTask() {
var files = ['./src/**/*.js'];
Array.prototype.unshift.apply(files, preTestFiles);
Array.prototype.push.apply(files, testFiles);
return gulp.src(files)
.pipe(karma({
configFile: 'karma.coverage.conf.js',
action: 'run'
}));
}
function librarySizeTask() {
return gulp.src('dist/Chart.bundle.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
gulp.task('_open', function(){
exec('open http://localhost:8000');
exec('subl .');
});
gulp.task('dev', ['server', 'default']);
function _openTask() {
exec('open http://localhost:8000');
exec('subl .');
}
+25
Ver Arquivo
@@ -0,0 +1,25 @@
module.exports = function(config) {
var configuration = {
browsers: ['Firefox'],
customLaunchers: {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
},
frameworks: ['browserify', 'jasmine'],
reporters: ['progress', 'html'],
preprocessors: {
'src/**/*.js': ['browserify']
},
browserify: {
debug: true
}
};
if (process.env.TRAVIS) {
configuration.browsers.push('Chrome_travis_ci');
}
config.set(configuration);
};
+14
Ver Arquivo
@@ -0,0 +1,14 @@
module.exports = function(config) {
config.set({
browsers: ['Chrome', 'Firefox'],
frameworks: ['browserify', 'jasmine'],
reporters: ['progress', 'html'],
preprocessors: {
'src/**/*.js': ['browserify']
},
browserify: {
debug: true
}
});
};
+43
Ver Arquivo
@@ -0,0 +1,43 @@
module.exports = function(config) {
var configuration = {
browsers: ['Firefox'],
frameworks: ['browserify', 'jasmine'],
preprocessors: {
'src/**/*.js': ['browserify']
},
browserify: {
debug: true,
transform: [['browserify-istanbul', {
instrumenterConfig: {
embed: true
}
}]]
},
reporters: ['progress', 'coverage'],
coverageReporter: {
dir: 'coverage/',
reporters: [
{ type: 'html', subdir: 'report-html' },
{ type: 'lcovonly', subdir: '.', file: 'lcov.info' }
]
}
};
// If on the CI, use the CI chrome launcher
if (process.env.TRAVIS) {
configuration.browsers.push('Chrome_travis_ci');
configuration.customLaunchers = {
Chrome_travis_ci: {
base: 'Chrome',
flags: ['--no-sandbox']
}
};
} else {
configuration.browsers.push('Chrome');
}
config.set(configuration);
};
+29 -6
Ver Arquivo
@@ -2,27 +2,50 @@
"name": "chart.js",
"homepage": "http://www.chartjs.org",
"description": "Simple HTML5 charts using the canvas element.",
"version": "1.0.2",
"main": "Chart.js",
"version": "2.0.0",
"main": "src/chart.js",
"repository": {
"type": "git",
"url": "https://github.com/nnnick/Chart.js.git"
},
"dependences": {},
"devDependencies": {
"gulp": "3.5.x",
"browserify": "^13.0.0",
"browserify-istanbul": "^0.2.1",
"coveralls": "^2.11.6",
"gulp": "3.9.x",
"gulp-concat": "~2.1.x",
"gulp-connect": "~2.0.5",
"gulp-html-validator": "^0.0.2",
"gulp-jshint": "~1.5.1",
"gulp-karma": "0.0.4",
"gulp-replace": "^0.4.0",
"gulp-size": "~0.4.0",
"gulp-streamify": "^1.0.2",
"gulp-uglify": "~0.2.x",
"gulp-umd": "~0.2.0",
"gulp-util": "~2.2.x",
"gulp-html-validator": "^0.0.2",
"inquirer": "^0.5.1",
"semver": "^3.0.1"
"jasmine": "^2.3.2",
"jasmine-core": "^2.3.4",
"jquery": "^2.1.4",
"jshint-stylish": "~2.1.0",
"karma": "^0.12.37",
"karma-browserify": "^5.0.1",
"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",
"merge-stream": "^1.0.0",
"semver": "^3.0.1",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.7.0"
},
"spm": {
"main": "Chart.js"
},
"dependencies": {
"chartjs-color": "^1.0.2",
"moment": "^2.10.6"
}
}
+170
Ver Arquivo
@@ -0,0 +1,170 @@
<!doctype html>
<html>
<head>
<title> Animation Callbacks </title>
<script src="../../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 75%;">
<canvas id="canvas"></canvas>
<progress id="animationProgress" max="1" value="0" style="width: 100%"></progress>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var $progress = $('#animationProgress');
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset ",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset ",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
title:{
display:true,
text:"Chart.js Line Chart - Animation Progress Bar"
},
animation: {
duration: 2000,
onProgress: function(animation) {
$progress.attr({
value: animation.animationObject.currentStep / animation.animationObject.numSteps,
});
},
onComplete: function(animation) {
window.setTimeout(function() {
$progress.attr({
value: 0
});
}, 2000);
}
},
tooltips: {
mode: 'label',
},
scales: {
xAxes: [{
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
scaleLabel: {
show: true,
labelString: 'Value'
},
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myLine.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+102
Ver Arquivo
@@ -0,0 +1,102 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Multi Axis</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 75%">
<canvas id="canvas"></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,
title:{
display:true,
text:"Chart.js Bar Chart - Multi Axis"
},
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>
+84
Ver Arquivo
@@ -0,0 +1,84 @@
<!doctype html>
<html>
<head>
<title>Stacked Bar Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 75%">
<canvas id="canvas"></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: {
title:{
display:true,
text:"Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
};
$('#randomizeData').click(function() {
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
});
window.myBar.update();
});
</script>
</body>
</html>
+134 -47
Ver Arquivo
@@ -1,57 +1,144 @@
<!doctype html>
<html>
<head>
<title>Bar Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width: 50%">
<canvas id="canvas" height="450" width="600"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
<head>
<title>Bar Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
var barChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,0.8)",
highlightFill : "rgba(151,187,205,0.75)",
highlightStroke : "rgba(151,187,205,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
}
window.onload = function(){
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx).Bar(barChartData, {
responsive : true
});
}
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)';
};
$('#randomizeData').click(function(){
barChartData.datasets[0].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
barChartData.datasets[0].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: true,
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
barChartData.datasets[1].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
barChartData.datasets[1].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
};
window.myBar.update();
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
}
});
};
$('#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();
});
$('#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();
});
$('#addData').click(function() {
if (barChartData.datasets.length > 0) {
var month = MONTHS[barChartData.labels.length % MONTHS.length];
barChartData.labels.push(month);
for (var index = 0; index < barChartData.datasets.length; ++index) {
//window.myBar.addData(randomScalingFactor(), index);
barChartData.datasets[index].data.push(randomScalingFactor());
}
window.myBar.update();
}
});
$('#removeDataset').click(function() {
barChartData.datasets.splice(0, 1);
window.myBar.update();
});
$('#removeData').click(function() {
barChartData.labels.splice(-1, 1); // remove the label first
barChartData.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myBar.update();
});
</script>
</body>
</script>
</body>
</html>
+192
Ver Arquivo
@@ -0,0 +1,192 @@
<!doctype html>
<html>
<head>
<title>Bubble Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style type="text/css">
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var DEFAULT_DATASET_SIZE = 7;
var addedCount = 0;
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var bubbleChartData = {
animation: {
duration: 10000
},
datasets: [{
label: "My First dataset",
backgroundColor: randomColor(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}]
}, {
label: "My Second dataset",
backgroundColor: randomColor(),
data: [{
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
}]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myChart = new Chart(ctx, {
type: 'bubble',
data: bubbleChartData,
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Bubble Chart'
},
}
});
};
$('#randomizeData').click(function() {
var zero = Math.random() < 0.2 ? true : false;
$.each(bubbleChartData.datasets, function(i, dataset) {
dataset.backgroundColor = randomColor();
dataset.data = dataset.data.map(function() {
return {
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
};
});
});
window.myChart.update();
});
$('#addDataset').click(function() {
++addedCount;
var newDataset = {
label: "My added dataset " + addedCount,
backgroundColor: randomColor(),
data: []
};
for (var index = 0; index < DEFAULT_DATASET_SIZE; ++index) {
newDataset.data.push({
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
});
}
bubbleChartData.datasets.push(newDataset);
window.myChart.update();
});
$('#addData').click(function() {
if (bubbleChartData.datasets.length > 0) {
for (var index = 0; index < bubbleChartData.datasets.length; ++index) {
bubbleChartData.datasets[index].data.push({
x: randomScalingFactor(),
y: randomScalingFactor(),
r: Math.abs(randomScalingFactor()) / 5,
});
}
window.myChart.update();
}
});
$('#removeDataset').click(function() {
bubbleChartData.datasets.splice(0, 1);
window.myChart.update();
});
$('#removeData').click(function() {
bubbleChartData.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myChart.update();
});
</script>
</body>
</html>
+80
Ver Arquivo
@@ -0,0 +1,80 @@
<!doctype html>
<html>
<head>
<title>Combo Bar-Line Chart</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="../dist/Chart.bundle.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width: 75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'line',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'bar',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, ]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js Combo Bar Line Chart'
}
}
});
};
$('#randomizeData').click(function() {
$.each(barChartData.datasets, function(i, dataset) {
dataset.backgroundColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
dataset.data = [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()];
});
window.myBar.update();
});
</script>
</body>
</html>
-58
Ver Arquivo
@@ -1,58 +0,0 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../src/Chart.Core.js"></script>
<script src="../src/Chart.Doughnut.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
#canvas-holder{
width:30%;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="500" height="500"/>
</div>
<script>
var doughnutData = [
{
value: 1,
label: "One"
},
{
value: 2,
label: "Two"
},
{
value: 3,
label: "Three"
},
{
value: 4,
label: "Four"
},
{
value: 5,
label: "Five"
}
];
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
};
</script>
</body>
</html>
+163 -67
Ver Arquivo
@@ -1,80 +1,176 @@
<!doctype html>
<html>
<head>
<title>Doughnut Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
body{
padding: 0;
margin: 0;
}
#canvas-holder{
width:30%;
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="500" height="500"/>
</div>
<button id="randomizeData">Randomize Data</button>
<head>
<title>Doughnut Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<script>
<body>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area" />
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<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 randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
var config = {
type: 'doughnut',
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Dataset 1'
}, {
hidden: true,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Dataset 2'
}, {
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'Dataset 3'
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Doughnut Chart'
}
}
};
var doughnutData = [
{
value: randomScalingFactor(),
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: randomScalingFactor(),
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: randomScalingFactor(),
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: randomScalingFactor(),
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: randomScalingFactor(),
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}
window.onload = function() {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx, config);
};
];
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myDoughnut = new Chart(ctx).Doughnut(doughnutData, {responsive : true});
};
dataset.backgroundColor = dataset.backgroundColor.map(function() {
return randomColor(0.7);
});
});
$('#randomizeData').click(function(){
$.each(doughnutData, function(i, piece){
doughnutData[i].value = randomScalingFactor();
doughnutData[i].color = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
});
window.myDoughnut.update();
});
window.myDoughnut.update();
});
$('#addDataset').click(function() {
var newDataset = {
backgroundColor: [],
data: [],
label: 'New dataset ' + config.data.datasets.length,
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
newDataset.backgroundColor.push(randomColor(0.7));
}
config.data.datasets.push(newDataset);
window.myDoughnut.update();
});
$('#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();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myDoughnut.update();
});
$('#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();
});
</script>
</body>
</script>
</body>
</html>
+114 -102
Ver Arquivo
@@ -2,128 +2,140 @@
<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%;
<title>Line Chart with Custom Tooltips</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
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>
.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>
<div id="canvas-holder2">
<canvas id="chart2" width="450" height="600" />
</div>
<div id="chartjs-tooltip"></div>
<script>
<div id="canvas-holder1" style="width:75%;">
<canvas id="chart1"/>
</div>
<script>
window.count = 0;
Chart.defaults.global.pointHitDetectionRadius = 1;
Chart.defaults.global.customTooltips = function(tooltip) {
var customTooltips = function(tooltip) {
var tooltipEl = $('#chartjs-tooltip');
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
var innerHtml = '';
for (var i = tooltip.labels.length - 1; i >= 0; i--) {
innerHtml += [
'<div class="chartjs-tooltip-section">',
' <span class="chartjs-tooltip-key" style="background-color:' + tooltip.legendColors[i].fill + '"></span>',
' <span class="chartjs-tooltip-value">' + tooltip.labels[i] + '</span>',
'</div>'
].join('');
}
tooltipEl.html(innerHtml);
if (!tooltipEl[0]) {
$('body').append('<div id="chartjs-tooltip"></div>');
tooltipEl = $('#chartjs-tooltip');
}
// Hide if no tooltip
if (!tooltip.opacity) {
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + tooltip.y + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
opacity: 0
});
$('.chartjs-wrap canvas')
.each(function(index, el) {
$(el).css('cursor', 'default');
});
return;
}
$(this._chart.canvas).css('cursor', 'pointer');
// Set caret Position
tooltipEl.removeClass('above below no-transform');
if (tooltip.yAlign) {
tooltipEl.addClass(tooltip.yAlign);
} else {
tooltipEl.addClass('no-transform');
}
// Set Text
if (tooltip.body) {
var innerHtml = [
(tooltip.beforeTitle || []).join('\n'), (tooltip.title || []).join('\n'), (tooltip.afterTitle || []).join('\n'), (tooltip.beforeBody || []).join('\n'), (tooltip.body || []).join('\n'), (tooltip.afterBody || []).join('\n'), (tooltip.beforeFooter || [])
.join('\n'), (tooltip.footer || []).join('\n'), (tooltip.afterFooter || []).join('\n')
];
tooltipEl.html(innerHtml.join('\n'));
}
// Find Y Location on page
var top = 0;
if (tooltip.yAlign) {
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
}
var offset = $(this._chart.canvas).offset();
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
width: tooltip.width ? (tooltip.width + 'px') : 'auto',
left: offset.left + tooltip.x + 'px',
top: offset.top + top + 'px',
fontFamily: tooltip._fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip._fontStyle,
padding: tooltip.yPadding + 'px ' + tooltip.xPadding + 'px',
});
};
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
return Math.round(Math.random() * 100);
};
var lineChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
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 ctx1 = document.getElementById("chart1").getContext("2d");
window.myLine = new Chart(ctx1).Line(lineChartData, {
showScale: false,
pointDot : true,
responsive: true
});
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine = new Chart(ctx2).Line(lineChartData, {
responsive: true
});
var chartEl = document.getElementById("chart1");
window.myLine = new Chart(chartEl, {
type: 'line',
data: lineChartData,
options: {
title:{
display:true,
text:'Chart.js Line Chart - Custom Tooltips'
},
tooltips: {
enabled: false,
custom: customTooltips
}
}
});
};
</script>
</script>
</body>
</html>
+171
Ver Arquivo
@@ -0,0 +1,171 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Third dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}, {
label: "My Fourth dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}]
},
options: {
responsive: true,
legend: {
position: 'bottom',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
},
title: {
display: true,
text: 'Chart.js Line Chart - Legend'
}
}
};
$.each(config.data.datasets, function(i, dataset) {
var background = randomColor(0.5);
dataset.borderColor = background;
dataset.backgroundColor = background;
dataset.pointBorderColor = background;
dataset.pointBackgroundColor = background;
dataset.pointBorderWidth = 1;
});
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 background = randomColor(0.5);
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: background,
backgroundColor: background,
pointBorderColor: background,
pointBackgroundColor: background,
pointBorderWidth: 1,
fill: false,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+152
Ver Arquivo
@@ -0,0 +1,152 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
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,
title:{
display:true,
text:'Chart.js Line Chart - Logarithmic'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'x axis'
}
}],
yAxes: [{
display: true,
type: 'logarithmic',
scaleLabel: {
display: true,
labelString: 'y axis'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
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) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
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>
+101
Ver Arquivo
@@ -0,0 +1,101 @@
<!doctype html>
<html>
<head>
<title>Line Chart Multiple Axes</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = Chart.Line(ctx, {
data: lineChartData,
options: {
responsive: true,
hoverMode: 'label',
stacked: false,
title:{
display:true,
text:'Chart.js Line Chart - Multi Axis'
},
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>
+164
Ver Arquivo
@@ -0,0 +1,164 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
//return 0;
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
// Skip a point in the middle
data: [randomScalingFactor(), randomScalingFactor(), NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: true,
borderDash: [5, 5],
}, {
label: "My Second dataset",
// Skip first and last points
data: [NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart - Skip Points'
},
tooltips: {
mode: 'label',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
},
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
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) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+163
Ver Arquivo
@@ -0,0 +1,163 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '1') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Third dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Third dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - Stacked Area"
},
tooltips: {
mode: 'label',
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
var color = randomColor(1);
dataset.borderColor = color;
dataset.backgroundColor = color;
dataset.pointBorderColor = color;
dataset.pointBackgroundColor = color;
dataset.pointBorderWidth = 1;
});
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) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+151
Ver Arquivo
@@ -0,0 +1,151 @@
<!doctype html>
<html>
<head>
<title>Chart with xAxis Filtering</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
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", "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,
title:{
display:true,
text:"Chart.js Line Chart - X-Axis Filter"
},
scales: {
xAxes: [{
display: true,
ticks: {
userCallback: function(dataLabel, index) {
return index % 2 === 0 ? dataLabel : '';
}
}
}],
yAxes: [{
display: true,
beginAtZero: false
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
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) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
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>
+205 -55
Ver Arquivo
@@ -1,68 +1,218 @@
<!doctype html>
<html>
<head>
<title>Line 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:30%">
<div>
<canvas id="canvas" height="450" width="600"></canvas>
</div>
</div>
<button id="randomizeData">Randomize Data</button>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<script>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="changeDataObject">Change Data Object</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
//return 0;
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
label: "My First dataset",
fillColor : "rgba(220,220,220,0.2)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(220,220,220,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
},
{
label: "My Second dataset",
fillColor : "rgba(151,187,205,0.2)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
pointHighlightFill : "#fff",
pointHighlightStroke : "rgba(151,187,205,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
hidden: true,
label: 'hidden dataset',
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:'Chart.js Line Chart'
},
tooltips: {
mode: 'label',
callbacks: {
// beforeTitle: function() {
// return '...beforeTitle';
// },
// afterTitle: function() {
// return '...afterTitle';
// },
// beforeBody: function() {
// return '...beforeBody';
// },
// afterBody: function() {
// return '...afterBody';
// },
// beforeFooter: function() {
// return '...beforeFooter';
// },
// footer: function() {
// return 'Footer';
// },
// afterFooter: function() {
// return '...afterFooter';
// },
}
},
hover: {
mode: 'dataset'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
},
ticks: {
suggestedMin: -10,
suggestedMax: 250,
}
}]
}
}
};
}
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function(){
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx).Line(lineChartData, {
responsive: true
});
}
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
$('#randomizeData').click(function(){
lineChartData.datasets[0].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
lineChartData.datasets[0].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
lineChartData.datasets[1].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
lineChartData.datasets[1].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
});
window.myLine.update();
});
window.myLine.update();
});
$('#changeDataObject').click(function() {
config.data = {
labels: ["July", "August", "September", "October", "November", "December"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
}, {
label: "My Second dataset",
fill: false,
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
// Update the chart
window.myLine.update();
});
$('#addDataset').click(function() {
var newDataset = {
label: 'Dataset ' + config.data.datasets.length,
borderColor: randomColor(0.4),
backgroundColor: randomColor(0.5),
pointBorderColor: randomColor(0.7),
pointBackgroundColor: randomColor(0.5),
pointBorderWidth: 1,
data: [],
};
for (var index = 0; index < config.data.labels.length; ++index) {
newDataset.data.push(randomScalingFactor());
}
config.data.datasets.push(newDataset);
window.myLine.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</script>
</body>
</html>
-156
Ver Arquivo
@@ -1,156 +0,0 @@
<!doctype html>
<html>
<head>
<title>Pie Chart with Custom Tooltips</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
#canvas-holder {
width: 100%;
margin-top: 50px;
text-align: center;
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.below {
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
#chartjs-tooltip.below:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 0 8px 8px 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above {
-webkit-transform: translate(-50%, -100%);
transform: translate(-50%, -100%);
}
#chartjs-tooltip.above:before {
border: solid;
border-color: #111 transparent;
border-color: rgba(0, 0, 0, .8) transparent;
border-width: 8px 8px 0 8px;
bottom: 1em;
content: "";
display: block;
left: 50%;
top: 100%;
position: absolute;
z-index: 99;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
</style>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area1" width="50" height="50" />
</div>
<div id="canvas-holder">
<canvas id="chart-area2" width="300" height="300" />
</div>
<div id="chartjs-tooltip"></div>
<script>
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
return;
}
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var pieData = [{
value: 300,
color: "#F7464A",
highlight: "#FF5A5E",
label: "Red"
}, {
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
}, {
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}, {
value: 40,
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
}, {
value: 120,
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}];
window.onload = function() {
var ctx1 = document.getElementById("chart-area1").getContext("2d");
window.myPie = new Chart(ctx1).Pie(pieData);
var ctx2 = document.getElementById("chart-area2").getContext("2d");
window.myPie = new Chart(ctx2).Pie(pieData);
};
</script>
</body>
</html>
+110 -58
Ver Arquivo
@@ -1,70 +1,122 @@
<!doctype html>
<html>
<head>
<title>Pie Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div id="canvas-holder">
<canvas id="chart-area" width="300" height="300"/>
</div>
<button id="randomizeData">Randomize Data</button>
<script>
<head>
<title>Pie Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
<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: randomScalingFactor(),
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: randomScalingFactor(),
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: randomScalingFactor(),
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: randomScalingFactor(),
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: randomScalingFactor(),
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}
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);
};
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPie = new Chart(ctx).Pie(pieData);
};
$('#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();
});
$('#randomizeData').click(function(){
$.each(pieData, function(i, piece){
pieData[i].value = randomScalingFactor();
pieData[i].color = '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>
</script>
</body>
</html>
+109 -60
Ver Arquivo
@@ -1,73 +1,122 @@
<!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:30%">
<canvas id="chart-area" width="300" height="300"/>
</div>
<button id="randomizeData">Randomize Data</button>
<head>
<title>Polar Area Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<script>
<body>
<div id="canvas-holder" style="width:75%">
<canvas id="chart-area"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
var config = {
data: {
datasets: [{
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
],
backgroundColor: [
"#F7464A",
"#46BFBD",
"#FDB45C",
"#949FB1",
"#4D5360",
],
label: 'My dataset' // for legend
}],
labels: [
"Red",
"Green",
"Yellow",
"Grey",
"Dark Grey"
]
},
options: {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Polar Area Chart'
},
scale: {
ticks: {
beginAtZero: true
},
reverse: false
},
animateRotate:false
}
};
var polarData = [
{
value: randomScalingFactor(),
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: randomScalingFactor(),
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: randomScalingFactor(),
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
},
{
value: randomScalingFactor(),
color: "#949FB1",
highlight: "#A8B3C5",
label: "Grey"
},
{
value: randomScalingFactor(),
color: "#4D5360",
highlight: "#616774",
label: "Dark Grey"
}
window.onload = function() {
var ctx = document.getElementById("chart-area");
window.myPolarArea = Chart.PolarArea(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[i].backgroundColor[j] = randomColor();
});
});
window.myPolarArea.update();
});
window.onload = function(){
var ctx = document.getElementById("chart-area").getContext("2d");
window.myPolarArea = new Chart(ctx).PolarArea(polarData, {
responsive:true
});
};
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
$('#randomizeData').click(function(){
$.each(polarData, function(i, piece){
polarData[i].value = randomScalingFactor();
polarData[i].color = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
});
window.myPolarArea.update();
});
$.each(config.data.datasets, function(i, dataset) {
dataset.backgroundColor.push(randomColor());
dataset.data.push(randomScalingFactor());
});
window.myPolarArea.update();
}
});
$('#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();
});
</script>
</body>
</script>
</body>
</html>
+145
Ver Arquivo
@@ -0,0 +1,145 @@
<!doctype html>
<html>
<head>
<title>Radar Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'radar',
data: {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "Skip first dataset",
borderColor: 'rgb(255, 0, 0)',
backgroundColor: "rgba(255,255,0,0.5)",
pointBackgroundColor: "rgba(220,220,220,1)",
data: [NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: "Skip mid dataset",
borderColor: 'rgb(255, 0, 255)',
backgroundColor: "rgba(0, 255, 0, 0.5)",
pointBackgroundColor: "rgba(151,187,205,1)",
hoverPointBackgroundColor: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), NaN, randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
},{
label: "Skip last dataset",
borderColor: 'rgb(0, 255, 255)',
backgroundColor: "rgba(0, 0, 255, 0.5)",
pointBackgroundColor: "rgba(151,187,205,1)",
hoverPointBackgroundColor: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), NaN]
}]
},
options: {
title:{
display:true,
text:"Chart.js Radar Chart - Skip Points"
},
elements: {
line: {
tension: 0.0,
}
},
scale: {
beginAtZero: true,
reverse: false
}
}
};
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
});
window.myRadar.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.myRadar.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
config.data.labels.push('dataset #' + config.data.labels.length);
$.each(config.data.datasets, function (i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myRadar.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.data.pop();
});
window.myRadar.update();
});
</script>
</body>
</html>
+127 -52
Ver Arquivo
@@ -1,64 +1,139 @@
<!doctype html>
<html>
<head>
<title>Radar Chart</title>
<script src="../Chart.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body>
<div style="width:30%">
<canvas id="canvas" height="450" width="450"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<head>
<title>Radar Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<script>
<body>
<div style="width:75%">
<canvas id="canvas"></canvas>
</div>
<button id="randomizeData">Randomize Data</button>
<button id="addDataset">Add Dataset</button>
<button id="removeDataset">Remove Dataset</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<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 randomScalingFactor = function(){ return Math.round(Math.random()*100)};
var randomColorFactor = function(){ return Math.round(Math.random()*255)};
var config = {
type: 'radar',
data: {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(220,220,220,0.2)",
pointBackgroundColor: "rgba(220,220,220,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Hidden dataset',
hidden: true,
data: [randomScalingFactor(), 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: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
},]
},
options: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Radar Chart'
},
scale: {
reverse: false,
ticks: {
beginAtZero: true
}
}
}
};
var radarChartData = {
labels: ["Eating", "Drinking", "Sleeping", "Designing", "Coding", "Cycling", "Running"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
]
};
window.onload = function() {
window.myRadar = new Chart(document.getElementById("canvas"), config);
};
window.onload = function(){
window.myRadar = new Chart(document.getElementById("canvas").getContext("2d")).Radar(radarChartData, {
responsive: true
});
}
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
dataset.data = dataset.data.map(function() {
return randomScalingFactor();
});
$('#randomizeData').click(function(){
radarChartData.datasets[0].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
radarChartData.datasets[0].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
});
radarChartData.datasets[1].fillColor = 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.3)';
radarChartData.datasets[1].data = [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()];
window.myRadar.update();
window.myRadar.update();
});
</script>
</body>
$('#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();
});
$('#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();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myRadar.update();
});
$('#removeData').click(function() {
config.data.labels.pop(); // remove the label first
$.each(config.data.datasets, function(i, dataset) {
dataset.data.pop();
});
window.myRadar.update();
});
</script>
</body>
</html>
+185
Ver Arquivo
@@ -0,0 +1,185 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<div>
<canvas id="canvas"></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: {
title: {
display: true,
text: 'Chart.js Scatter Chart - Logarithmic X-Axis'
},
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom',
ticks: {
userCallback: function(tick) {
var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));
if (remain === 1 || remain === 2 || remain === 5) {
return tick.toString() + "Hz";
}
return '';
},
},
scaleLabel: {
labelString: 'Frequency',
display: true,
}
}],
yAxes: [{
type: 'linear',
ticks: {
userCallback: function(tick) {
return tick.toString() + "dB";
}
},
scaleLabel: {
labelString: 'Voltage',
display: true
}
}]
}
}
});
};
</script>
</body>
</html>
+186
Ver Arquivo
@@ -0,0 +1,186 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart Multi Axis</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<div>
<canvas id="canvas"></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;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
responsive: true,
hoverMode: 'single',
title: {
display: true,
text: 'Chart.js Scatter Chart - Multi Axis'
},
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>
+177
Ver Arquivo
@@ -0,0 +1,177 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<div>
<canvas id="canvas"></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;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart'
},
scales: {
xAxes: [{
position: 'top',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'x axis'
}
}],
yAxes: [{
position: 'right',
gridLines: {
zeroLineColor: "rgba(0,255,0,1)"
},
scaleLabel: {
display: true,
labelString: 'y axis'
}
}]
}
}
});
};
$('#randomizeData').click(function() {
scatterChartData.datasets[0].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}];
scatterChartData.datasets[1].data = [{
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}, {
x: randomScalingFactor(),
y: randomScalingFactor(),
}]
window.myScatter.update();
});
</script>
</body>
</html>
+165
Ver Arquivo
@@ -0,0 +1,165 @@
<!doctype html>
<html>
<head>
<title>Line Chart - Combo Time Scale</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 timeFormat = 'MM/DD/YYYY HH:mm';
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
var config = {
type: 'bar',
data: {
labels: [newDateString(0), newDateString(1), newDateString(2), newDateString(3), newDateString(4), newDateString(5), newDateString(6)],
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
borderColor: 'white',
borderWidth: 2
}, {
type: 'line',
label: 'Dataset 3',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, ]
},
options: {
showLines: true,
responsive: true,
title:{
display:true,
text:"Chart.js Combo Time Scale"
},
scales: {
xAxes: [{
type: "time",
display: true,
time: {
format: timeFormat,
// round: 'day'
}
}],
},
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
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(newDateString(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) {
config.data.datasets[datasetIndex].data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+164
Ver Arquivo
@@ -0,0 +1,164 @@
<!doctype html>
<html>
<head>
<title>Time Scale Point Data</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></canvas>
</div>
<br>
<br>
<button id="randomizeData">Randomize Data</button>
<button id="addData">Add Data</button>
<button id="removeData">Remove Data</button>
<script>
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDate(days) {
return moment().add(days, 'd').toDate();
}
function newDateString(days) {
return moment().add(days, 'd').format();
}
var config = {
type: 'line',
data: {
datasets: [{
label: "Dataset with string point data",
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(2),
y: randomScalingFactor()
}, {
x: newDateString(4),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}],
fill: false
}, {
label: "Dataset with date object point data",
data: [{
x: newDate(0),
y: randomScalingFactor()
}, {
x: newDate(2),
y: randomScalingFactor()
}, {
x: newDate(4),
y: randomScalingFactor()
}, {
x: newDate(5),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Time Point Data"
},
scales: {
xAxes: [{
type: "time",
display: true,
scaleLabel: {
display: true,
labelString: 'Date'
}
}, ],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'value'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
$('#randomizeData').click(function() {
$.each(config.data.datasets, function(i, dataset) {
$.each(dataset.data, function(j, dataObj) {
dataObj.y = randomScalingFactor();
});
});
window.myLine.update();
});
$('#addData').click(function() {
if (config.data.datasets.length > 0) {
var lastTime = myLine.scales['x-axis-0'].labelMoments[0].length ? myLine.scales['x-axis-0'].labelMoments[0][myLine.scales['x-axis-0'].labelMoments[0].length - 1] : moment();
var newTime = lastTime
.clone()
.add(1, 'day')
.format('MM/DD/YYYY HH:mm');
for (var index = 0; index < config.data.datasets.length; ++index) {
config.data.datasets[index].data.push({
x: newTime,
y: randomScalingFactor()
});
}
window.myLine.update();
}
});
$('#removeData').click(function() {
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
+198
Ver Arquivo
@@ -0,0 +1,198 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 timeFormat = 'MM/DD/YYYY HH:mm';
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDate(days) {
return moment().add(days, 'd').toDate();
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
function newTimestamp(days) {
return moment().add(days, 'd').unix();
}
var config = {
type: 'line',
data: {
labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "Dataset with point data",
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}, {
x: newDateString(7),
y: randomScalingFactor()
}, {
x: newDateString(15),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Time Scale"
},
scales: {
xAxes: [{
type: "time",
time: {
format: timeFormat,
// round: 'day'
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
}
}, ],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
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) {
$.each(dataset.data, function(j, dataObj) {
if (typeof dataObj === 'object') {
dataObj.y = randomScalingFactor();
} else {
dataset.data[j] = 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(newDate(config.data.labels.length));
for (var index = 0; index < config.data.datasets.length; ++index) {
if (typeof config.data.datasets[index].data[0] === "object") {
config.data.datasets[index].data.push({
x: newDate(config.data.datasets[index].data.length),
y: randomScalingFactor(),
});
} else {
config.data.datasets[index].data.push(randomScalingFactor());
}
}
window.myLine.update();
}
});
$('#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>
+183
Ver Arquivo
@@ -0,0 +1,183 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="../dist/Chart.bundle.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<canvas id="canvas"></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 MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
};
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Line Chart - Tooltip Hooks"
},
tooltips: {
mode: 'label',
callbacks: {
beforeTitle: function() {
return '...beforeTitle';
},
afterTitle: function() {
return '...afterTitle';
},
beforeBody: function() {
return '...beforeBody';
},
afterBody: function() {
return '...afterBody';
},
beforeFooter: function() {
return '...beforeFooter';
},
footer: function() {
return 'Footer';
},
afterFooter: function() {
return '...afterFooter';
},
}
},
hover: {
mode: 'label'
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Month'
}
}],
yAxes: [{
display: true,
scaleLabel: {
show: true,
labelString: 'Value'
}
}]
}
}
};
$.each(config.data.datasets, function(i, dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
$('#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) {
var month = MONTHS[config.data.labels.length % MONTHS.length];
config.data.labels.push(month);
$.each(config.data.datasets, function(i, dataset) {
dataset.data.push(randomScalingFactor());
});
window.myLine.update();
}
});
$('#removeDataset').click(function() {
config.data.datasets.splice(0, 1);
window.myLine.update();
});
$('#removeData').click(function() {
config.data.labels.splice(-1, 1); // remove the label first
config.data.datasets.forEach(function(dataset, datasetIndex) {
dataset.data.pop();
});
window.myLine.update();
});
</script>
</body>
</html>
-329
Ver Arquivo
@@ -1,329 +0,0 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
scaleBeginAtZero : true,
//Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
//Number - Spacing between data sets within X values
barDatasetSpacing : 1,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
};
Chart.Type.extend({
name: "Bar",
defaults : defaultConfig,
initialize: function(data){
// Save data as a source for updating of values & methods
this.data = data;
//Expose options as a scope variable here so we can access it in the ScaleClass
var options = this.options;
this.ScaleClass = Chart.Scale.extend({
offsetGridLines : true,
calculateBarX : function(datasetCount, datasetIndex, barIndex){
//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
var xWidth = this.calculateBaseWidth(),
xAbsolute = this.calculateX(barIndex) - (xWidth/2),
barWidth = this.calculateBarWidth(datasetCount);
return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
},
calculateBaseWidth : function(){
return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
},
calculateBarWidth : function(datasetCount){
//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
return (baseWidth / datasetCount);
}
});
this.datasets = [];
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
this.eachBars(function(bar){
bar.restore(['fillColor', 'strokeColor']);
});
helpers.each(activeBars, function(activeBar){
activeBar.fillColor = activeBar.highlightFill;
activeBar.strokeColor = activeBar.highlightStroke;
});
this.showTooltip(activeBars);
});
}
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.BarClass = Chart.Rectangle.extend({
strokeWidth : this.options.barStrokeWidth,
showStroke : this.options.barShowStroke,
ctx : this.chart.ctx
});
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset,datasetIndex){
var datasetObject = {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
bars : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
datasetObject.bars.push(new this.BarClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.strokeColor,
fillColor : dataset.fillColor,
highlightFill : dataset.highlightFill || dataset.fillColor,
highlightStroke : dataset.highlightStroke || dataset.strokeColor
}));
},this);
},this);
this.buildScale(data.labels);
this.BarClass.prototype.base = this.scale.endPoint;
this.eachBars(function(bar, index, datasetIndex){
helpers.extend(bar, {
width : this.scale.calculateBarWidth(this.datasets.length),
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
y: this.scale.endPoint
});
bar.save();
}, this);
this.render();
},
update : function(){
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(this.data.datasets,function(dataset,datasetIndex){
helpers.extend(this.datasets[datasetIndex], {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
});
helpers.each(dataset.data,function(dataPoint,index){
helpers.extend(this.datasets[datasetIndex].bars[index], {
value : dataPoint,
label : this.data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.strokeColor,
fillColor : dataset.fillColor,
highlightFill : dataset.highlightFill || dataset.fillColor,
highlightStroke : dataset.highlightStroke || dataset.strokeColor
});
},this);
},this);
this.scale.update();
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor', 'strokeColor']);
});
this.eachBars(function(bar){
bar.save();
});
this.render();
},
eachBars : function(callback){
helpers.each(this.datasets,function(dataset, datasetIndex){
helpers.each(dataset.bars, callback, this, datasetIndex);
},this);
},
getBarsAtEvent : function(e){
var barsArray = [],
eventPosition = helpers.getRelativePosition(e),
datasetIterator = function(dataset){
barsArray.push(dataset.bars[barIndex]);
},
barIndex;
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
helpers.each(this.datasets, datasetIterator);
return barsArray;
}
}
}
return barsArray;
},
buildScale : function(labels){
var self = this;
var dataTotal = function(){
var values = [];
self.eachBars(function(bar){
values.push(bar.value);
});
return values;
};
var scaleOptions = {
templateString : this.options.scaleLabel,
height : this.chart.height,
width : this.chart.width,
ctx : this.chart.ctx,
textColor : this.options.scaleFontColor,
fontSize : this.options.scaleFontSize,
fontStyle : this.options.scaleFontStyle,
fontFamily : this.options.scaleFontFamily,
valuesCount : labels.length,
beginAtZero : this.options.scaleBeginAtZero,
integersOnly : this.options.scaleIntegersOnly,
calculateYRange: function(currentHeight){
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly
);
helpers.extend(this, updatedRanges);
},
xLabels : labels,
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth : this.options.scaleLineWidth,
lineColor : this.options.scaleLineColor,
showHorizontalLines : this.options.scaleShowHorizontalLines,
showVerticalLines : this.options.scaleShowVerticalLines,
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
showLabels : this.options.scaleShowLabels,
display : this.options.showScale
};
if (this.options.scaleOverride){
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new this.ScaleClass(scaleOptions);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
helpers.each(valuesArray,function(value,datasetIndex){
//Add a new point for each piece of data, passing any required data to draw.
this.datasets[datasetIndex].bars.push(new this.BarClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
y: this.scale.endPoint,
width : this.scale.calculateBarWidth(this.datasets.length),
base : this.scale.endPoint,
strokeColor : this.datasets[datasetIndex].strokeColor,
fillColor : this.datasets[datasetIndex].fillColor
}));
},this);
this.scale.addXLabel(label);
//Then re-render the chart.
this.update();
},
removeData : function(){
this.scale.removeXLabel();
//Then re-render the chart.
helpers.each(this.datasets,function(dataset){
dataset.bars.shift();
},this);
this.update();
},
reflow : function(){
helpers.extend(this.BarClass.prototype,{
y: this.scale.endPoint,
base : this.scale.endPoint
});
var newScaleProps = helpers.extend({
height : this.chart.height,
width : this.chart.width
});
this.scale.update(newScaleProps);
},
draw : function(ease){
var easingDecimal = ease || 1;
this.clear();
var ctx = this.chart.ctx;
this.scale.draw(easingDecimal);
//Draw all the bars for each dataset
helpers.each(this.datasets,function(dataset,datasetIndex){
helpers.each(dataset.bars,function(bar,index){
if (bar.hasValue()){
bar.base = this.scale.endPoint;
//Transition then draw
bar.transition({
x : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),
y : this.scale.calculateY(bar.value),
width : this.scale.calculateBarWidth(this.datasets.length)
}, easingDecimal).draw();
}
},this);
},this);
}
});
}).call(this);
-2201
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
-212
Ver Arquivo
@@ -1,212 +0,0 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Whether we should show a stroke on each segment
segmentShowStroke : true,
//String - The colour of each segment stroke
segmentStrokeColor : "#fff",
//Number - The width of each segment stroke
segmentStrokeWidth : 2,
//The percentage of the chart that we cut out of the middle.
percentageInnerCutout : 50,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect
animationEasing : "easeOutBounce",
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate : true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
Chart.Type.extend({
//Passing in a name registers this chart in the Chart namespace
name: "Doughnut",
//Providing a defaults will also register the deafults in the chart namespace
defaults : defaultConfig,
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
//Config is automatically merged by the core of Chart.js, and is available at this.options
initialize: function(data){
// Save data as a source for updating of values & methods
this.data = data;
//Declare segments as a static property to prevent inheriting across the Chart type prototype
this.segments = [];
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
this.SegmentArc = Chart.Arc.extend({
ctx : this.chart.ctx,
x : this.chart.width/2,
y : this.chart.height/2
});
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
helpers.each(this.segments,function(segment){
segment.restore(["fillColor"]);
});
helpers.each(activeSegments,function(activeSegment){
activeSegment.fillColor = activeSegment.highlightColor;
});
this.showTooltip(activeSegments);
});
}
this.calculateTotal(data);
helpers.each(data,function(datapoint, index){
if (!datapoint.color) {
datapoint.color = 'hsl(' + (360 * index / data.length) + ', 100%, 50%)';
}
this.addData(datapoint, index, true);
},this);
this.render();
},
getSegmentsAtEvent : function(e){
var segmentsArray = [];
var location = helpers.getRelativePosition(e);
helpers.each(this.segments,function(segment){
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
},this);
return segmentsArray;
},
addData : function(segment, atIndex, silent){
var index = atIndex || this.segments.length;
this.segments.splice(index, 0, new this.SegmentArc({
value : segment.value,
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
fillColor : segment.color,
highlightColor : segment.highlight || segment.color,
showStroke : this.options.segmentShowStroke,
strokeWidth : this.options.segmentStrokeWidth,
strokeColor : this.options.segmentStrokeColor,
startAngle : Math.PI * 1.5,
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
label : segment.label
}));
if (!silent){
this.reflow();
this.update();
}
},
calculateCircumference : function(value) {
if ( this.total > 0 ) {
return (Math.PI*2)*(value / this.total);
} else {
return 0;
}
},
calculateTotal : function(data){
this.total = 0;
helpers.each(data,function(segment){
this.total += Math.abs(segment.value);
},this);
},
update : function(){
// Map new data to data points
if(this.data.length == this.segments.length){
helpers.each(this.data, function(segment, i){
helpers.extend(this.segments[i], {
value : segment.value,
fillColor : segment.color,
highlightColor : segment.highlight || segment.color,
showStroke : this.options.segmentShowStroke,
strokeWidth : this.options.segmentStrokeWidth,
strokeColor : this.options.segmentStrokeColor,
label : segment.label
});
}, this);
} else{
// Data size changed without properly inserting, just redraw the chart
this.initialize(this.data);
}
this.calculateTotal(this.segments);
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor']);
});
helpers.each(this.segments,function(segment){
segment.save();
});
this.render();
},
removeData: function(atIndex){
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
this.segments.splice(indexToDelete, 1);
this.reflow();
this.update();
},
reflow : function(){
helpers.extend(this.SegmentArc.prototype,{
x : this.chart.width/2,
y : this.chart.height/2
});
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
helpers.each(this.segments, function(segment){
segment.update({
outerRadius : this.outerRadius,
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
});
}, this);
},
draw : function(easeDecimal){
var animDecimal = (easeDecimal) ? easeDecimal : 1;
this.clear();
helpers.each(this.segments,function(segment,index){
segment.transition({
circumference : this.calculateCircumference(segment.value),
outerRadius : this.outerRadius,
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
},animDecimal);
segment.endAngle = segment.startAngle + segment.circumference;
segment.draw();
if (index === 0){
segment.startAngle = Math.PI * 1.5;
}
//Check to see if it's the last segment, if not get the next and update the start angle
if (index < this.segments.length-1){
this.segments[index+1].startAngle = segment.endAngle;
}
},this);
}
});
Chart.types.Doughnut.extend({
name : "Pie",
defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
});
}).call(this);
-408
Ver Arquivo
@@ -1,408 +0,0 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
var defaultConfig = {
///Boolean - Whether grid lines are shown across the chart
scaleShowGridLines : true,
//String - Colour of the grid lines
scaleGridLineColor : "rgba(0,0,0,.05)",
//Number - Width of the grid lines
scaleGridLineWidth : 1,
//Boolean - Whether to show horizontal lines (except X axis)
scaleShowHorizontalLines: true,
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - Whether the line is curved between points
bezierCurve : true,
//Number - Tension of the bezier curve between points
bezierCurveTension : 0.4,
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 4,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
//Boolean - Whether to horizontally center the label and point dot inside the grid
offsetGridLines : false
};
Chart.Type.extend({
name: "Line",
defaults : defaultConfig,
initialize: function(data){
// Save data as a source for updating of values & methods
this.data = data;
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.PointClass = Chart.Point.extend({
offsetGridLines : this.options.offsetGridLines,
strokeWidth : this.options.pointDotStrokeWidth,
radius : this.options.pointDotRadius,
display: this.options.pointDot,
hitDetectionRadius : this.options.pointHitDetectionRadius,
ctx : this.chart.ctx,
inRange : function(mouseX){
return (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));
}
});
this.datasets = [];
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
this.eachPoints(function(point){
point.restore(['fillColor', 'strokeColor']);
});
helpers.each(activePoints, function(activePoint){
activePoint.fillColor = activePoint.highlightFill;
activePoint.strokeColor = activePoint.highlightStroke;
});
this.showTooltip(activePoints);
});
}
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset){
var datasetObject = {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
points : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
datasetObject.points.push(new this.PointClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
}));
},this);
this.buildScale(data.labels);
this.eachPoints(function(point, index){
helpers.extend(point, {
x: this.scale.calculateX(index),
y: this.scale.endPoint
});
point.save();
}, this);
},this);
this.render();
},
update : function(){
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(this.data.datasets,function(dataset,datasetIndex){
helpers.extend(this.datasets[datasetIndex], {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
});
helpers.each(dataset.data,function(dataPoint,index){
helpers.extend(this.datasets[datasetIndex].points[index], {
value : dataPoint,
label : this.data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
});
},this);
},this);
this.scale.update();
// Reset any highlight colours before updating.
helpers.each(this.activeElements, function(activeElement){
activeElement.restore(['fillColor', 'strokeColor']);
});
this.eachPoints(function(point){
point.save();
});
this.render();
},
eachPoints : function(callback){
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,callback,this);
},this);
},
getPointsAtEvent : function(e){
var pointsArray = [],
eventPosition = helpers.getRelativePosition(e);
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,function(point){
if (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);
});
},this);
return pointsArray;
},
buildScale : function(labels){
var self = this;
var dataTotal = function(){
var values = [];
self.eachPoints(function(point){
values.push(point.value);
});
return values;
};
var scaleOptions = {
templateString : this.options.scaleLabel,
height : this.chart.height,
width : this.chart.width,
ctx : this.chart.ctx,
textColor : this.options.scaleFontColor,
offsetGridLines : this.options.offsetGridLines,
fontSize : this.options.scaleFontSize,
fontStyle : this.options.scaleFontStyle,
fontFamily : this.options.scaleFontFamily,
valuesCount : labels.length,
beginAtZero : this.options.scaleBeginAtZero,
integersOnly : this.options.scaleIntegersOnly,
calculateYRange : function(currentHeight){
var updatedRanges = helpers.calculateScaleRange(
dataTotal(),
currentHeight,
this.fontSize,
this.beginAtZero,
this.integersOnly
);
helpers.extend(this, updatedRanges);
},
xLabels : labels,
font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
lineWidth : this.options.scaleLineWidth,
lineColor : this.options.scaleLineColor,
showHorizontalLines : this.options.scaleShowHorizontalLines,
showVerticalLines : this.options.scaleShowVerticalLines,
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,
showLabels : this.options.scaleShowLabels,
display : this.options.showScale
};
if (this.options.scaleOverride){
helpers.extend(scaleOptions, {
calculateYRange: helpers.noop,
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
});
}
this.scale = new Chart.Scale(scaleOptions);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
helpers.each(valuesArray,function(value,datasetIndex){
//Add a new point for each piece of data, passing any required data to draw.
this.datasets[datasetIndex].points.push(new this.PointClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: this.scale.calculateX(this.scale.valuesCount+1),
y: this.scale.endPoint,
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
fillColor : this.datasets[datasetIndex].pointColor
}));
},this);
this.scale.addXLabel(label);
//Then re-render the chart.
this.update();
},
removeData : function(){
this.scale.removeXLabel();
//Then re-render the chart.
helpers.each(this.datasets,function(dataset){
dataset.points.shift();
},this);
this.update();
},
reflow : function(){
var newScaleProps = helpers.extend({
height : this.chart.height,
width : this.chart.width
});
this.scale.update(newScaleProps);
},
draw : function(ease){
var easingDecimal = ease || 1;
this.clear();
var ctx = this.chart.ctx;
// Some helper methods for getting the next/prev points
var hasValue = function(item){
return item.value !== null;
},
nextPoint = function(point, collection, index){
return helpers.findNextWhere(collection, hasValue, index) || point;
},
previousPoint = function(point, collection, index){
return helpers.findPreviousWhere(collection, hasValue, index) || point;
};
this.scale.draw(easingDecimal);
helpers.each(this.datasets,function(dataset){
var pointsWithValues = helpers.where(dataset.points, hasValue);
//Transition each point first so that the line and point drawing isn't out of sync
//We can use this extra loop to calculate the control points of this dataset also in this loop
helpers.each(dataset.points, function(point, index){
if (point.hasValue()){
point.transition({
y : this.scale.calculateY(point.value),
x : this.scale.calculateX(index)
}, easingDecimal);
}
},this);
// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point
// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed
if (this.options.bezierCurve){
helpers.each(pointsWithValues, function(point, index){
var tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;
point.controlPoints = helpers.splineCurve(
previousPoint(point, pointsWithValues, index),
point,
nextPoint(point, pointsWithValues, index),
tension
);
// Prevent the bezier going outside of the bounds of the graph
// Cap puter bezier handles to the upper/lower scale bounds
if (point.controlPoints.outer.y > this.scale.endPoint){
point.controlPoints.outer.y = this.scale.endPoint;
}
else if (point.controlPoints.outer.y < this.scale.startPoint){
point.controlPoints.outer.y = this.scale.startPoint;
}
// Cap inner bezier handles to the upper/lower scale bounds
if (point.controlPoints.inner.y > this.scale.endPoint){
point.controlPoints.inner.y = this.scale.endPoint;
}
else if (point.controlPoints.inner.y < this.scale.startPoint){
point.controlPoints.inner.y = this.scale.startPoint;
}
},this);
}
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
helpers.each(pointsWithValues, function(point, index){
if (index === 0){
ctx.moveTo(point.x, point.y);
}
else{
if(this.options.bezierCurve){
var previous = previousPoint(point, pointsWithValues, index);
ctx.bezierCurveTo(
previous.controlPoints.outer.x,
previous.controlPoints.outer.y,
point.controlPoints.inner.x,
point.controlPoints.inner.y,
point.x,
point.y
);
}
else{
ctx.lineTo(point.x,point.y);
}
}
}, this);
ctx.stroke();
if (this.options.datasetFill && pointsWithValues.length > 0){
//Round off the line by going to the base of the chart, back to the start, then fill.
ctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);
ctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);
ctx.fillStyle = dataset.fillColor;
ctx.closePath();
ctx.fill();
}
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
helpers.each(pointsWithValues,function(point){
point.draw();
});
},this);
}
});
}).call(this);
-269
Ver Arquivo
@@ -1,269 +0,0 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
//Cache a local reference to Chart.helpers
helpers = Chart.helpers;
var defaultConfig = {
//Boolean - Show a backdrop to the scale label
scaleShowLabelBackdrop : true,
//String - The colour of the label backdrop
scaleBackdropColor : "rgba(255,255,255,0.75)",
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//Number - The backdrop padding above & below the label in pixels
scaleBackdropPaddingY : 2,
//Number - The backdrop padding to the side of the label in pixels
scaleBackdropPaddingX : 2,
//Boolean - Show line for each value in the scale
scaleShowLine : true,
//Boolean - Stroke a line around each segment in the chart
segmentShowStroke : true,
//String - The colour of the stroke on each segment.
segmentStrokeColor : "#fff",
//Number - The width of the stroke value in pixels
segmentStrokeWidth : 2,
//Number - Amount of animation steps
animationSteps : 100,
//String - Animation easing effect.
animationEasing : "easeOutBounce",
//Boolean - Whether to animate the rotation of the chart
animateRotate : true,
//Boolean - Whether to animate scaling the chart from the centre
animateScale : false,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
};
Chart.Type.extend({
//Passing in a name registers this chart in the Chart namespace
name: "PolarArea",
//Providing a defaults will also register the deafults in the chart namespace
defaults : defaultConfig,
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
//Config is automatically merged by the core of Chart.js, and is available at this.options
initialize: function(data){
// Save data as a source for updating of values & methods
this.data = data;
this.segments = [];
//Declare segment class as a chart instance specific class, so it can share props for this instance
this.SegmentArc = Chart.Arc.extend({
showStroke : this.options.segmentShowStroke,
strokeWidth : this.options.segmentStrokeWidth,
strokeColor : this.options.segmentStrokeColor,
ctx : this.chart.ctx,
innerRadius : 0,
x : this.chart.width/2,
y : this.chart.height/2
});
this.scale = new Chart.RadialScale({
display: this.options.showScale,
fontStyle: this.options.scaleFontStyle,
fontSize: this.options.scaleFontSize,
fontFamily: this.options.scaleFontFamily,
fontColor: this.options.scaleFontColor,
showLabels: this.options.scaleShowLabels,
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
backdropColor: this.options.scaleBackdropColor,
backdropPaddingY : this.options.scaleBackdropPaddingY,
backdropPaddingX: this.options.scaleBackdropPaddingX,
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
lineColor: this.options.scaleLineColor,
lineArc: true,
width: this.chart.width,
height: this.chart.height,
xCenter: this.chart.width/2,
yCenter: this.chart.height/2,
ctx : this.chart.ctx,
templateString: this.options.scaleLabel,
valuesCount: data.length
});
this.updateScaleRange(data);
this.scale.update();
helpers.each(data,function(segment,index){
this.addData(segment,index,true);
},this);
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
helpers.each(this.segments,function(segment){
segment.restore(["fillColor"]);
});
helpers.each(activeSegments,function(activeSegment){
activeSegment.fillColor = activeSegment.highlightColor;
});
this.showTooltip(activeSegments);
});
}
this.render();
},
getSegmentsAtEvent : function(e){
var segmentsArray = [];
var location = helpers.getRelativePosition(e);
helpers.each(this.segments,function(segment){
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
},this);
return segmentsArray;
},
addData : function(segment, atIndex, silent){
var index = atIndex || this.segments.length;
this.segments.splice(index, 0, new this.SegmentArc({
fillColor: segment.color,
highlightColor: segment.highlight || segment.color,
label: segment.label,
value: segment.value,
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
startAngle: Math.PI * 1.5
}));
if (!silent){
this.reflow();
this.update();
}
},
removeData: function(atIndex){
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
this.segments.splice(indexToDelete, 1);
this.reflow();
this.update();
},
calculateTotal: function(data){
this.total = 0;
helpers.each(data,function(segment){
this.total += segment.value;
},this);
this.scale.valuesCount = this.segments.length;
},
updateScaleRange: function(datapoints){
var valuesArray = [];
helpers.each(datapoints,function(segment){
valuesArray.push(segment.value);
});
var scaleSizes = (this.options.scaleOverride) ?
{
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
} :
helpers.calculateScaleRange(
valuesArray,
helpers.min([this.chart.width, this.chart.height])/2,
this.options.scaleFontSize,
this.options.scaleBeginAtZero,
this.options.scaleIntegersOnly
);
helpers.extend(
this.scale,
scaleSizes,
{
size: helpers.min([this.chart.width, this.chart.height]),
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
}
);
},
update : function(){
// Map new data to data points
if(this.data.length == this.segments.length){
helpers.each(this.data, function(segment, i){
helpers.extend(this.segments[i], {
fillColor: segment.color,
highlightColor: segment.highlight || segment.color,
label: segment.label,
value: segment.value,
});
},this);
} else{
// Data size changed without properly inserting, just redraw the chart
this.initialize(this.data);
}
this.calculateTotal(this.segments);
helpers.each(this.segments,function(segment){
segment.save();
});
this.reflow();
this.render();
},
reflow : function(){
helpers.extend(this.SegmentArc.prototype,{
x : this.chart.width/2,
y : this.chart.height/2
});
this.updateScaleRange(this.segments);
this.scale.update();
helpers.extend(this.scale,{
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
});
helpers.each(this.segments, function(segment){
segment.update({
outerRadius : this.scale.calculateCenterOffset(segment.value)
});
}, this);
},
draw : function(ease){
var easingDecimal = ease || 1;
//Clear & draw the canvas
this.clear();
helpers.each(this.segments,function(segment, index){
segment.transition({
circumference : this.scale.getCircumference(),
outerRadius : this.scale.calculateCenterOffset(segment.value)
},easingDecimal);
segment.endAngle = segment.startAngle + segment.circumference;
// If we've removed the first segment we need to set the first one to
// start at the top.
if (index === 0){
segment.startAngle = Math.PI * 1.5;
}
//Check to see if it's the last segment, if not get the next and update the start angle
if (index < this.segments.length - 1){
this.segments[index+1].startAngle = segment.endAngle;
}
segment.draw();
}, this);
this.scale.draw();
}
});
}).call(this);
-372
Ver Arquivo
@@ -1,372 +0,0 @@
(function(){
"use strict";
var root = this,
Chart = root.Chart,
helpers = Chart.helpers;
Chart.Type.extend({
name: "Radar",
defaults:{
//Boolean - Whether to show lines for each scale point
scaleShowLine : true,
//Boolean - Whether we show the angle lines out of the radar
angleShowLineOut : true,
//Boolean - Whether to show labels on the scale
scaleShowLabels : false,
// Boolean - Whether the scale should begin at zero
scaleBeginAtZero : true,
//String - Colour of the angle line
angleLineColor : "rgba(0,0,0,.1)",
//Number - Pixel width of the angle line
angleLineWidth : 1,
//String - Point label font declaration
pointLabelFontFamily : "'Arial'",
//String - Point label font weight
pointLabelFontStyle : "normal",
//Number - Point label font size in pixels
pointLabelFontSize : 10,
//String - Point label font colour
pointLabelFontColor : "#666",
//Boolean - Whether to show a dot for each point
pointDot : true,
//Number - Radius of each point dot in pixels
pointDotRadius : 3,
//Number - Pixel width of point dot stroke
pointDotStrokeWidth : 1,
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
pointHitDetectionRadius : 20,
//Boolean - Whether to show a stroke for datasets
datasetStroke : true,
//Number - Pixel width of dataset stroke
datasetStrokeWidth : 2,
//Boolean - Whether to fill the dataset with a colour
datasetFill : true,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].strokeColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
},
initialize: function(data){
// Save data as a source for updating of values & methods
this.data = data;
this.PointClass = Chart.Point.extend({
strokeWidth : this.options.pointDotStrokeWidth,
radius : this.options.pointDotRadius,
display: this.options.pointDot,
hitDetectionRadius : this.options.pointHitDetectionRadius,
ctx : this.chart.ctx
});
this.datasets = [];
this.buildScale(data);
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
var activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];
this.eachPoints(function(point){
point.restore(['fillColor', 'strokeColor']);
});
helpers.each(activePointsCollection, function(activePoint){
activePoint.fillColor = activePoint.highlightFill;
activePoint.strokeColor = activePoint.highlightStroke;
});
this.showTooltip(activePointsCollection);
});
}
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(data.datasets,function(dataset){
var datasetObject = {
label: dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
points : []
};
this.datasets.push(datasetObject);
helpers.each(dataset.data,function(dataPoint,index){
//Add a new point for each piece of data, passing any required data to draw.
var pointPosition;
if (!this.scale.animation){
pointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));
}
datasetObject.points.push(new this.PointClass({
value : dataPoint,
label : data.labels[index],
datasetLabel: dataset.label,
x: (this.options.animation) ? this.scale.xCenter : pointPosition.x,
y: (this.options.animation) ? this.scale.yCenter : pointPosition.y,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
}));
},this);
},this);
this.render();
},
eachPoints : function(callback){
helpers.each(this.datasets,function(dataset){
helpers.each(dataset.points,callback,this);
},this);
},
getPointsAtEvent : function(evt){
var mousePosition = helpers.getRelativePosition(evt),
fromCenter = helpers.getAngleFromPoint({
x: this.scale.xCenter,
y: this.scale.yCenter
}, mousePosition);
var anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,
pointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),
activePointsCollection = [];
// If we're at the top, make the pointIndex 0 to get the first of the array.
if (pointIndex >= this.scale.valuesCount || pointIndex < 0){
pointIndex = 0;
}
if (fromCenter.distance <= this.scale.drawingArea){
helpers.each(this.datasets, function(dataset){
activePointsCollection.push(dataset.points[pointIndex]);
});
}
return activePointsCollection;
},
buildScale : function(data){
this.scale = new Chart.RadialScale({
display: this.options.showScale,
fontStyle: this.options.scaleFontStyle,
fontSize: this.options.scaleFontSize,
fontFamily: this.options.scaleFontFamily,
fontColor: this.options.scaleFontColor,
showLabels: this.options.scaleShowLabels,
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
backdropColor: this.options.scaleBackdropColor,
backdropPaddingY : this.options.scaleBackdropPaddingY,
backdropPaddingX: this.options.scaleBackdropPaddingX,
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
lineColor: this.options.scaleLineColor,
angleLineColor : this.options.angleLineColor,
angleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,
// Point labels at the edge of each line
pointLabelFontColor : this.options.pointLabelFontColor,
pointLabelFontSize : this.options.pointLabelFontSize,
pointLabelFontFamily : this.options.pointLabelFontFamily,
pointLabelFontStyle : this.options.pointLabelFontStyle,
height : this.chart.height,
width: this.chart.width,
xCenter: this.chart.width/2,
yCenter: this.chart.height/2,
ctx : this.chart.ctx,
templateString: this.options.scaleLabel,
labels: data.labels,
valuesCount: data.datasets[0].data.length
});
this.scale.setScaleSize();
this.updateScaleRange(data.datasets);
this.scale.buildYLabels();
},
updateScaleRange: function(datasets){
var valuesArray = (function(){
var totalDataArray = [];
helpers.each(datasets,function(dataset){
if (dataset.data){
totalDataArray = totalDataArray.concat(dataset.data);
}
else {
helpers.each(dataset.points, function(point){
totalDataArray.push(point.value);
});
}
});
return totalDataArray;
})();
var scaleSizes = (this.options.scaleOverride) ?
{
steps: this.options.scaleSteps,
stepValue: this.options.scaleStepWidth,
min: this.options.scaleStartValue,
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
} :
helpers.calculateScaleRange(
valuesArray,
helpers.min([this.chart.width, this.chart.height])/2,
this.options.scaleFontSize,
this.options.scaleBeginAtZero,
this.options.scaleIntegersOnly
);
helpers.extend(
this.scale,
scaleSizes
);
},
addData : function(valuesArray,label){
//Map the values array for each of the datasets
this.scale.valuesCount++;
helpers.each(valuesArray,function(value,datasetIndex){
var pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));
this.datasets[datasetIndex].points.push(new this.PointClass({
value : value,
label : label,
datasetLabel: this.datasets[datasetIndex].label,
x: pointPosition.x,
y: pointPosition.y,
strokeColor : this.datasets[datasetIndex].pointStrokeColor,
fillColor : this.datasets[datasetIndex].pointColor
}));
},this);
this.scale.labels.push(label);
this.reflow();
this.update();
},
removeData : function(){
this.scale.valuesCount--;
this.scale.labels.shift();
helpers.each(this.datasets,function(dataset){
dataset.points.shift();
},this);
this.reflow();
this.update();
},
update : function(){
//Iterate through each of the datasets, and build this into a property of the chart
helpers.each(this.data.datasets,function(dataset,datasetIndex){
helpers.extend(this.datasets[datasetIndex], {
label : dataset.label || null,
fillColor : dataset.fillColor,
strokeColor : dataset.strokeColor,
pointColor : dataset.pointColor,
pointStrokeColor : dataset.pointStrokeColor,
});
helpers.each(dataset.data,function(dataPoint,index){
helpers.extend(this.datasets[datasetIndex].points[index], {
value : dataPoint,
label : this.data.labels[index],
datasetLabel: dataset.label,
strokeColor : dataset.pointStrokeColor,
fillColor : dataset.pointColor,
highlightFill : dataset.pointHighlightFill || dataset.pointColor,
highlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor
});
},this);
},this);
this.eachPoints(function(point){
point.save();
});
this.reflow();
this.render();
},
reflow: function(){
helpers.extend(this.scale, {
width : this.chart.width,
height: this.chart.height,
size : helpers.min([this.chart.width, this.chart.height]),
xCenter: this.chart.width/2,
yCenter: this.chart.height/2
});
this.updateScaleRange(this.datasets);
this.scale.setScaleSize();
this.scale.buildYLabels();
},
draw : function(ease){
var easeDecimal = ease || 1,
ctx = this.chart.ctx;
this.clear();
this.scale.draw();
helpers.each(this.datasets,function(dataset){
//Transition each point first so that the line and point drawing isn't out of sync
helpers.each(dataset.points,function(point,index){
if (point.hasValue()){
point.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);
}
},this);
//Draw the line between all the points
ctx.lineWidth = this.options.datasetStrokeWidth;
ctx.strokeStyle = dataset.strokeColor;
ctx.beginPath();
helpers.each(dataset.points,function(point,index){
if (index === 0){
ctx.moveTo(point.x,point.y);
}
else{
ctx.lineTo(point.x,point.y);
}
},this);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = dataset.fillColor;
ctx.fill();
//Now draw the points over the line
//A little inefficient double looping, but better than the line
//lagging behind the point positions
helpers.each(dataset.points,function(point){
if (point.hasValue()){
point.draw();
}
});
},this);
}
});
}).call(this);
+52
Ver Arquivo
@@ -0,0 +1,52 @@
/*!
* 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
*/
var Chart = require('./core/core.js')();
require('./core/core.helpers')(Chart);
require('./core/core.element')(Chart);
require('./core/core.animation')(Chart);
require('./core/core.controller')(Chart);
require('./core/core.datasetController')(Chart);
require('./core/core.layoutService')(Chart);
require('./core/core.legend')(Chart);
require('./core/core.scale')(Chart);
require('./core/core.scaleService')(Chart);
require('./core/core.title')(Chart);
require('./core/core.tooltip')(Chart);
require('./controllers/controller.bar')(Chart);
require('./controllers/controller.bubble')(Chart);
require('./controllers/controller.doughnut')(Chart);
require('./controllers/controller.line')(Chart);
require('./controllers/controller.polarArea')(Chart);
require('./controllers/controller.radar')(Chart);
require('./scales/scale.category')(Chart);
require('./scales/scale.linear')(Chart);
require('./scales/scale.logarithmic')(Chart);
require('./scales/scale.radialLinear')(Chart);
require('./scales/scale.time')(Chart);
require('./elements/element.arc')(Chart);
require('./elements/element.line')(Chart);
require('./elements/element.point')(Chart);
require('./elements/element.rectangle')(Chart);
require('./charts/Chart.Bar')(Chart);
require('./charts/Chart.Bubble')(Chart);
require('./charts/Chart.Doughnut')(Chart);
require('./charts/Chart.Line')(Chart);
require('./charts/Chart.PolarArea')(Chart);
require('./charts/Chart.Radar')(Chart);
require('./charts/Chart.Scatter')(Chart);
window.Chart = module.exports = Chart;
+11
Ver Arquivo
@@ -0,0 +1,11 @@
"use strict";
module.exports = function(Chart) {
Chart.Bar = function(context, config) {
config.type = 'bar';
return new Chart(context, config);
};
};
+10
Ver Arquivo
@@ -0,0 +1,10 @@
"use strict";
module.exports = function(Chart) {
Chart.Bubble = function(context, config) {
config.type = 'bubble';
return new Chart(context, config);
};
};
+11
Ver Arquivo
@@ -0,0 +1,11 @@
"use strict";
module.exports = function(Chart) {
Chart.Doughnut = function(context, config) {
config.type = 'doughnut';
return new Chart(context, config);
};
};
+11
Ver Arquivo
@@ -0,0 +1,11 @@
"use strict";
module.exports = function(Chart) {
Chart.Line = function(context, config) {
config.type = 'line';
return new Chart(context, config);
};
};
+11
Ver Arquivo
@@ -0,0 +1,11 @@
"use strict";
module.exports = function(Chart) {
Chart.PolarArea = function(context, config) {
config.type = 'polarArea';
return new Chart(context, config);
};
};
+18
Ver Arquivo
@@ -0,0 +1,18 @@
"use strict";
module.exports = function(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);
};
};
+47
Ver Arquivo
@@ -0,0 +1,47 @@
"use strict";
module.exports = function(Chart) {
var defaultConfig = {
hover: {
mode: 'single'
},
scales: {
xAxes: [{
type: "linear", // scatter should not use a category axis
position: "bottom",
id: "x-axis-1" // need an ID so datasets can reference the scale
}],
yAxes: [{
type: "linear",
position: "left",
id: "y-axis-1"
}]
},
tooltips: {
callbacks: {
title: function(tooltipItems, data) {
// Title doesn't make sense for scatter since we format the data as a point
return '';
},
label: function(tooltipItem, data) {
return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
}
}
}
};
// Register the default config for this type
Chart.defaults.scatter = defaultConfig;
// Scatter charts use line controllers
Chart.controllers.scatter = Chart.controllers.line;
Chart.Scatter = function(context, config) {
config.type = 'scatter';
return new Chart(context, config);
};
};
+306
Ver Arquivo
@@ -0,0 +1,306 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.bar = {
hover: {
mode: "label"
},
scales: {
xAxes: [{
type: "category",
// Specific to Bar Controller
categoryPercentage: 0.8,
barPercentage: 0.9,
// grid line settings
gridLines: {
offsetGridLines: true
}
}],
yAxes: [{
type: "linear"
}]
}
};
Chart.controllers.bar = Chart.DatasetController.extend({
initialize: function(chart, datasetIndex) {
Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
// Use this to indicate that this is a bar dataset.
this.getDataset().bar = true;
},
// Get the number of datasets that display bars. We use this to correctly calculate the bar width
getBarCount: function getBarCount() {
var barCount = 0;
helpers.each(this.chart.data.datasets, function(dataset) {
if (helpers.isDatasetVisible(dataset) && dataset.bar) {
++barCount;
}
});
return barCount;
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var rectangle = new Chart.elements.Rectangle({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
var numBars = this.getBarCount();
this.updateElement(rectangle, index, true, numBars);
this.getDataset().metaData.splice(index, 0, rectangle);
},
update: function update(reset) {
var numBars = this.getBarCount();
helpers.each(this.getDataset().metaData, function(rectangle, index) {
this.updateElement(rectangle, index, reset, numBars);
}, this);
},
updateElement: function updateElement(rectangle, index, reset, numBars) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var yScalePoint;
if (yScale.min < 0 && yScale.max < 0) {
// all less than 0. use the top
yScalePoint = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
yScalePoint = yScale.getPixelForValue(yScale.min);
} else {
yScalePoint = yScale.getPixelForValue(0);
}
helpers.extend(rectangle, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: this.calculateBarX(index, this.index),
y: reset ? yScalePoint : this.calculateBarY(index, this.index),
// Tooltip
label: this.chart.data.labels[index],
datasetLabel: this.getDataset().label,
// Appearance
base: reset ? yScalePoint : 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),
borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped,
borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor),
borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth)
}
});
rectangle.pivot();
},
calculateBarBase: function(datasetIndex, index) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var base = 0;
if (yScale.options.stacked) {
var value = this.chart.data.datasets[datasetIndex].data[index];
if (value < 0) {
for (var i = 0; i < datasetIndex; i++) {
var negDS = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(negDS) && negDS.yAxisID === yScale.id && negDS.bar) {
base += negDS.data[index] < 0 ? negDS.data[index] : 0;
}
}
} else {
for (var j = 0; j < datasetIndex; j++) {
var posDS = this.chart.data.datasets[j];
if (helpers.isDatasetVisible(posDS) && posDS.yAxisID === yScale.id && posDS.bar) {
base += posDS.data[index] > 0 ? posDS.data[index] : 0;
}
}
}
return yScale.getPixelForValue(base);
}
base = yScale.getPixelForValue(yScale.min);
if (yScale.beginAtZero || ((yScale.min <= 0 && yScale.max >= 0) || (yScale.min >= 0 && yScale.max <= 0))) {
base = yScale.getPixelForValue(0, 0);
//base += yScale.options.gridLines.lineWidth;
} else if (yScale.min < 0 && yScale.max < 0) {
// All values are negative. Use the top as the base
base = yScale.getPixelForValue(yScale.max);
}
return base;
},
getRuler: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var datasetCount = this.getBarCount();
var tickWidth = (function() {
var min = xScale.getPixelForTick(1) - xScale.getPixelForTick(0);
for (var i = 2; i < this.getDataset().data.length; i++) {
min = Math.min(xScale.getPixelForTick(i) - xScale.getPixelForTick(i - 1), min);
}
return min;
}).call(this);
var categoryWidth = tickWidth * xScale.options.categoryPercentage;
var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
var fullBarWidth = categoryWidth / datasetCount;
var barWidth = fullBarWidth * xScale.options.barPercentage;
var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
return {
datasetCount: datasetCount,
tickWidth: tickWidth,
categoryWidth: categoryWidth,
categorySpacing: categorySpacing,
fullBarWidth: fullBarWidth,
barWidth: barWidth,
barSpacing: barSpacing
};
},
calculateBarWidth: function() {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var ruler = this.getRuler();
return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
},
// Get bar index from the given dataset index accounting for the fact that not all bars are visible
getBarIndex: function(datasetIndex) {
var barIndex = 0;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j]) && this.chart.data.datasets[j].bar) {
++barIndex;
}
}
return barIndex;
},
calculateBarX: function(index, datasetIndex) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var barIndex = this.getBarIndex(datasetIndex);
var ruler = this.getRuler();
var leftTick = xScale.getPixelForValue(null, index, datasetIndex, this.chart.isCombo);
leftTick -= this.chart.isCombo ? (ruler.tickWidth / 2) : 0;
if (xScale.options.stacked) {
return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
}
return leftTick +
(ruler.barWidth / 2) +
ruler.categorySpacing +
(ruler.barWidth * barIndex) +
(ruler.barSpacing / 2) +
(ruler.barSpacing * barIndex);
},
calculateBarY: function(index, datasetIndex) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var value = this.getDataset().data[index];
if (yScale.options.stacked) {
var sumPos = 0,
sumNeg = 0;
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
if (helpers.isDatasetVisible(ds) && ds.bar && ds.yAxisID === yScale.id) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
sumPos += ds.data[index] || 0;
}
}
}
if (value < 0) {
return yScale.getPixelForValue(sumNeg + value);
} else {
return yScale.getPixelForValue(sumPos + value);
}
return yScale.getPixelForValue(value);
}
return yScale.getPixelForValue(value);
},
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(rectangle, index) {
var d = this.getDataset().data[index];
if (d !== null && d !== undefined && !isNaN(d)) {
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);
}
});
};
+168
Ver Arquivo
@@ -0,0 +1,168 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.bubble = {
hover: {
mode: "single"
},
scales: {
xAxes: [{
type: "linear", // bubble should probably use a linear scale by default
position: "bottom",
id: "x-axis-0" // need an ID so datasets can reference the scale
}],
yAxes: [{
type: "linear",
position: "left",
id: "y-axis-0"
}]
},
tooltips: {
callbacks: {
title: function(tooltipItems, data) {
// Title doesn't make sense for scatter since we format the data as a point
return '';
},
label: function(tooltipItem, data) {
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
var dataPoint = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return datasetLabel + ': (' + dataPoint.x + ', ' + dataPoint.y + ', ' + dataPoint.r + ')';
}
}
}
};
Chart.controllers.bubble = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
},
update: function update(reset) {
var points = this.getDataset().metaData;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
helpers.extend(point, {
// Utility
_chart: this.chart.chart,
_xScale: xScale,
_yScale: yScale,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index),
// Appearance
radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]),
backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor),
borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor),
borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius)
}
});
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
point.pivot();
},
getRadius: function(value) {
return value.r || this.chart.options.elements.point.radius;
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition and Draw the Points
helpers.each(this.getDataset().metaData, function(point, index) {
point.transition(easingDecimal);
point.draw();
});
},
setHoverStyle: function(point) {
// Point
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]);
point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth);
},
removeHoverStyle: function(point) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]);
point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor);
point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor);
point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth);
}
});
};
+249
Ver Arquivo
@@ -0,0 +1,249 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.doughnut = {
animation: {
//Boolean - Whether we animate the rotation of the Doughnut
animateRotate: true,
//Boolean - Whether we animate scaling the Doughnut from the centre
animateScale: false
},
aspectRatio: 1,
hover: {
mode: 'single'
},
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
if (chart.data.datasets.length) {
for (var i = 0; i < chart.data.datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</span></li>');
}
}
text.push('</ul>');
return text.join("");
},
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
// Extra data used for toggling the correct item
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
this.chart.update();
}
},
//The percentage of the chart that we cut out of the middle.
cutoutPercentage: 50,
// Need to override these to give a nice default
tooltips: {
callbacks: {
title: function() {
return '';
},
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
}
}
}
};
Chart.defaults.pie = helpers.clone(Chart.defaults.doughnut);
helpers.extend(Chart.defaults.pie, {
cutoutPercentage: 0
});
Chart.controllers.doughnut = Chart.controllers.pie = Chart.DatasetController.extend({
linkScales: function() {
// no scales for doughnut
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index, colorForNewElement) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
if (colorForNewElement && helpers.isArray(this.getDataset().backgroundColor)) {
this.getDataset().backgroundColor.splice(index, 0, colorForNewElement);
}
// Reset the point
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) {
return helpers.isDatasetVisible(ds);
}).length;
},
// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
getRingIndex: function getRingIndex(datasetIndex) {
var ringIndex = 0;
for (var j = 0; j < datasetIndex; ++j) {
if (helpers.isDatasetVisible(this.chart.data.datasets[j])) {
++ringIndex;
}
}
return ringIndex;
},
update: function update(reset) {
var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top);
this.chart.outerRadius = Math.max((minSize / 2) - this.chart.options.elements.arc.borderWidth / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
if (!isNaN(value)) {
this.getDataset().total += Math.abs(value);
}
}, this);
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.getRingIndex(this.index));
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
updateElement: function(arc, index, reset) {
var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2;
var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2;
var startAngle = Math.PI * -0.5; // non reset case handled later
var endAngle = Math.PI * -0.5; // non reset case handled later
var circumference = reset && this.chart.options.animation.animateRotate ? 0 : this.calculateCircumference(this.getDataset().data[index]);
var innerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.innerRadius;
var outerRadius = reset && this.chart.options.animation.animateScale ? 0 : this.outerRadius;
helpers.extend(arc, {
// Utility
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
// Desired view properties
_model: {
x: centerX,
y: centerY,
startAngle: startAngle,
endAngle: endAngle,
circumference: circumference,
outerRadius: outerRadius,
innerRadius: 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])
}
});
// Set correct angles if not resetting
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;
}
arc.pivot();
},
draw: function(ease) {
var easingDecimal = ease || 1;
helpers.each(this.getDataset().metaData, function(arc, index) {
arc.transition(easingDecimal).draw();
});
},
setHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString());
arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, arc._model.borderWidth);
},
removeHoverStyle: function(arc) {
var dataset = this.chart.data.datasets[arc._datasetIndex];
var index = arc._index;
arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor);
arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor);
arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth);
},
calculateCircumference: function(value) {
if (this.getDataset().total > 0 && !isNaN(value)) {
return (Math.PI * 1.999999) * (value / this.getDataset().total);
} else {
return 0;
}
}
});
};
+290
Ver Arquivo
@@ -0,0 +1,290 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.line = {
showLines: true,
hover: {
mode: "label"
},
scales: {
xAxes: [{
type: "category",
id: 'x-axis-0'
}],
yAxes: [{
type: "linear",
id: 'y-axis-0'
}]
}
};
Chart.controllers.line = Chart.DatasetController.extend({
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0)
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
// Update Line
if (this.chart.options.showLines) {
// Utility
line._scale = yScale;
line._datasetIndex = this.index;
// Data
line._children = points;
// Model
line._model = {
// Appearance
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle),
borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash),
borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset),
borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle),
fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill),
// Scale
scaleTop: yScale.top,
scaleBottom: yScale.bottom,
scaleZero: scaleBase
};
line.pivot();
}
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0)
this.updateBezierControlPoints();
},
getPointBackgroundColor: function(point, index) {
var backgroundColor = this.chart.options.elements.point.backgroundColor;
var dataset = this.getDataset();
if (point.custom && point.custom.backgroundColor) {
backgroundColor = point.custom.backgroundColor;
} else if (dataset.pointBackgroundColor) {
backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor);
} else if (dataset.backgroundColor) {
backgroundColor = dataset.backgroundColor;
}
return backgroundColor;
},
getPointBorderColor: function(point, index) {
var borderColor = this.chart.options.elements.point.borderColor;
var dataset = this.getDataset();
if (point.custom && point.custom.borderColor) {
borderColor = point.custom.borderColor;
} else if (dataset.pointBorderColor) {
borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor);
} else if (dataset.borderColor) {
borderColor = dataset.borderColor;
}
return borderColor;
},
getPointBorderWidth: function(point, index) {
var borderWidth = this.chart.options.elements.point.borderWidth;
var dataset = this.getDataset();
if (point.custom && point.custom.borderWidth !== undefined) {
borderWidth = point.custom.borderWidth;
} else if (dataset.pointBorderWidth !== undefined) {
borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth);
} else if (dataset.borderWidth !== undefined) {
borderWidth = dataset.borderWidth;
}
return borderWidth;
},
updateElement: function(point, index, reset) {
var yScale = this.getScaleForId(this.getDataset().yAxisID);
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var scaleBase;
if (yScale.min < 0 && yScale.max < 0) {
scaleBase = yScale.getPixelForValue(yScale.max);
} else if (yScale.min > 0 && yScale.max > 0) {
scaleBase = yScale.getPixelForValue(yScale.min);
} else {
scaleBase = yScale.getPixelForValue(0);
}
// Utility
point._chart = this.chart.chart;
point._xScale = xScale;
point._yScale = yScale;
point._datasetIndex = this.index;
point._index = index;
// Desired view properties
point._model = {
x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo),
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius),
pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle),
backgroundColor: this.getPointBackgroundColor(point, index),
borderColor: this.getPointBorderColor(point, index),
borderWidth: this.getPointBorderWidth(point, index),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius)
};
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
calculatePointY: function(value, index, datasetIndex, isCombo) {
var xScale = this.getScaleForId(this.getDataset().xAxisID);
var yScale = this.getScaleForId(this.getDataset().yAxisID);
if (yScale.options.stacked) {
var sumPos = 0,
sumNeg = 0;
for (var i = 0; i < datasetIndex; i++) {
var ds = this.chart.data.datasets[i];
if (ds.type === 'line' && helpers.isDatasetVisible(ds)) {
if (ds.data[index] < 0) {
sumNeg += ds.data[index] || 0;
} else {
sumPos += ds.data[index] || 0;
}
}
}
if (value < 0) {
return yScale.getPixelForValue(sumNeg + value);
} else {
return yScale.getPixelForValue(sumPos + value);
}
}
return yScale.getPixelForValue(value);
},
updateBezierControlPoints: function() {
// Update bezier control points
helpers.each(this.getDataset().metaData, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index)._model,
point._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
// Now pivot the point for animation
point.pivot();
}, this);
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point) {
point.transition(easingDecimal);
});
// Transition and Draw the line
if (this.chart.options.showLines)
this.getDataset().metaDataset.transition(easingDecimal).draw();
// Draw the points
helpers.each(this.getDataset().metaData, function(point) {
point.draw();
});
},
setHoverStyle: function(point) {
// Point
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius);
point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(point._model.backgroundColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(point._model.borderColor).saturate(0.5).darken(0.1).rgbString());
point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth);
},
removeHoverStyle: function(point) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius);
point._model.backgroundColor = this.getPointBackgroundColor(point, index);
point._model.borderColor = this.getPointBorderColor(point, index);
point._model.borderWidth = this.getPointBorderWidth(point, index);
}
});
};
+236
Ver Arquivo
@@ -0,0 +1,236 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.polarArea = {
scale: {
type: "radialLinear",
lineArc: true // so that lines are circular
},
//Boolean - Whether to animate the rotation of the chart
animateRotate: true,
animateScale: true,
aspectRatio: 1,
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
if (chart.data.datasets.length) {
for (var i = 0; i < chart.data.datasets[0].data.length; ++i) {
text.push('<li><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</span></li>');
}
}
text.push('</ul>');
return text.join("");
},
legend: {
labels: {
generateLabels: function(data) {
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
return {
text: label,
fillStyle: data.datasets[0].backgroundColor[i],
hidden: isNaN(data.datasets[0].data[i]),
// Extra data used for toggling the correct item
index: i
};
});
} else {
return [];
}
}
},
onClick: function(e, legendItem) {
helpers.each(this.chart.data.datasets, function(dataset) {
dataset.metaHiddenData = dataset.metaHiddenData || [];
var idx = legendItem.index;
if (!isNaN(dataset.data[idx])) {
dataset.metaHiddenData[idx] = dataset.data[idx];
dataset.data[idx] = NaN;
} else if (!isNaN(dataset.metaHiddenData[idx])) {
dataset.data[idx] = dataset.metaHiddenData[idx];
}
});
this.chart.update();
}
},
// Need to override these to give a nice default
tooltips: {
callbacks: {
title: function() {
return '';
},
label: function(tooltipItem, data) {
return data.labels[tooltipItem.index] + ': ' + tooltipItem.yLabel;
}
}
}
};
Chart.controllers.polarArea = Chart.DatasetController.extend({
linkScales: function() {
// no scales for doughnut
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var arc = new Chart.elements.Arc({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
this.updateElement(arc, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, arc);
},
getVisibleDatasetCount: function getVisibleDatasetCount() {
return helpers.where(this.chart.data.datasets, function(ds) {
return helpers.isDatasetVisible(ds);
}).length;
},
update: function update(reset) {
var minSize = Math.min(this.chart.chartArea.right - this.chart.chartArea.left, this.chart.chartArea.bottom - this.chart.chartArea.top);
this.chart.outerRadius = Math.max((minSize - this.chart.options.elements.arc.borderWidth / 2) / 2, 0);
this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0);
this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.getVisibleDatasetCount();
this.getDataset().total = 0;
helpers.each(this.getDataset().data, function(value) {
this.getDataset().total += Math.abs(value);
}, this);
this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index);
this.innerRadius = this.outerRadius - this.chart.radiusLength;
helpers.each(this.getDataset().metaData, function(arc, index) {
this.updateElement(arc, index, reset);
}, this);
},
updateElement: function(arc, index, reset) {
var circumference = this.calculateCircumference(this.getDataset().data[index]);
var centerX = (this.chart.chartArea.left + this.chart.chartArea.right) / 2;
var centerY = (this.chart.chartArea.top + this.chart.chartArea.bottom) / 2;
// If there is NaN data before us, we need to calculate the starting angle correctly.
// We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
var notNullIndex = 0;
for (var i = 0; i < index; ++i) {
if (!isNaN(this.getDataset().data[i])) {
++notNullIndex;
}
}
var startAngle = (-0.5 * Math.PI) + (circumference * notNullIndex);
var endAngle = startAngle + circumference;
var resetModel = {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.options.animateScale ? 0 : this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : startAngle,
endAngle: this.chart.options.animateRotate ? Math.PI * -0.5 : endAngle,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth),
borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor),
label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index])
};
helpers.extend(arc, {
// Utility
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
_scale: this.chart.scale,
// Desired view properties
_model: reset ? resetModel : {
x: centerX,
y: centerY,
innerRadius: 0,
outerRadius: this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]),
startAngle: startAngle,
endAngle: endAngle,
backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor),
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();
});
},
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 (isNaN(value)) {
return 0;
} else {
// Count the number of NaN values
var numNaN = helpers.where(this.getDataset().data, function(data) {
return isNaN(data);
}).length;
return (2 * Math.PI) / (this.getDataset().data.length - numNaN);
}
}
});
};
+205
Ver Arquivo
@@ -0,0 +1,205 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.radar = {
scale: {
type: "radialLinear"
},
elements: {
line: {
tension: 0 // no bezier in radar
}
}
};
Chart.controllers.radar = Chart.DatasetController.extend({
linkScales: function() {
// No need. Single scale only
},
addElements: function() {
this.getDataset().metaData = this.getDataset().metaData || [];
this.getDataset().metaDataset = this.getDataset().metaDataset || new Chart.elements.Line({
_chart: this.chart.chart,
_datasetIndex: this.index,
_points: this.getDataset().metaData,
_loop: true
});
helpers.each(this.getDataset().data, function(value, index) {
this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index,
_model: {
x: 0, //xScale.getPixelForValue(null, index, true),
y: 0 //this.chartArea.bottom,
}
});
}, this);
},
addElementAndReset: function(index) {
this.getDataset().metaData = this.getDataset().metaData || [];
var point = new Chart.elements.Point({
_chart: this.chart.chart,
_datasetIndex: this.index,
_index: index
});
// Reset the point
this.updateElement(point, index, true);
// Add to the points array
this.getDataset().metaData.splice(index, 0, point);
// Make sure bezier control points are updated
this.updateBezierControlPoints();
},
update: function update(reset) {
var line = this.getDataset().metaDataset;
var points = this.getDataset().metaData;
var scale = this.chart.scale;
var scaleBase;
if (scale.min < 0 && scale.max < 0) {
scaleBase = scale.getPointPositionForValue(0, scale.max);
} else if (scale.min > 0 && scale.max > 0) {
scaleBase = scale.getPointPositionForValue(0, scale.min);
} else {
scaleBase = scale.getPointPositionForValue(0, 0);
}
helpers.extend(this.getDataset().metaDataset, {
// Utility
_datasetIndex: this.index,
// Data
_children: this.getDataset().metaData,
// Model
_model: {
// Appearance
tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill),
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),
// Scale
scaleTop: scale.top,
scaleBottom: scale.bottom,
scaleZero: scaleBase
}
});
this.getDataset().metaDataset.pivot();
// Update Points
helpers.each(points, function(point, index) {
this.updateElement(point, index, reset);
}, this);
// Update bezier control points
this.updateBezierControlPoints();
},
updateElement: function(point, index, reset) {
var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]);
helpers.extend(point, {
// Utility
_datasetIndex: this.index,
_index: index,
_scale: this.chart.scale,
// Desired view properties
_model: {
x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales
y: reset ? this.chart.scale.yCenter : pointPosition.y,
// Appearance
tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
radius: point.custom && point.custom.radius ? point.custom.radius : 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),
pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle),
// Tooltip
hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius)
}
});
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
},
updateBezierControlPoints: function() {
helpers.each(this.getDataset().metaData, function(point, index) {
var controlPoints = helpers.splineCurve(
helpers.previousItem(this.getDataset().metaData, index, true)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index, true)._model,
point._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left);
point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top);
// Now pivot the point for animation
point.pivot();
}, this);
},
draw: function(ease) {
var easingDecimal = ease || 1;
// Transition Point Locations
helpers.each(this.getDataset().metaData, function(point, index) {
point.transition(easingDecimal);
});
// 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);
}
});
};
+120
Ver Arquivo
@@ -0,0 +1,120 @@
/*global window: false */
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.animation = {
duration: 1000,
easing: "easeOutQuart",
onProgress: helpers.noop,
onComplete: helpers.noop
};
Chart.Animation = Chart.Element.extend({
currentStep: null, // the current animation step
numSteps: 60, // default number of steps
easing: "", // the easing to use for this animation
render: null, // render function used by the animation service
onAnimationProgress: null, // user specified callback to fire on each step of the animation
onAnimationComplete: null // user specified callback to fire when the animation finishes
});
Chart.animationService = {
frameDuration: 17,
animations: [],
dropFrames: 0,
addAnimation: function(chartInstance, animationObject, duration, lazy) {
if (!lazy) {
chartInstance.animating = true;
}
for (var index = 0; index < this.animations.length; ++index) {
if (this.animations[index].chartInstance === chartInstance) {
// replacing an in progress animation
this.animations[index].animationObject = animationObject;
return;
}
}
this.animations.push({
chartInstance: chartInstance,
animationObject: animationObject
});
// If there are no animations queued, manually kickstart a digest, for lack of a better word
if (this.animations.length === 1) {
helpers.requestAnimFrame.call(window, this.digestWrapper);
}
},
// Cancel the animation for a given chart instance
cancelAnimation: function(chartInstance) {
var index = helpers.findIndex(this.animations, function(animationWrapper) {
return animationWrapper.chartInstance === chartInstance;
});
if (index !== -1) {
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;
}
var i = 0;
while (i < this.animations.length) {
if (this.animations[i].animationObject.currentStep === null) {
this.animations[i].animationObject.currentStep = 0;
}
this.animations[i].animationObject.currentStep += 1 + framesToDrop;
if (this.animations[i].animationObject.currentStep > this.animations[i].animationObject.numSteps) {
this.animations[i].animationObject.currentStep = this.animations[i].animationObject.numSteps;
}
this.animations[i].animationObject.render(this.animations[i].chartInstance, this.animations[i].animationObject);
if (this.animations[i].animationObject.onAnimationProgress && this.animations[i].animationObject.onAnimationProgress.call) {
this.animations[i].animationObject.onAnimationProgress.call(this.animations[i].chartInstance, this.animations[i]);
}
if (this.animations[i].animationObject.currentStep === this.animations[i].animationObject.numSteps) {
if (this.animations[i].animationObject.onAnimationComplete && this.animations[i].animationObject.onAnimationComplete.call) {
this.animations[i].animationObject.onAnimationComplete.call(this.animations[i].chartInstance, this.animations[i]);
}
// executed the last frame. Remove the animation.
this.animations[i].chartInstance.animating = false;
this.animations.splice(i, 1);
} else {
++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);
}
}
};
};
+572
Ver Arquivo
@@ -0,0 +1,572 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
//Create a dictionary of chart types, to allow for extension of existing types
Chart.types = {};
//Store a reference to each instance - allowing us to globally resize chart instances on window resize.
//Destroy method on the chart will remove the instance of the chart from this reference.
Chart.instances = {};
// Controllers available for dataset visualization eg. bar, line, slice, etc.
Chart.controllers = {};
// The main controller of a chart
Chart.Controller = function(instance) {
this.chart = instance;
this.config = instance.config;
this.options = this.config.options = helpers.configMerge(Chart.defaults.global, Chart.defaults[this.config.type], this.config.options || {});
this.id = helpers.uid();
Object.defineProperty(this, 'data', {
get: function() {
return this.config.data;
}
});
//Add the chart instance to the global namespace
Chart.instances[this.id] = this;
if (this.options.responsive) {
// Silent resize before chart draws
this.resize(true);
}
this.initialize();
return this;
};
helpers.extend(Chart.Controller.prototype, {
initialize: function initialize() {
// TODO
// If BeforeInit(this) doesn't return false, proceed
this.bindEvents();
// Make sure controllers are built first so that each dataset is bound to an axis before the scales
// are built
this.ensureScalesHaveIDs();
this.buildOrUpdateControllers();
this.buildScales();
this.buildSurroundingItems();
this.updateLayout();
this.resetElements();
this.initToolTip();
this.update();
// TODO
// If AfterInit(this) doesn't return false, proceed
return this;
},
clear: function clear() {
helpers.clear(this.chart);
return this;
},
stop: function stop() {
// Stops any current animation loop occuring
Chart.animationService.cancelAnimation(this);
return this;
},
resize: function resize(silent) {
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);
var sizeChanged = this.chart.width !== newWidth || this.chart.height !== newHeight;
if (!sizeChanged)
return this;
canvas.width = this.chart.width = newWidth;
canvas.height = this.chart.height = newHeight;
helpers.retinaScale(this.chart);
if (!silent) {
this.stop();
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);
});
}
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);
});
}
}
},
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 xType = helpers.getValueOrDefault(xAxisOptions.type, 'category');
var ScaleClass = Chart.scaleService.getScaleConstructor(xType);
if (ScaleClass) {
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: xAxisOptions,
chart: this,
id: xAxisOptions.id
});
this.scales[scale.id] = scale;
}
}, this);
}
if (this.options.scales.yAxes && this.options.scales.yAxes.length) {
// Build the y axes
helpers.each(this.options.scales.yAxes, function(yAxisOptions, index) {
var yType = helpers.getValueOrDefault(yAxisOptions.type, 'linear');
var ScaleClass = Chart.scaleService.getScaleConstructor(yType);
if (ScaleClass) {
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: yAxisOptions,
chart: this,
id: yAxisOptions.id
});
this.scales[scale.id] = scale;
}
}, this);
}
}
if (this.options.scale) {
// Build radial axes
var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type);
if (ScaleClass) {
var scale = new ScaleClass({
ctx: this.chart.ctx,
options: this.options.scale,
chart: this
});
this.scale = scale;
this.scales.radialScale = scale;
}
}
Chart.scaleService.addScalesToLayout(this);
},
buildSurroundingItems: function() {
if (this.options.title) {
this.titleBlock = new Chart.Title({
ctx: this.chart.ctx,
options: this.options.title,
chart: this
});
Chart.layoutService.addBox(this, this.titleBlock);
}
if (this.options.legend) {
this.legend = new Chart.Legend({
ctx: this.chart.ctx,
options: this.options.legend,
chart: this
});
Chart.layoutService.addBox(this, this.legend);
}
},
updateLayout: function() {
Chart.layoutService.update(this, this.chart.width, this.chart.height);
},
buildOrUpdateControllers: function buildOrUpdateControllers() {
var types = [];
var newControllers = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (!dataset.type) {
dataset.type = this.config.type;
}
var type = dataset.type;
types.push(type);
if (dataset.controller) {
dataset.controller.updateIndex(datasetIndex);
} else {
dataset.controller = new Chart.controllers[type](this, datasetIndex);
newControllers.push(dataset.controller);
}
}, this);
if (types.length > 1) {
for (var i = 1; i < types.length; i++) {
if (types[i] !== types[i - 1]) {
this.isCombo = true;
break;
}
}
}
return newControllers;
},
resetElements: function resetElements() {
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.reset();
});
},
update: function update(animationDuration, lazy) {
// In case the entire data object changed
this.tooltip._data = this.data;
// Make sure dataset controllers are updated and new controllers are reset
var newControllers = this.buildOrUpdateControllers();
Chart.layoutService.update(this, this.chart.width, this.chart.height);
// Can only reset the new controllers after the scales have been updated
helpers.each(newControllers, function(controller) {
controller.reset();
});
// Make sure all dataset controllers have correct meta data counts
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
dataset.controller.buildOrUpdateElements();
});
// 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.render(animationDuration, lazy);
},
render: function render(duration, lazy) {
if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) {
var animation = new Chart.Animation();
animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps
animation.easing = this.options.animation.easing;
// render function
animation.render = function(chartInstance, animationObject) {
var easingFunction = helpers.easingEffects[animationObject.easing];
var stepDecimal = animationObject.currentStep / animationObject.numSteps;
var easeDecimal = easingFunction(stepDecimal);
chartInstance.draw(easeDecimal, stepDecimal, animationObject.currentStep);
};
// user events
animation.onAnimationProgress = this.options.animation.onProgress;
animation.onAnimationComplete = this.options.animation.onComplete;
Chart.animationService.addAnimation(this, animation, duration, lazy);
} else {
this.draw();
if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) {
this.options.animation.onComplete.call(this);
}
}
return this;
},
draw: function(ease) {
var easingDecimal = ease || 1;
this.clear();
// Draw all the scales
helpers.each(this.boxes, function(box) {
box.draw(this.chartArea);
}, this);
if (this.scale) {
this.scale.draw();
}
// Clip out the chart area so that anything outside does not draw. This is necessary for zoom and pan to function
this.chart.ctx.save();
this.chart.ctx.beginPath();
this.chart.ctx.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top);
this.chart.ctx.clip();
// Draw each dataset via its respective controller (reversed to support proper line stacking)
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
dataset.controller.draw(ease);
}
}, null, true);
// Restore from the clipping operation
this.chart.ctx.restore();
// Finally draw the tooltip
this.tooltip.transition(easingDecimal).draw();
},
// Get the single element that was clicked on
// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
getElementAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
if (helpers.isDatasetVisible(dataset)) {
helpers.each(dataset.metaData, function(element, index) {
if (element.inRange(eventPosition.x, eventPosition.y)) {
elementsArray.push(element);
return elementsArray;
}
});
}
});
return elementsArray;
},
getElementsAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
var found = (function() {
if (this.data.datasets) {
for (var i = 0; i < this.data.datasets.length; i++) {
if (helpers.isDatasetVisible(this.data.datasets[i])) {
for (var j = 0; j < this.data.datasets[i].metaData.length; j++) {
if (this.data.datasets[i].metaData[j].inRange(eventPosition.x, eventPosition.y)) {
return this.data.datasets[i].metaData[j];
}
}
}
}
}
}).call(this);
if (!found) {
return elementsArray;
}
helpers.each(this.data.datasets, function(dataset, dsIndex) {
if (helpers.isDatasetVisible(dataset)) {
elementsArray.push(dataset.metaData[found._index]);
}
});
return elementsArray;
},
getDatasetAtEvent: function(e) {
var elementsArray = this.getElementAtEvent(e);
if (elementsArray.length > 0) {
elementsArray = this.data.datasets[elementsArray[0]._datasetIndex].metaData;
}
return elementsArray;
},
generateLegend: function generateLegend() {
return this.options.legendCallback(this);
},
destroy: function destroy() {
this.clear();
helpers.unbindEvents(this, this.events);
helpers.removeResizeListener(this.chart.canvas.parentNode);
// Reset canvas height/width attributes
var canvas = this.chart.canvas;
canvas.width = this.chart.width;
canvas.height = this.chart.height;
// if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here
if (this.chart.originalDevicePixelRatio !== undefined) {
this.chart.ctx.scale(1 / this.chart.originalDevicePixelRatio, 1 / this.chart.originalDevicePixelRatio);
}
// Reset to the old style since it may have been changed by the device pixel ratio changes
canvas.style.width = this.chart.originalCanvasStyleWidth;
canvas.style.height = this.chart.originalCanvasStyleHeight;
delete Chart.instances[this.id];
},
toBase64Image: function toBase64Image() {
return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
},
initToolTip: function initToolTip() {
this.tooltip = new Chart.Tooltip({
_chart: this.chart,
_chartInstance: this,
_data: this.data,
_options: this.options
}, this);
},
bindEvents: function bindEvents() {
helpers.bindEvents(this, this.options.events, function(evt) {
this.eventHandler(evt);
});
},
eventHandler: function eventHandler(e) {
this.lastActive = this.lastActive || [];
this.lastTooltipActive = this.lastTooltipActive || [];
// Find Active Elements for hover and tooltips
if (e.type === 'mouseout') {
this.active = [];
this.tooltipActive = [];
} else {
var _this = this;
var getItemsForMode = function(mode) {
switch (mode) {
case 'single':
return _this.getElementAtEvent(e);
case 'label':
return _this.getElementsAtEvent(e);
case 'dataset':
return _this.getDatasetAtEvent(e);
default:
return e;
}
};
this.active = getItemsForMode(this.options.hover.mode);
this.tooltipActive = getItemsForMode(this.options.tooltips.mode);
}
// On Hover hook
if (this.options.hover.onHover) {
this.options.hover.onHover.call(this, this.active);
}
if (e.type === 'mouseup' || e.type === 'click') {
if (this.options.onClick) {
this.options.onClick.call(this, e, this.active);
}
if (this.legend && this.legend.handleEvent) {
this.legend.handleEvent(e);
}
}
var dataset;
var index;
// Remove styling for last active (even if it may still be active)
if (this.lastActive.length) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.lastActive[0]._datasetIndex].controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index);
break;
case 'label':
case 'dataset':
for (var i = 0; i < this.lastActive.length; i++) {
if (this.lastActive[i])
this.data.datasets[this.lastActive[i]._datasetIndex].controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index);
}
break;
default:
// Don't change anything
}
}
// Built in hover styling
if (this.active.length && this.options.hover.mode) {
switch (this.options.hover.mode) {
case 'single':
this.data.datasets[this.active[0]._datasetIndex].controller.setHoverStyle(this.active[0]);
break;
case 'label':
case 'dataset':
for (var j = 0; j < this.active.length; j++) {
if (this.active[j])
this.data.datasets[this.active[j]._datasetIndex].controller.setHoverStyle(this.active[j]);
}
break;
default:
// Don't change anything
}
}
// Built in Tooltips
if (this.options.tooltips.enabled || this.options.tooltips.custom) {
// The usual updates
this.tooltip.initialize();
this.tooltip._active = this.tooltipActive;
this.tooltip.update();
}
// Hover animations
this.tooltip.pivot();
if (!this.animating) {
var changed;
helpers.each(this.active, function(element, index) {
if (element !== this.lastActive[index]) {
changed = true;
}
}, this);
helpers.each(this.tooltipActive, function(element, index) {
if (element !== this.lastTooltipActive[index]) {
changed = true;
}
}, this);
// If entering, leaving, or changing elements, animate the change via pivot
if ((this.lastActive.length !== this.active.length) ||
(this.lastTooltipActive.length !== this.tooltipActive.length) ||
changed) {
this.stop();
if (this.options.tooltips.enabled || this.options.tooltips.custom) {
this.tooltip.update(true);
}
// We only need to render at this point. Updating will cause scales to be recomputed generating flicker & using more
// memory than necessary.
this.render(this.options.hover.animationDuration, true);
}
}
// Remember Last Actives
this.lastActive = this.active;
this.lastTooltipActive = this.tooltipActive;
return this;
}
});
};
+73
Ver Arquivo
@@ -0,0 +1,73 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
// Base class for all dataset controllers (line, bar, etc)
Chart.DatasetController = function(chart, datasetIndex) {
this.initialize.call(this, chart, datasetIndex);
};
helpers.extend(Chart.DatasetController.prototype, {
initialize: function(chart, datasetIndex) {
this.chart = chart;
this.index = datasetIndex;
this.linkScales();
this.addElements();
},
updateIndex: function(datasetIndex) {
this.index = datasetIndex;
},
linkScales: function() {
if (!this.getDataset().xAxisID) {
this.getDataset().xAxisID = this.chart.options.scales.xAxes[0].id;
}
if (!this.getDataset().yAxisID) {
this.getDataset().yAxisID = this.chart.options.scales.yAxes[0].id;
}
},
getDataset: function() {
return this.chart.data.datasets[this.index];
},
getScaleForId: function(scaleID) {
return this.chart.scales[scaleID];
},
reset: function() {
this.update(true);
},
buildOrUpdateElements: function buildOrUpdateElements() {
// Handle the number of data points changing
var numData = this.getDataset().data.length;
var numMetaData = this.getDataset().metaData.length;
// Make sure that we handle number of datapoints changing
if (numData < numMetaData) {
// Remove excess bars for data points that have been removed
this.getDataset().metaData.splice(numData, numMetaData - numData);
} else if (numData > numMetaData) {
// Add new elements
for (var index = numMetaData; index < numData; ++index) {
this.addElementAndReset(index);
}
}
},
// Controllers should implement the following
addElements: helpers.noop,
addElementAndReset: helpers.noop,
draw: helpers.noop,
removeHoverStyle: helpers.noop,
setHoverStyle: helpers.noop,
update: helpers.noop
});
Chart.DatasetController.extend = helpers.inherits;
};
+93
Ver Arquivo
@@ -0,0 +1,93 @@
"use strict";
module.exports = function(Chart) {
var 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);
}
// No animation -> No Transition
if (ease === 1) {
this._view = this._model;
this._start = null;
return this;
}
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.hasOwnProperty(key)) {
if (typeof value === 'number' && !isNaN(this._view[key])) {
this._view[key] = value * ease;
} else {
this._view[key] = value;
}
}
// No unnecessary computations
else if (value === this._view[key]) {
// It's the same! Woohoo!
}
// Color transitions if possible
else if (typeof value === 'string') {
try {
var color = helpers.color(this._start[key]).mix(helpers.color(this._model[key]), ease);
this._view[key] = color.rgbString();
} catch (err) {
this._view[key] = value;
}
}
// Number transitions
else if (typeof value === 'number') {
var startVal = this._start[key] !== undefined && isNaN(this._start[key]) === false ? this._start[key] : 0;
this._view[key] = ((this._model[key] - startVal) * ease) + startVal;
}
// Everything else
else {
this._view[key] = value;
}
}, this);
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;
};
+944
Ver Arquivo
@@ -0,0 +1,944 @@
/*global window: false */
/*global document: false */
"use strict";
var color = require('chartjs-color');
module.exports = function(Chart) {
//Global Chart helpers object for utility methods and classes
var helpers = Chart.helpers = {};
//-- Basic js utility methods
helpers.each = function(loopable, callback, self, reverse) {
// Check to see if null or undefined firstly.
var i, len;
if (helpers.isArray(loopable)) {
len = loopable.length;
if (reverse) {
for (i = len - 1; i >= 0; i--) {
callback.call(self, loopable[i], i);
}
} else {
for (i = 0; i < len; i++) {
callback.call(self, loopable[i], i);
}
}
} else if (typeof loopable === 'object') {
var keys = Object.keys(loopable);
len = keys.length;
for (i = 0; i < len; i++) {
callback.call(self, loopable[keys[i]], keys[i]);
}
}
};
helpers.clone = function(obj) {
var objClone = {};
helpers.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] = helpers.clone(value);
} else {
objClone[key] = value;
}
}
});
return objClone;
};
helpers.extend = function(base) {
var len = arguments.length;
var additionalArgs = [];
for (var i = 1; i < len; i++) {
additionalArgs.push(arguments[i]);
}
helpers.each(additionalArgs, function(extensionObject) {
helpers.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
helpers.configMerge = function(_base) {
var base = helpers.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;
};
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;
}
};
helpers.scaleMerge = function(_base, extension) {
var base = helpers.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) {
var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
var axisDefaults = Chart.scaleService.getScaleDefaults(axisType);
if (index >= base[key].length || !base[key][index].type) {
base[key].push(helpers.configMerge(axisDefaults, valueObj));
} else if (valueObj.type && 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], axisDefaults, valueObj);
} else {
// Type is the same
base[key][index] = helpers.configMerge(base[key][index], valueObj);
}
});
} else {
base[key] = [];
helpers.each(value, function(valueObj) {
var axisType = helpers.getValueOrDefault(valueObj.type, key === 'xAxes' ? 'category' : 'linear');
base[key].push(helpers.configMerge(Chart.scaleService.getScaleDefaults(axisType), 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;
};
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;
};
helpers.getValueOrDefault = function(value, defaultValue) {
return value === undefined ? defaultValue : value;
};
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;
}
};
helpers.where = function(collection, filterCallback) {
var filtered = [];
helpers.each(collection, function(item) {
if (filterCallback(item)) {
filtered.push(item);
}
});
return filtered;
};
helpers.findIndex = function(arrayToSearch, callback, thisArg) {
var index = -1;
if (Array.prototype.findIndex) {
index = arrayToSearch.findIndex(callback, thisArg);
} else {
for (var i = 0; i < arrayToSearch.length; ++i) {
thisArg = thisArg !== undefined ? thisArg : arrayToSearch;
if (callback.call(thisArg, arrayToSearch[i], i, arrayToSearch)) {
index = i;
break;
}
}
}
return index;
};
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;
}
}
};
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;
}
}
};
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 = helpers.inherits;
if (extensions) {
helpers.extend(ChartElement.prototype, extensions);
}
ChartElement.__super__ = parent.prototype;
return ChartElement;
};
helpers.noop = function() {};
helpers.uid = (function() {
var id = 0;
return function() {
return "chart-" + id++;
};
})();
helpers.warn = function(str) {
//Method for warning of errors
if (console && typeof console.warn === "function") {
console.warn(str);
}
};
//-- Math methods
helpers.isNumber = function(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
};
helpers.almostEquals = function(x, y, epsilon) {
return Math.abs(x - y) < epsilon;
};
helpers.max = function(array) {
return array.reduce(function(max, value) {
if (!isNaN(value)) {
return Math.max(max, value);
} else {
return max;
}
}, Number.NEGATIVE_INFINITY);
};
helpers.min = function(array) {
return array.reduce(function(min, value) {
if (!isNaN(value)) {
return Math.min(min, value);
} else {
return min;
}
}, Number.POSITIVE_INFINITY);
};
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;
}
};
helpers.log10 = function(x) {
if (Math.log10) {
return Math.log10(x);
} else {
return Math.log(x) / Math.LN10;
}
};
helpers.toRadians = function(degrees) {
return degrees * (Math.PI / 180);
};
helpers.toDegrees = function(radians) {
return radians * (180 / Math.PI);
};
// Gets the angle from vertical upright to the point about a centre.
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
};
};
helpers.aliasPixel = function(pixelWidth) {
return (pixelWidth % 2 === 0) ? 0 : 0.5;
};
helpers.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {
//Props to Rob Spencer at scaled innovation for his post on splining between points
//http://scaledinnovation.com/analytics/splines/aboutSplines.html
// This function must also respect "skipped" points
var previous = firstPoint.skip ? middlePoint : firstPoint,
current = middlePoint,
next = afterPoint.skip ? middlePoint : afterPoint;
var d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));
var d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));
var s01 = d01 / (d01 + d12);
var s12 = d12 / (d01 + d12);
// If all points are the same, s01 & s02 will be inf
s01 = isNaN(s01) ? 0 : s01;
s12 = isNaN(s12) ? 0 : s12;
var fa = t * s01; // scaling factor for triangle Ta
var fb = t * s12;
return {
previous: {
x: current.x - fa * (next.x - previous.x),
y: current.y - fa * (next.y - previous.y)
},
next: {
x: current.x + fb * (next.x - previous.x),
y: current.y + fb * (next.y - previous.y)
}
};
};
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];
};
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
helpers.niceNum = function(range, round) {
var exponent = Math.floor(helpers.log10(range));
var fraction = range / Math.pow(10, exponent);
var niceFraction;
if (round) {
if (fraction < 1.5) {
niceFraction = 1;
} else if (fraction < 3) {
niceFraction = 2;
} else if (fraction < 7) {
niceFraction = 5;
} else {
niceFraction = 10;
}
} else {
if (fraction <= 1.0) {
niceFraction = 1;
} else if (fraction <= 2) {
niceFraction = 2;
} else if (fraction <= 5) {
niceFraction = 5;
} else {
niceFraction = 10;
}
}
return niceFraction * Math.pow(10, exponent);
};
//Easing functions adapted from Robert Penner's easing equations
//http://www.robertpenner.com/easing/
var 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/
helpers.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
return window.setTimeout(callback, 1000 / 60);
};
})();
helpers.cancelAnimFrame = (function() {
return window.cancelAnimationFrame ||
window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
window.oCancelAnimationFrame ||
window.msCancelAnimationFrame ||
function(callback) {
return window.clearTimeout(callback, 1000 / 60);
};
})();
//-- DOM methods
helpers.getRelativePosition = function(evt, chart) {
var mouseX, mouseY;
var e = evt.originalEvent || evt,
canvas = evt.currentTarget || evt.srcElement,
boundingRect = canvas.getBoundingClientRect();
if (e.touches && e.touches.length > 0) {
mouseX = e.touches[0].clientX;
mouseY = e.touches[0].clientY;
} else {
mouseX = e.clientX;
mouseY = e.clientY;
}
// Scale mouse coordinates into canvas coordinates
// by following the pattern laid out by 'jerryj' in the comments of
// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
var paddingLeft = parseFloat(helpers.getStyle(canvas, 'padding-left'));
var paddingTop = parseFloat(helpers.getStyle(canvas, 'padding-top'));
var paddingRight = parseFloat(helpers.getStyle(canvas, 'padding-right'));
var paddingBottom = parseFloat(helpers.getStyle(canvas, 'padding-bottom'));
var width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;
var height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;
// 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 - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);
mouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);
return {
x: mouseX,
y: mouseY
};
};
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;
}
};
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] = helpers.noop;
}
};
helpers.bindEvents = function(chartInstance, arrayOfEvents, handler) {
// Create the events object if it's not already present
if (!chartInstance.events)
chartInstance.events = {};
helpers.each(arrayOfEvents, function(eventName) {
chartInstance.events[eventName] = function() {
handler.apply(chartInstance, arguments);
};
helpers.addEvent(chartInstance.chart.canvas, eventName, chartInstance.events[eventName]);
});
};
helpers.unbindEvents = function(chartInstance, arrayOfEvents) {
helpers.each(arrayOfEvents, function(handler, eventName) {
helpers.removeEvent(chartInstance.chart.canvas, eventName, handler);
});
};
// Private helper function to convert max-width/max-height values that may be percentages into a number
function parseMaxStyle(styleValue, node, parentProperty) {
var valueInPixels;
if (typeof(styleValue) === 'string') {
valueInPixels = parseInt(styleValue, 10);
if (styleValue.indexOf('%') != -1) {
// percentage * size in dimension
valueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];
}
} else {
valueInPixels = styleValue;
}
return valueInPixels;
}
// Private helper to get a constraint dimension
// @param domNode : the node to check the constraint on
// @param maxStyle : the style that defines the maximum for the direction we are using (max-width / max-height)
// @param percentageProperty : property of parent to use when calculating width as a percentage
function getConstraintDimension(domNode, maxStyle, percentageProperty) {
var constrainedDimension;
var constrainedNode = document.defaultView.getComputedStyle(domNode)[maxStyle];
var constrainedContainer = document.defaultView.getComputedStyle(domNode.parentNode)[maxStyle];
var hasCNode = constrainedNode !== null && constrainedNode !== "none";
var hasCContainer = constrainedContainer !== null && constrainedContainer !== "none";
if (hasCNode || hasCContainer) {
constrainedDimension = Math.min((hasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : Number.POSITIVE_INFINITY), (hasCContainer ? parseMaxStyle(constrainedContainer, domNode.parentNode, percentageProperty) : Number.POSITIVE_INFINITY));
}
return constrainedDimension;
}
// returns Number or undefined if no constraint
helpers.getConstraintWidth = function(domNode) {
return getConstraintDimension(domNode, 'max-width', 'clientWidth');
};
// returns Number or undefined if no constraint
helpers.getConstraintHeight = function(domNode) {
return getConstraintDimension(domNode, 'max-height', 'clientHeight');
};
helpers.getMaximumWidth = function(domNode) {
var container = domNode.parentNode;
var padding = parseInt(helpers.getStyle(container, 'padding-left')) + parseInt(helpers.getStyle(container, 'padding-right'));
var w = container.clientWidth - padding;
var cw = helpers.getConstraintWidth(domNode);
if (cw !== undefined) {
w = Math.min(w, cw);
}
return w;
};
helpers.getMaximumHeight = function(domNode) {
var container = domNode.parentNode;
var padding = parseInt(helpers.getStyle(container, 'padding-top')) + parseInt(helpers.getStyle(container, 'padding-bottom'));
var h = container.clientHeight - padding;
var ch = helpers.getConstraintHeight(domNode);
if (ch !== undefined) {
h = Math.min(h, ch);
}
return h;
};
helpers.getStyle = function(el, property) {
return el.currentStyle ?
el.currentStyle[property] :
document.defaultView.getComputedStyle(el, null).getPropertyValue(property);
};
helpers.retinaScale = function(chart) {
var ctx = chart.ctx;
var width = chart.canvas.width;
var height = chart.canvas.height;
var pixelRatio = chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
if (pixelRatio !== 1) {
ctx.canvas.height = height * pixelRatio;
ctx.canvas.width = width * pixelRatio;
ctx.scale(pixelRatio, pixelRatio);
// Store the device pixel ratio so that we can go backwards in `destroy`.
// The devicePixelRatio changes with zoom, so there are no guarantees that it is the same
// when destroy is called
chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || pixelRatio;
}
ctx.canvas.style.width = width + 'px';
ctx.canvas.style.height = height + 'px';
};
//-- Canvas methods
helpers.clear = function(chart) {
chart.ctx.clearRect(0, 0, chart.width, chart.height);
};
helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
return fontStyle + " " + pixelSize + "px " + fontFamily;
};
helpers.longestText = function(ctx, font, arrayOfStrings, cache) {
cache = cache || {};
cache.data = cache.data || {};
cache.garbageCollect = cache.garbageCollect || [];
if (cache.font !== font) {
cache.data = {};
cache.garbageCollect = [];
cache.font = font;
}
ctx.font = font;
var longest = 0;
helpers.each(arrayOfStrings, function(string) {
// Undefined strings should not be measured
if (string !== undefined && string !== null) {
var textWidth = cache.data[string];
if (!textWidth) {
textWidth = cache.data[string] = ctx.measureText(string).width;
cache.garbageCollect.push(string);
}
if (textWidth > longest) {
longest = textWidth;
}
}
});
var gcLen = cache.garbageCollect.length / 2;
if (gcLen > arrayOfStrings.length) {
for (var i = 0; i < gcLen; i++) {
delete cache.data[cache.garbageCollect[i]];
}
cache.garbageCollect.splice(0, gcLen);
}
return longest;
};
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();
};
helpers.color = function(c) {
if (!color) {
console.log('Color.js not found!');
return c;
}
return color(c);
};
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);
(hiddenIframe.contentWindow || hiddenIframe).onresize = function() {
if (callback) {
callback();
}
};
};
helpers.removeResizeListener = function(node) {
var hiddenIframe = node.querySelector('.chartjs-hidden-iframe');
// Remove the resize detect iframe
if (hiddenIframe) {
hiddenIframe.parentNode.removeChild(hiddenIframe);
}
};
helpers.isArray = function(obj) {
if (!Array.isArray) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
return Array.isArray(obj);
};
helpers.pushAllIfDefined = function(element, array) {
if (typeof element === "undefined") {
return;
}
if (helpers.isArray(element)) {
array.push.apply(array, element);
} else {
array.push(element);
}
};
helpers.isDatasetVisible = function(dataset) {
return !dataset.hidden;
};
helpers.callCallback = function(fn, args, _tArg) {
if (fn && typeof fn.call === 'function') {
fn.apply(_tArg, args);
}
};
};
Arquivo executável
+104
Ver Arquivo
@@ -0,0 +1,104 @@
"use strict";
module.exports = function() {
//Occupy the global variable of Chart, and create a simple base class
var Chart = function(context, config) {
this.config = config;
// Support a jQuery'd canvas element
if (context.length && context[0].getContext) {
context = context[0];
}
// Support a canvas domnode
if (context.getContext) {
context = context.getContext("2d");
}
this.ctx = context;
this.canvas = context.canvas;
// Figure out what the size of the chart will be.
// If the canvas has a specified width and height, we use those else
// we look to see if the canvas node has a CSS width and height.
// If there is still no height, fill the parent container
this.width = context.canvas.width || parseInt(Chart.helpers.getStyle(context.canvas, 'width')) || Chart.helpers.getMaximumWidth(context.canvas);
this.height = context.canvas.height || parseInt(Chart.helpers.getStyle(context.canvas, 'height')) || Chart.helpers.getMaximumHeight(context.canvas);
this.aspectRatio = this.width / this.height;
if (isNaN(this.aspectRatio) || isFinite(this.aspectRatio) === false) {
// If the canvas has no size, try and figure out what the aspect ratio will be.
// Some charts prefer square canvases (pie, radar, etc). If that is specified, use that
// else use the canvas default ratio of 2
this.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
}
// Store the original style of the element so we can set it back
this.originalCanvasStyleWidth = context.canvas.style.width;
this.originalCanvasStyleHeight = context.canvas.style.height;
// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
Chart.helpers.retinaScale(this);
if (config) {
this.controller = new Chart.Controller(this);
}
// Always bind this so that if the responsive state changes we still work
var _this = this;
Chart.helpers.addResizeListener(context.canvas.parentNode, function() {
if (_this.controller && _this.controller.config.options.responsive) {
_this.controller.resize();
}
});
return this.controller ? this.controller : this;
};
//Globally expose the defaults to allow for user updating/changing
Chart.defaults = {
global: {
responsive: true,
responsiveAnimationDuration: 0,
maintainAspectRatio: true,
events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"],
hover: {
onHover: null,
mode: 'single',
animationDuration: 400
},
onClick: null,
defaultColor: 'rgba(0,0,0,0.1)',
defaultFontColor: '#666',
defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
defaultFontSize: 12,
defaultFontStyle: 'normal',
showLines: true,
// Element defaults defined in element extensions
elements: {},
// Legend callback string
legendCallback: function(chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend">');
for (var i = 0; i < chart.data.datasets.length; i++) {
text.push('<li><span style="background-color:' + chart.data.datasets[i].backgroundColor + '">');
if (chart.data.datasets[i].label) {
text.push(chart.data.datasets[i].label);
}
text.push('</span></li>');
}
text.push('</ul>');
return text.join("");
}
}
};
return Chart;
};
+323
Ver Arquivo
@@ -0,0 +1,323 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
// The layout service is very self explanatory. It's responsible for the layout within a chart.
// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need
// It is this service's responsibility of carrying out that layout.
Chart.layoutService = {
defaults: {},
// Register a box to a chartInstance. A box is simply a reference to an object that requires layout. eg. Scales, Legend, Plugins.
addBox: function(chartInstance, box) {
if (!chartInstance.boxes) {
chartInstance.boxes = [];
}
chartInstance.boxes.push(box);
},
removeBox: function(chartInstance, box) {
if (!chartInstance.boxes) {
return;
}
chartInstance.boxes.splice(chartInstance.boxes.indexOf(box), 1);
},
// The most important function
update: function(chartInstance, width, height) {
if (!chartInstance) {
return;
}
var xPadding = 0;
var yPadding = 0;
var leftBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === "left";
});
var rightBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === "right";
});
var topBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === "top";
});
var bottomBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === "bottom";
});
// Boxes that overlay the chartarea such as the radialLinear scale
var chartAreaBoxes = helpers.where(chartInstance.boxes, function(box) {
return box.options.position === "chartArea";
});
function fullWidthSorter(a, b) {
}
// Ensure that full width boxes are at the very top / bottom
topBoxes.sort(function(a, b) {
return (b.options.fullWidth ? 1 : 0) - (a.options.fullWidth ? 1 : 0);
});
bottomBoxes.sort(function(a, b) {
return (a.options.fullWidth ? 1 : 0) - (b.options.fullWidth ? 1 : 0);
});
// Essentially we now have any number of boxes on each of the 4 sides.
// Our canvas looks like the following.
// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
// B1 is the bottom axis
// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays
// These locations are single-box locations only, when trying to register a chartArea location that is already taken,
// an error will be thrown.
//
// |----------------------------------------------------|
// | T1 (Full Width) |
// |----------------------------------------------------|
// | | | T2 | |
// | |----|-------------------------------------|----|
// | | | C1 | | C2 | |
// | | |----| |----| |
// | | | | |
// | L1 | L2 | ChartArea (C0) | R1 |
// | | | | |
// | | |----| |----| |
// | | | C3 | | C4 | |
// | |----|-------------------------------------|----|
// | | | B1 | |
// |----------------------------------------------------|
// | B2 (Full Width) |
// |----------------------------------------------------|
//
// What we do to find the best sizing, we do the following
// 1. Determine the minimum size of the chart area.
// 2. Split the remaining width equally between each vertical axis
// 3. Split the remaining height equally between each horizontal axis
// 4. Give each layout the maximum size it can be. The layout will return it's minimum size
// 5. Adjust the sizes of each axis based on it's minimum reported size.
// 6. Refit each axis
// 7. Position each axis in the final location
// 8. Tell the chart the final location of the chart area
// 9. Tell any axes that overlay the chart area the positions of the chart area
// Step 1
var chartWidth = width - (2 * xPadding);
var chartHeight = height - (2 * yPadding);
var chartAreaWidth = chartWidth / 2; // min 50%
var chartAreaHeight = chartHeight / 2; // min 50%
// Step 2
var verticalBoxWidth = (width - chartAreaWidth) / (leftBoxes.length + rightBoxes.length);
// Step 3
var horizontalBoxHeight = (height - chartAreaHeight) / (topBoxes.length + bottomBoxes.length);
// Step 4
var maxChartAreaWidth = chartWidth;
var maxChartAreaHeight = chartHeight;
var minBoxSizes = [];
helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
function getMinimumBoxSize(box) {
var minSize;
var isHorizontal = box.isHorizontal();
if (isHorizontal) {
minSize = box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
maxChartAreaHeight -= minSize.height;
} else {
minSize = box.update(verticalBoxWidth, chartAreaHeight);
maxChartAreaWidth -= minSize.width;
}
minBoxSizes.push({
horizontal: isHorizontal,
minSize: minSize,
box: box
});
}
// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
// be if the axes are drawn at their minimum sizes.
// Steps 5 & 6
var totalLeftBoxesWidth = xPadding;
var totalRightBoxesWidth = xPadding;
var totalTopBoxesHeight = yPadding;
var totalBottomBoxesHeight = yPadding;
// Update, and calculate the left and right margins for the horizontal boxes
helpers.each(leftBoxes.concat(rightBoxes), fitBox);
helpers.each(leftBoxes, function(box) {
totalLeftBoxesWidth += box.width;
});
helpers.each(rightBoxes, function(box) {
totalRightBoxesWidth += box.width;
});
// Set the Left and Right margins for the horizontal boxes
helpers.each(topBoxes.concat(bottomBoxes), fitBox);
// Function to fit a box
function fitBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
return minBoxSize.box === box;
});
if (minBoxSize) {
if (box.isHorizontal()) {
var scaleMargin = {
left: totalLeftBoxesWidth,
right: totalRightBoxesWidth,
top: 0,
bottom: 0
};
// Don't use min size here because of label rotation. When the labels are rotated, their rotation highly depends
// on the margin. Sometimes they need to increase in size slightly
box.update(box.options.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);
} else {
box.update(minBoxSize.minSize.width, maxChartAreaHeight);
}
}
}
// Figure out how much margin is on the top and bottom of the vertical boxes
helpers.each(topBoxes, function(box) {
totalTopBoxesHeight += box.height;
});
helpers.each(bottomBoxes, function(box) {
totalBottomBoxesHeight += box.height;
});
// Let the left layout know the final margin
helpers.each(leftBoxes.concat(rightBoxes), finalFitVerticalBox);
function finalFitVerticalBox(box) {
var minBoxSize = helpers.findNextWhere(minBoxSizes, function(minBoxSize) {
return minBoxSize.box === box;
});
var scaleMargin = {
left: 0,
right: 0,
top: totalTopBoxesHeight,
bottom: totalBottomBoxesHeight
};
if (minBoxSize) {
box.update(minBoxSize.minSize.width, maxChartAreaHeight, scaleMargin);
}
}
// Recalculate because the size of each layout might have changed slightly due to the margins (label rotation for instance)
totalLeftBoxesWidth = xPadding;
totalRightBoxesWidth = xPadding;
totalTopBoxesHeight = yPadding;
totalBottomBoxesHeight = yPadding;
helpers.each(leftBoxes, function(box) {
totalLeftBoxesWidth += box.width;
});
helpers.each(rightBoxes, function(box) {
totalRightBoxesWidth += box.width;
});
helpers.each(topBoxes, function(box) {
totalTopBoxesHeight += box.height;
});
helpers.each(bottomBoxes, function(box) {
totalBottomBoxesHeight += box.height;
});
// Figure out if our chart area changed. This would occur if the dataset layout label rotation
// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
// without calling `fit` again
var newMaxChartAreaHeight = height - totalTopBoxesHeight - totalBottomBoxesHeight;
var newMaxChartAreaWidth = width - totalLeftBoxesWidth - totalRightBoxesWidth;
if (newMaxChartAreaWidth !== maxChartAreaWidth || newMaxChartAreaHeight !== maxChartAreaHeight) {
helpers.each(leftBoxes, function(box) {
box.height = newMaxChartAreaHeight;
});
helpers.each(rightBoxes, function(box) {
box.height = newMaxChartAreaHeight;
});
helpers.each(topBoxes, function(box) {
box.width = newMaxChartAreaWidth;
});
helpers.each(bottomBoxes, function(box) {
box.width = newMaxChartAreaWidth;
});
maxChartAreaHeight = newMaxChartAreaHeight;
maxChartAreaWidth = newMaxChartAreaWidth;
}
// Step 7 - Position the boxes
var left = xPadding;
var top = yPadding;
var right = 0;
var bottom = 0;
helpers.each(leftBoxes.concat(topBoxes), placeBox);
// Account for chart width and height
left += maxChartAreaWidth;
top += maxChartAreaHeight;
helpers.each(rightBoxes, placeBox);
helpers.each(bottomBoxes, placeBox);
function placeBox(box) {
if (box.isHorizontal()) {
box.left = box.options.fullWidth ? xPadding : totalLeftBoxesWidth;
box.right = box.options.fullWidth ? width - xPadding : totalLeftBoxesWidth + maxChartAreaWidth;
box.top = top;
box.bottom = top + box.height;
// Move to next point
top = box.bottom;
} else {
box.left = left;
box.right = left + box.width;
box.top = totalTopBoxesHeight;
box.bottom = totalTopBoxesHeight + maxChartAreaHeight;
// Move to next point
left = box.right;
}
}
// Step 8
chartInstance.chartArea = {
left: totalLeftBoxesWidth,
top: totalTopBoxesHeight,
right: totalLeftBoxesWidth + maxChartAreaWidth,
bottom: totalTopBoxesHeight + maxChartAreaHeight
};
// Step 9
helpers.each(chartAreaBoxes, function(box) {
box.left = chartInstance.chartArea.left;
box.top = chartInstance.chartArea.top;
box.right = chartInstance.chartArea.right;
box.bottom = chartInstance.chartArea.bottom;
box.update(maxChartAreaWidth, maxChartAreaHeight);
});
}
};
};
+331
Ver Arquivo
@@ -0,0 +1,331 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.legend = {
display: true,
position: 'top',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
reverse: false,
// a callback that will handle
onClick: function(e, legendItem) {
var dataset = this.chart.data.datasets[legendItem.datasetIndex];
dataset.hidden = !dataset.hidden;
// We hid a dataset ... rerender the chart
this.chart.update();
},
labels: {
boxWidth: 40,
padding: 10,
// Generates labels shown in the legend
// Valid properties to return:
// text : text to display
// fillStyle : fill of coloured box
// strokeStyle: stroke of coloured box
// hidden : if this legend item refers to a hidden item
// lineCap : cap style for line
// lineDash
// lineDashOffset :
// lineJoin :
// lineWidth :
generateLabels: function(data) {
return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
return {
text: dataset.label,
fillStyle: dataset.backgroundColor,
hidden: dataset.hidden,
lineCap: dataset.borderCapStyle,
lineDash: dataset.borderDash,
lineDashOffset: dataset.borderDashOffset,
lineJoin: dataset.borderJoinStyle,
lineWidth: dataset.borderWidth,
strokeStyle: dataset.borderColor,
// Below is extra data used for toggling the datasets
datasetIndex: i
};
}, this) : [];
}
}
};
Chart.Legend = Chart.Element.extend({
initialize: function(config) {
helpers.extend(this, config);
// Contains hit boxes for each dataset (in dataset order)
this.legendHitBoxes = [];
// Are we in doughnut mode which has a different data type
this.doughnutMode = false;
},
// These methods are ordered by lifecyle. Utilities then follow.
// Any function defined here is inherited by all legend types.
// Any function can be extended by the legend type
beforeUpdate: helpers.noop,
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = margins;
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Labels
this.beforeBuildLabels();
this.buildLabels();
this.afterBuildLabels();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: helpers.noop,
//
beforeSetDimensions: helpers.noop,
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
// Reset minSize
this.minSize = {
width: 0,
height: 0
};
},
afterSetDimensions: helpers.noop,
//
beforeBuildLabels: helpers.noop,
buildLabels: function() {
this.legendItems = this.options.labels.generateLabels.call(this, this.chart.data);
if(this.options.reverse){
this.legendItems.reverse();
}
},
afterBuildLabels: helpers.noop,
//
beforeFit: helpers.noop,
fit: function() {
var ctx = this.ctx;
var fontSize = helpers.getValueOrDefault(this.options.labels.fontSize, Chart.defaults.global.defaultFontSize);
var fontStyle = helpers.getValueOrDefault(this.options.labels.fontStyle, Chart.defaults.global.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(this.options.labels.fontFamily, Chart.defaults.global.defaultFontFamily);
var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
// Reset hit boxes
this.legendHitBoxes = [];
// Width
if (this.isHorizontal()) {
this.minSize.width = this.maxWidth; // fill all the width
} else {
this.minSize.width = this.options.display ? 10 : 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.display ? 10 : 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Increase sizes here
if (this.options.display) {
if (this.isHorizontal()) {
// Labels
// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one
this.lineWidths = [0];
var totalHeight = this.legendItems.length ? fontSize + (this.options.labels.padding) : 0;
ctx.textAlign = "left";
ctx.textBaseline = 'top';
ctx.font = labelFont;
helpers.each(this.legendItems, function(legendItem, i) {
var width = this.options.labels.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
if (this.lineWidths[this.lineWidths.length - 1] + width + this.options.labels.padding >= this.width) {
totalHeight += fontSize + (this.options.labels.padding);
this.lineWidths[this.lineWidths.length] = this.left;
}
// Store the hitbox width and height here. Final position will be updated in `draw`
this.legendHitBoxes[i] = {
left: 0,
top: 0,
width: width,
height: fontSize
};
this.lineWidths[this.lineWidths.length - 1] += width + this.options.labels.padding;
}, this);
this.minSize.height += totalHeight;
} else {
// TODO vertical
}
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: helpers.noop,
// Shared Methods
isHorizontal: function() {
return this.options.position === "top" || this.options.position === "bottom";
},
// Actualy draw the legend on the canvas
draw: function() {
if (this.options.display) {
var ctx = this.ctx;
var cursor = {
x: this.left + ((this.width - this.lineWidths[0]) / 2),
y: this.top + this.options.labels.padding,
line: 0
};
var fontColor = helpers.getValueOrDefault(this.options.labels.fontColor, Chart.defaults.global.defaultFontColor);
var fontSize = helpers.getValueOrDefault(this.options.labels.fontSize, Chart.defaults.global.defaultFontSize);
var fontStyle = helpers.getValueOrDefault(this.options.labels.fontStyle, Chart.defaults.global.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(this.options.labels.fontFamily, Chart.defaults.global.defaultFontFamily);
var labelFont = helpers.fontString(fontSize, fontStyle, fontFamily);
// Horizontal
if (this.isHorizontal()) {
// Labels
ctx.textAlign = "left";
ctx.textBaseline = 'top';
ctx.lineWidth = 0.5;
ctx.strokeStyle = fontColor; // for strikethrough effect
ctx.fillStyle = fontColor; // render in correct colour
ctx.font = labelFont;
helpers.each(this.legendItems, function(legendItem, i) {
var textWidth = ctx.measureText(legendItem.text).width;
var width = this.options.labels.boxWidth + (fontSize / 2) + textWidth;
if (cursor.x + width >= this.width) {
cursor.y += fontSize + (this.options.labels.padding);
cursor.line++;
cursor.x = this.left + ((this.width - this.lineWidths[cursor.line]) / 2);
}
// Set the ctx for the box
ctx.save();
var itemOrDefault = function(item, defaulVal) {
return item !== undefined ? item : defaulVal;
};
ctx.fillStyle = itemOrDefault(legendItem.fillStyle, Chart.defaults.global.defaultColor);
ctx.lineCap = itemOrDefault(legendItem.lineCap, Chart.defaults.global.elements.line.borderCapStyle);
ctx.lineDashOffset = itemOrDefault(legendItem.lineDashOffset, Chart.defaults.global.elements.line.borderDashOffset);
ctx.lineJoin = itemOrDefault(legendItem.lineJoin, Chart.defaults.global.elements.line.borderJoinStyle);
ctx.lineWidth = itemOrDefault(legendItem.lineWidth, Chart.defaults.global.elements.line.borderWidth);
ctx.strokeStyle = itemOrDefault(legendItem.strokeStyle, Chart.defaults.global.defaultColor);
if (ctx.setLineDash) {
// IE 9 and 10 do not support line dash
ctx.setLineDash(itemOrDefault(legendItem.lineDash, Chart.defaults.global.elements.line.borderDash));
}
// Draw the box
ctx.strokeRect(cursor.x, cursor.y, this.options.labels.boxWidth, fontSize);
ctx.fillRect(cursor.x, cursor.y, this.options.labels.boxWidth, fontSize);
ctx.restore();
this.legendHitBoxes[i].left = cursor.x;
this.legendHitBoxes[i].top = cursor.y;
// Fill the actual label
ctx.fillText(legendItem.text, this.options.labels.boxWidth + (fontSize / 2) + cursor.x, cursor.y);
if (legendItem.hidden) {
// Strikethrough the text if hidden
ctx.beginPath();
ctx.lineWidth = 2;
ctx.moveTo(this.options.labels.boxWidth + (fontSize / 2) + cursor.x, cursor.y + (fontSize / 2));
ctx.lineTo(this.options.labels.boxWidth + (fontSize / 2) + cursor.x + textWidth, cursor.y + (fontSize / 2));
ctx.stroke();
}
cursor.x += width + (this.options.labels.padding);
}, this);
} else {
}
}
},
// Handle an event
handleEvent: function(e) {
var position = helpers.getRelativePosition(e, this.chart.chart);
if (position.x >= this.left && position.x <= this.right && position.y >= this.top && position.y <= this.bottom) {
// See if we are touching one of the dataset boxes
for (var i = 0; i < this.legendHitBoxes.length; ++i) {
var hitBox = this.legendHitBoxes[i];
if (position.x >= hitBox.left && position.x <= hitBox.left + hitBox.width && position.y >= hitBox.top && position.y <= hitBox.top + hitBox.height) {
// Touching an element
if (this.options.onClick) {
this.options.onClick.call(this, e, this.legendItems[i]);
}
break;
}
}
}
}
});
};
+685
Ver Arquivo
@@ -0,0 +1,685 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.scale = {
display: true,
// grid line settings
gridLines: {
display: true,
color: "rgba(0, 0, 0, 0.1)",
lineWidth: 1,
drawOnChartArea: true,
drawTicks: true,
zeroLineWidth: 1,
zeroLineColor: "rgba(0,0,0,0.25)",
offsetGridLines: false
},
// scale label
scaleLabel: {
// actual label
labelString: '',
// display property
display: false
},
// label settings
ticks: {
beginAtZero: false,
maxRotation: 90,
mirror: false,
padding: 10,
reverse: false,
display: true,
autoSkip: true,
autoSkipPadding: 20,
callback: function(value) {
return '' + value;
}
}
};
Chart.Scale = Chart.Element.extend({
// These methods are ordered by lifecyle. Utilities then follow.
// Any function defined here is inherited by all scale types.
// Any function can be extended by the scale type
beforeUpdate: function() {
helpers.callCallback(this.options.beforeUpdate, [this]);
},
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = helpers.extend({
left: 0,
right: 0,
top: 0,
bottom: 0
}, margins);
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Data min/max
this.beforeDataLimits();
this.determineDataLimits();
this.afterDataLimits();
// Ticks
this.beforeBuildTicks();
this.buildTicks();
this.afterBuildTicks();
this.beforeTickToLabelConversion();
this.convertTicksToLabels();
this.afterTickToLabelConversion();
// Tick Rotation
this.beforeCalculateTickRotation();
this.calculateTickRotation();
this.afterCalculateTickRotation();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: function() {
helpers.callCallback(this.options.afterUpdate, [this]);
},
//
beforeSetDimensions: function() {
helpers.callCallback(this.options.beforeSetDimensions, [this]);
},
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
},
afterSetDimensions: function() {
helpers.callCallback(this.options.afterSetDimensions, [this]);
},
// Data limits
beforeDataLimits: function() {
helpers.callCallback(this.options.beforeDataLimits, [this]);
},
determineDataLimits: helpers.noop,
afterDataLimits: function() {
helpers.callCallback(this.options.afterDataLimits, [this]);
},
//
beforeBuildTicks: function() {
helpers.callCallback(this.options.beforeBuildTicks, [this]);
},
buildTicks: helpers.noop,
afterBuildTicks: function() {
helpers.callCallback(this.options.afterBuildTicks, [this]);
},
beforeTickToLabelConversion: function() {
helpers.callCallback(this.options.beforeTickToLabelConversion, [this]);
},
convertTicksToLabels: function() {
// Convert ticks to strings
this.ticks = this.ticks.map(function(numericalTick, index, ticks) {
if (this.options.ticks.userCallback) {
return this.options.ticks.userCallback(numericalTick, index, ticks);
}
return this.options.ticks.callback(numericalTick, index, ticks);
},
this);
},
afterTickToLabelConversion: function() {
helpers.callCallback(this.options.afterTickToLabelConversion, [this]);
},
//
beforeCalculateTickRotation: function() {
helpers.callCallback(this.options.beforeCalculateTickRotation, [this]);
},
calculateTickRotation: function() {
//Get the width of each grid by calculating the difference
//between x offsets between 0 and 1.
var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
this.ctx.font = tickLabelFont;
var firstWidth = this.ctx.measureText(this.ticks[0]).width;
var lastWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width;
var firstRotated;
this.labelRotation = 0;
this.paddingRight = 0;
this.paddingLeft = 0;
if (this.options.display) {
if (this.isHorizontal()) {
this.paddingRight = lastWidth / 2 + 3;
this.paddingLeft = firstWidth / 2 + 3;
if (!this.longestTextCache) {
this.longestTextCache = {};
}
var originalLabelWidth = helpers.longestText(this.ctx, tickLabelFont, this.ticks, this.longestTextCache);
var labelWidth = originalLabelWidth;
var cosRotation;
var sinRotation;
// 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 (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;
// We're right aligning the text now.
if (firstRotated + tickFontSize / 2 > this.yLabelWidth) {
this.paddingLeft = firstRotated + tickFontSize / 2;
}
this.paddingRight = tickFontSize / 2;
if (sinRotation * originalLabelWidth > this.maxHeight) {
// go back one step
this.labelRotation--;
break;
}
this.labelRotation++;
labelWidth = cosRotation * originalLabelWidth;
}
}
}
if (this.margins) {
this.paddingLeft = Math.max(this.paddingLeft - this.margins.left, 0);
this.paddingRight = Math.max(this.paddingRight - this.margins.right, 0);
}
},
afterCalculateTickRotation: function() {
helpers.callCallback(this.options.afterCalculateTickRotation, [this]);
},
//
beforeFit: function() {
helpers.callCallback(this.options.beforeFit, [this]);
},
fit: function() {
this.minSize = {
width: 0,
height: 0
};
var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize);
var scaleLabelFontStyle = helpers.getValueOrDefault(this.options.scaleLabel.fontStyle, Chart.defaults.global.defaultFontStyle);
var scaleLabelFontFamily = helpers.getValueOrDefault(this.options.scaleLabel.fontFamily, Chart.defaults.global.defaultFontFamily);
var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);
// Width
if (this.isHorizontal()) {
// subtract the margins to line up with the chartArea if we are a full width scale
this.minSize.width = this.isFullWidth() ? this.maxWidth - this.margins.left - this.margins.right : this.maxWidth;
} else {
this.minSize.width = this.options.gridLines.display && this.options.display ? 10 : 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = this.options.gridLines.display && this.options.display ? 10 : 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Are we showing a title for the scale?
if (this.options.scaleLabel.display) {
if (this.isHorizontal()) {
this.minSize.height += (scaleLabelFontSize * 1.5);
} else {
this.minSize.width += (scaleLabelFontSize * 1.5);
}
}
if (this.options.ticks.display && this.options.display) {
// Don't bother fitting the ticks if we are not showing them
if (!this.longestTextCache) {
this.longestTextCache = {};
}
var largestTextWidth = helpers.longestText(this.ctx, tickLabelFont, this.ticks, this.longestTextCache);
if (this.isHorizontal()) {
// A horizontal axis is more constrained by the height.
this.longestLabelWidth = largestTextWidth;
// TODO - improve this calculation
var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * tickFontSize;
this.minSize.height = Math.min(this.maxHeight, this.minSize.height + labelHeight);
this.ctx.font = tickLabelFont;
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 * (tickFontSize / 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;
// Account for padding
if (!this.options.ticks.mirror) {
largestTextWidth += this.options.ticks.padding;
}
if (largestTextWidth < maxLabelWidth) {
// We don't need all the room
this.minSize.width += largestTextWidth;
} else {
// Expand to max size
this.minSize.width = this.maxWidth;
}
this.paddingTop = tickFontSize / 2;
this.paddingBottom = tickFontSize / 2;
}
}
if (this.margins) {
this.paddingLeft = Math.max(this.paddingLeft - this.margins.left, 0);
this.paddingTop = Math.max(this.paddingTop - this.margins.top, 0);
this.paddingRight = Math.max(this.paddingRight - this.margins.right, 0);
this.paddingBottom = Math.max(this.paddingBottom - this.margins.bottom, 0);
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: function() {
helpers.callCallback(this.options.afterFit, [this]);
},
// Shared Methods
isHorizontal: function() {
return this.options.position === "top" || this.options.position === "bottom";
},
isFullWidth: function() {
return (this.options.fullWidth);
},
// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
getRightValue: function getRightValue(rawValue) {
// Null and undefined values first
if (rawValue === null || typeof(rawValue) === 'undefined') {
return NaN;
}
// isNaN(object) returns true, so make sure NaN is checking for a number
if (typeof(rawValue) === 'number' && isNaN(rawValue)) {
return NaN;
}
// If it is in fact an object, dive in one more level
if (typeof(rawValue) === "object") {
if (rawValue instanceof Date) {
return rawValue;
} else {
return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
}
}
// Value is good, return it
return rawValue;
},
// Used to get the value to display in the tooltip for the data at the given index
// function getLabelForIndex(index, datasetIndex)
getLabelForIndex: helpers.noop,
// Used to get data value locations. Value can either be an index or a numerical value
getPixelForValue: helpers.noop,
// Used for tick location, should
getPixelForTick: function(index, includeOffset) {
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var tickWidth = innerWidth / Math.max((this.ticks.length - ((this.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var pixel = (tickWidth * index) + this.paddingLeft;
if (includeOffset) {
pixel += tickWidth / 2;
}
var finalVal = this.left + Math.round(pixel);
finalVal += this.isFullWidth() ? this.margins.left : 0;
return finalVal;
} else {
var innerHeight = this.height - (this.paddingTop + this.paddingBottom);
return this.top + (index * (innerHeight / (this.ticks.length - 1)));
}
},
// Utility for getting the pixel location of a percentage of scale
getPixelForDecimal: function(decimal /*, includeOffset*/ ) {
if (this.isHorizontal()) {
var innerWidth = this.width - (this.paddingLeft + this.paddingRight);
var valueOffset = (innerWidth * decimal) + this.paddingLeft;
var finalVal = this.left + Math.round(valueOffset);
finalVal += this.isFullWidth() ? this.margins.left : 0;
return finalVal;
} else {
return this.top + (decimal * this.height);
}
},
// Actualy draw the scale on the canvas
// @param {rectangle} chartArea : the area of the chart to draw full grid lines on
draw: function(chartArea) {
if (this.options.display) {
var setContextLineSettings;
var isRotated = this.labelRotation !== 0;
var skipRatio;
var scaleLabelX;
var scaleLabelY;
var useAutoskipper = this.options.ticks.autoSkip;
// figure out the maximum number of gridlines to show
var maxTicks;
if (this.options.ticks.maxTicksLimit) {
maxTicks = this.options.ticks.maxTicksLimit;
}
var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, Chart.defaults.global.defaultFontColor);
var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize);
var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
var scaleLabelFontColor = helpers.getValueOrDefault(this.options.scaleLabel.fontColor, Chart.defaults.global.defaultFontColor);
var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize);
var scaleLabelFontStyle = helpers.getValueOrDefault(this.options.scaleLabel.fontStyle, Chart.defaults.global.defaultFontStyle);
var scaleLabelFontFamily = helpers.getValueOrDefault(this.options.scaleLabel.fontFamily, Chart.defaults.global.defaultFontFamily);
var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);
var cosRotation = Math.cos(helpers.toRadians(this.labelRotation));
var sinRotation = Math.sin(helpers.toRadians(this.labelRotation));
var longestRotatedLabel = this.longestLabelWidth * cosRotation;
var rotatedLabelHeight = tickFontSize * sinRotation;
// Make sure we draw text in the correct color and font
this.ctx.fillStyle = tickFontColor;
if (this.isHorizontal()) {
setContextLineSettings = true;
var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - 10;
var yTickEnd = this.options.position === "bottom" ? this.top + 10 : this.bottom;
skipRatio = false;
if (((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) {
skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight)));
}
// if they defined a max number of ticks,
// increase skipRatio until that number is met
if (maxTicks && this.ticks.length > maxTicks) {
while (!skipRatio || this.ticks.length / (skipRatio || 1) > maxTicks) {
if (!skipRatio) {
skipRatio = 1;
}
skipRatio += 1;
}
}
if (!useAutoskipper) {
skipRatio = false;
}
helpers.each(this.ticks, function(label, index) {
// Blank ticks
var isLastTick = this.ticks.length === index + 1;
// Since we always show the last tick,we need may need to hide the last shown one before
var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio > this.ticks.length);
if (shouldSkip && !isLastTick || (label === undefined || label === null)) {
return;
}
var xLineValue = this.getPixelForTick(index); // xvalues for grid lines
var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option)
if (this.options.gridLines.display) {
if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) {
// Draw the first index specially
this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
setContextLineSettings = true; // reset next time
} else if (setContextLineSettings) {
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
setContextLineSettings = false;
}
xLineValue += helpers.aliasPixel(this.ctx.lineWidth);
// Draw the label area
this.ctx.beginPath();
if (this.options.gridLines.drawTicks) {
this.ctx.moveTo(xLineValue, yTickStart);
this.ctx.lineTo(xLineValue, yTickEnd);
}
// Draw the chart area
if (this.options.gridLines.drawOnChartArea) {
this.ctx.moveTo(xLineValue, chartArea.top);
this.ctx.lineTo(xLineValue, chartArea.bottom);
}
// Need to stroke in the loop because we are potentially changing line widths & colours
this.ctx.stroke();
}
if (this.options.ticks.display) {
this.ctx.save();
this.ctx.translate(xLabelValue, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - 10 : this.top + 10);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = tickLabelFont;
this.ctx.textAlign = (isRotated) ? "right" : "center";
this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, this);
if (this.options.scaleLabel.display) {
// Draw the scale label
this.ctx.textAlign = "center";
this.ctx.textBaseline = 'middle';
this.ctx.fillStyle = scaleLabelFontColor; // render in correct colour
this.ctx.font = scaleLabelFont;
scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width
scaleLabelY = this.options.position === 'bottom' ? this.bottom - (scaleLabelFontSize / 2) : this.top + (scaleLabelFontSize / 2);
this.ctx.fillText(this.options.scaleLabel.labelString, scaleLabelX, scaleLabelY);
}
} else {
setContextLineSettings = true;
var xTickStart = this.options.position === "right" ? this.left : this.right - 5;
var xTickEnd = this.options.position === "right" ? this.left + 5 : this.right;
helpers.each(this.ticks, function(label, index) {
// If the callback returned a null or undefined value, do not draw this line
if (label === undefined || label === null) {
return;
}
var yLineValue = this.getPixelForTick(index); // xvalues for grid lines
if (this.options.gridLines.display) {
if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) {
// Draw the first index specially
this.ctx.lineWidth = this.options.gridLines.zeroLineWidth;
this.ctx.strokeStyle = this.options.gridLines.zeroLineColor;
setContextLineSettings = true; // reset next time
} else if (setContextLineSettings) {
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
setContextLineSettings = false;
}
yLineValue += helpers.aliasPixel(this.ctx.lineWidth);
// Draw the label area
this.ctx.beginPath();
if (this.options.gridLines.drawTicks) {
this.ctx.moveTo(xTickStart, yLineValue);
this.ctx.lineTo(xTickEnd, yLineValue);
}
// Draw the chart area
if (this.options.gridLines.drawOnChartArea) {
this.ctx.moveTo(chartArea.left, yLineValue);
this.ctx.lineTo(chartArea.right, yLineValue);
}
// Need to stroke in the loop because we are potentially changing line widths & colours
this.ctx.stroke();
}
if (this.options.ticks.display) {
var xLabelValue;
var yLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option)
this.ctx.save();
if (this.options.position === "left") {
if (this.options.ticks.mirror) {
xLabelValue = this.right + this.options.ticks.padding;
this.ctx.textAlign = "left";
} else {
xLabelValue = this.right - this.options.ticks.padding;
this.ctx.textAlign = "right";
}
} else {
// right side
if (this.options.ticks.mirror) {
xLabelValue = this.left - this.options.ticks.padding;
this.ctx.textAlign = "right";
} else {
xLabelValue = this.left + this.options.ticks.padding;
this.ctx.textAlign = "left";
}
}
this.ctx.translate(xLabelValue, yLabelValue);
this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1);
this.ctx.font = tickLabelFont;
this.ctx.textBaseline = "middle";
this.ctx.fillText(label, 0, 0);
this.ctx.restore();
}
}, this);
if (this.options.scaleLabel.display) {
// Draw the scale label
scaleLabelX = this.options.position === 'left' ? this.left + (scaleLabelFontSize / 2) : this.right - (scaleLabelFontSize / 2);
scaleLabelY = this.top + ((this.bottom - this.top) / 2);
var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
this.ctx.save();
this.ctx.translate(scaleLabelX, scaleLabelY);
this.ctx.rotate(rotation);
this.ctx.textAlign = "center";
this.ctx.fillStyle =scaleLabelFontColor; // render in correct colour
this.ctx.font = scaleLabelFont;
this.ctx.textBaseline = 'middle';
this.ctx.fillText(this.options.scaleLabel.labelString, 0, 0);
this.ctx.restore();
}
}
// Draw the line at the edge of the axis
this.ctx.lineWidth = this.options.gridLines.lineWidth;
this.ctx.strokeStyle = this.options.gridLines.color;
var x1 = this.left,
x2 = this.right,
y1 = this.top,
y2 = this.bottom;
if (this.isHorizontal()) {
y1 = y2 = this.options.position === 'top' ? this.bottom : this.top;
y1 += helpers.aliasPixel(this.ctx.lineWidth);
y2 += helpers.aliasPixel(this.ctx.lineWidth);
} else {
x1 = x2 = this.options.position === 'left' ? this.right : this.left;
x1 += helpers.aliasPixel(this.ctx.lineWidth);
x2 += helpers.aliasPixel(this.ctx.lineWidth);
}
this.ctx.beginPath();
this.ctx.moveTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
}
}
});
};
+34
Ver Arquivo
@@ -0,0 +1,34 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.scaleService = {
// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then
// use the new chart options to grab the correct scale
constructors: {},
// Use a registration function so that we can move to an ES6 map when we no longer need to support
// old browsers
// Scale config defaults
defaults: {},
registerScaleType: function(type, scaleConstructor, defaults) {
this.constructors[type] = scaleConstructor;
this.defaults[type] = helpers.clone(defaults);
},
getScaleConstructor: function(type) {
return this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;
},
getScaleDefaults: function(type) {
// Return the scale defaults merged with the global settings so that we always use the latest ones
return this.defaults.hasOwnProperty(type) ? helpers.scaleMerge(Chart.defaults.scale, this.defaults[type]) : {};
},
addScalesToLayout: function(chartInstance) {
// Adds each scale to the chart.boxes array to be sized accordingly
helpers.each(chartInstance.scales, function(scale) {
Chart.layoutService.addBox(chartInstance, scale);
});
}
};
};
+193
Ver Arquivo
@@ -0,0 +1,193 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.title = {
display: false,
position: 'top',
fullWidth: true, // marks that this box should take the full width of the canvas (pushing down other boxes)
fontStyle: 'bold',
padding: 10,
// actual title
text: ''
};
Chart.Title = Chart.Element.extend({
initialize: function(config) {
helpers.extend(this, config);
this.options = helpers.configMerge(Chart.defaults.global.title, config.options);
// Contains hit boxes for each dataset (in dataset order)
this.legendHitBoxes = [];
},
// These methods are ordered by lifecyle. Utilities then follow.
beforeUpdate: helpers.noop,
update: function(maxWidth, maxHeight, margins) {
// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)
this.beforeUpdate();
// Absorb the master measurements
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.margins = margins;
// Dimensions
this.beforeSetDimensions();
this.setDimensions();
this.afterSetDimensions();
// Labels
this.beforeBuildLabels();
this.buildLabels();
this.afterBuildLabels();
// Fit
this.beforeFit();
this.fit();
this.afterFit();
//
this.afterUpdate();
return this.minSize;
},
afterUpdate: helpers.noop,
//
beforeSetDimensions: helpers.noop,
setDimensions: function() {
// Set the unconstrained dimension before label rotation
if (this.isHorizontal()) {
// Reset position before calculating rotation
this.width = this.maxWidth;
this.left = 0;
this.right = this.width;
} else {
this.height = this.maxHeight;
// Reset position before calculating rotation
this.top = 0;
this.bottom = this.height;
}
// Reset padding
this.paddingLeft = 0;
this.paddingTop = 0;
this.paddingRight = 0;
this.paddingBottom = 0;
// Reset minSize
this.minSize = {
width: 0,
height: 0
};
},
afterSetDimensions: helpers.noop,
//
beforeBuildLabels: helpers.noop,
buildLabels: helpers.noop,
afterBuildLabels: helpers.noop,
//
beforeFit: helpers.noop,
fit: function() {
var ctx = this.ctx;
var fontSize = helpers.getValueOrDefault(this.options.fontSize, Chart.defaults.global.defaultFontSize);
var fontStyle = helpers.getValueOrDefault(this.options.fontStyle, Chart.defaults.global.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(this.options.fontFamily, Chart.defaults.global.defaultFontFamily);
var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
// Width
if (this.isHorizontal()) {
this.minSize.width = this.maxWidth; // fill all the width
} else {
this.minSize.width = 0;
}
// height
if (this.isHorizontal()) {
this.minSize.height = 0;
} else {
this.minSize.height = this.maxHeight; // fill all the height
}
// Increase sizes here
if (this.isHorizontal()) {
// Title
if (this.options.display) {
this.minSize.height += fontSize + (this.options.padding * 2);
}
} else {
if (this.options.display) {
this.minSize.width += fontSize + (this.options.padding * 2);
}
}
this.width = this.minSize.width;
this.height = this.minSize.height;
},
afterFit: helpers.noop,
// Shared Methods
isHorizontal: function() {
return this.options.position === "top" || this.options.position === "bottom";
},
// Actualy draw the title block on the canvas
draw: function() {
if (this.options.display) {
var ctx = this.ctx;
var titleX, titleY;
var fontColor = helpers.getValueOrDefault(this.options.fontColor, Chart.defaults.global.defaultFontColor);
var fontSize = helpers.getValueOrDefault(this.options.fontSize, Chart.defaults.global.defaultFontSize);
var fontStyle = helpers.getValueOrDefault(this.options.fontStyle, Chart.defaults.global.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(this.options.fontFamily, Chart.defaults.global.defaultFontFamily);
var titleFont = helpers.fontString(fontSize, fontStyle, fontFamily);
ctx.fillStyle = fontColor; // render in correct colour
ctx.font = titleFont;
// Horizontal
if (this.isHorizontal()) {
// Title
ctx.textAlign = "center";
ctx.textBaseline = 'middle';
titleX = this.left + ((this.right - this.left) / 2); // midpoint of the width
titleY = this.top + ((this.bottom - this.top) / 2); // midpoint of the height
ctx.fillText(this.options.text, titleX, titleY);
} else {
// Title
titleX = this.options.position === 'left' ? this.left + (fontSize / 2) : this.right - (fontSize / 2);
titleY = this.top + ((this.bottom - this.top) / 2);
var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI;
ctx.save();
ctx.translate(titleX, titleY);
ctx.rotate(rotation);
ctx.textAlign = "center";
ctx.textBaseline = 'middle';
ctx.fillText(this.options.text, 0, 0);
ctx.restore();
}
}
}
});
};
+615
Ver Arquivo
@@ -0,0 +1,615 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.tooltips = {
enabled: true,
custom: null,
mode: 'single',
backgroundColor: "rgba(0,0,0,0.8)",
titleFontStyle: "bold",
titleSpacing: 2,
titleMarginBottom: 6,
titleColor: "#fff",
titleAlign: "left",
bodySpacing: 2,
bodyColor: "#fff",
bodyAlign: "left",
footerFontStyle: "bold",
footerSpacing: 2,
footerMarginTop: 6,
footerColor: "#fff",
footerAlign: "left",
yPadding: 6,
xPadding: 6,
yAlign : 'center',
xAlign : 'center',
caretSize: 5,
cornerRadius: 6,
multiKeyBackground: '#fff',
callbacks: {
// Args are: (tooltipItems, data)
beforeTitle: helpers.noop,
title: function(tooltipItems, data) {
// Pick first xLabel for now
var title = '';
if (tooltipItems.length > 0) {
if (tooltipItems[0].xLabel) {
title = tooltipItems[0].xLabel;
} else if (data.labels.length > 0 && tooltipItems[0].index < data.labels.length) {
title = data.labels[tooltipItems[0].index];
}
}
return title;
},
afterTitle: helpers.noop,
// Args are: (tooltipItems, data)
beforeBody: helpers.noop,
// Args are: (tooltipItem, data)
beforeLabel: helpers.noop,
label: function(tooltipItem, data) {
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
return datasetLabel + ': ' + tooltipItem.yLabel;
},
afterLabel: helpers.noop,
// Args are: (tooltipItems, data)
afterBody: helpers.noop,
// Args are: (tooltipItems, data)
beforeFooter: helpers.noop,
footer: helpers.noop,
afterFooter: helpers.noop
}
};
// Helper to push or concat based on if the 2nd parameter is an array or not
function pushOrConcat(base, toPush) {
if (toPush) {
if (helpers.isArray(toPush)) {
base = base.concat(toPush);
} else {
base.push(toPush);
}
}
return base;
}
Chart.Tooltip = Chart.Element.extend({
initialize: function() {
var options = this._options;
helpers.extend(this, {
_model: {
// Positioning
xPadding: options.tooltips.xPadding,
yPadding: options.tooltips.yPadding,
xAlign : options.tooltips.yAlign,
yAlign : options.tooltips.xAlign,
// Body
bodyColor: options.tooltips.bodyColor,
_bodyFontFamily: helpers.getValueOrDefault(options.tooltips.bodyFontFamily, Chart.defaults.global.defaultFontFamily),
_bodyFontStyle: helpers.getValueOrDefault(options.tooltips.bodyFontStyle, Chart.defaults.global.defaultFontStyle),
_bodyAlign: options.tooltips.bodyAlign,
bodyFontSize: helpers.getValueOrDefault(options.tooltips.bodyFontSize, Chart.defaults.global.defaultFontSize),
bodySpacing: options.tooltips.bodySpacing,
// Title
titleColor: options.tooltips.titleColor,
_titleFontFamily: helpers.getValueOrDefault(options.tooltips.titleFontFamily, Chart.defaults.global.defaultFontFamily),
_titleFontStyle: helpers.getValueOrDefault(options.tooltips.titleFontStyle, Chart.defaults.global.defaultFontStyle),
titleFontSize: helpers.getValueOrDefault(options.tooltips.titleFontSize, Chart.defaults.global.defaultFontSize),
_titleAlign: options.tooltips.titleAlign,
titleSpacing: options.tooltips.titleSpacing,
titleMarginBottom: options.tooltips.titleMarginBottom,
// Footer
footerColor: options.tooltips.footerColor,
_footerFontFamily: helpers.getValueOrDefault(options.tooltips.footerFontFamily, Chart.defaults.global.defaultFontFamily),
_footerFontStyle: helpers.getValueOrDefault(options.tooltips.footerFontStyle, Chart.defaults.global.defaultFontStyle),
footerFontSize: helpers.getValueOrDefault(options.tooltips.footerFontSize, Chart.defaults.global.defaultFontSize),
_footerAlign: options.tooltips.footerAlign,
footerSpacing: options.tooltips.footerSpacing,
footerMarginTop: options.tooltips.footerMarginTop,
// Appearance
caretSize: options.tooltips.caretSize,
cornerRadius: options.tooltips.cornerRadius,
backgroundColor: options.tooltips.backgroundColor,
opacity: 0,
legendColorBackground: options.tooltips.multiKeyBackground
}
});
},
// Get the title
// Args are: (tooltipItem, data)
getTitle: function() {
var beforeTitle = this._options.tooltips.callbacks.beforeTitle.apply(this, arguments),
title = this._options.tooltips.callbacks.title.apply(this, arguments),
afterTitle = this._options.tooltips.callbacks.afterTitle.apply(this, arguments);
var lines = [];
lines = pushOrConcat(lines, beforeTitle);
lines = pushOrConcat(lines, title);
lines = pushOrConcat(lines, afterTitle);
return lines;
},
// Args are: (tooltipItem, data)
getBeforeBody: function() {
var lines = this._options.tooltips.callbacks.beforeBody.apply(this, arguments);
return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
},
// Args are: (tooltipItem, data)
getBody: function(tooltipItems, data) {
var lines = [];
helpers.each(tooltipItems, function(bodyItem) {
helpers.pushAllIfDefined(this._options.tooltips.callbacks.beforeLabel.call(this, bodyItem, data), lines);
helpers.pushAllIfDefined(this._options.tooltips.callbacks.label.call(this, bodyItem, data), lines);
helpers.pushAllIfDefined(this._options.tooltips.callbacks.afterLabel.call(this, bodyItem, data), lines);
}, this);
return lines;
},
// Args are: (tooltipItem, data)
getAfterBody: function() {
var lines = this._options.tooltips.callbacks.afterBody.apply(this, arguments);
return helpers.isArray(lines) ? lines : lines !== undefined ? [lines] : [];
},
// Get the footer and beforeFooter and afterFooter lines
// Args are: (tooltipItem, data)
getFooter: function() {
var beforeFooter = this._options.tooltips.callbacks.beforeFooter.apply(this, arguments);
var footer = this._options.tooltips.callbacks.footer.apply(this, arguments);
var afterFooter = this._options.tooltips.callbacks.afterFooter.apply(this, arguments);
var lines = [];
lines = pushOrConcat(lines, beforeFooter);
lines = pushOrConcat(lines, footer);
lines = pushOrConcat(lines, afterFooter);
return lines;
},
getAveragePosition: function(elements) {
if (!elements.length) {
return false;
}
var xPositions = [];
var yPositions = [];
helpers.each(elements, function(el) {
if (el) {
var pos = el.tooltipPosition();
xPositions.push(pos.x);
yPositions.push(pos.y);
}
});
var x = 0,
y = 0;
for (var i = 0; i < xPositions.length; i++) {
x += xPositions[i];
y += yPositions[i];
}
return {
x: Math.round(x / xPositions.length),
y: Math.round(y / xPositions.length)
};
},
update: function(changed) {
if (this._active.length) {
this._model.opacity = 1;
var element = this._active[0],
labelColors = [],
tooltipPosition;
var tooltipItems = [];
if (this._options.tooltips.mode === 'single') {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
tooltipItems.push({
xLabel: element._xScale ? element._xScale.getLabelForIndex(element._index, element._datasetIndex) : '',
yLabel: yScale ? yScale.getLabelForIndex(element._index, element._datasetIndex) : '',
index: element._index,
datasetIndex: element._datasetIndex
});
tooltipPosition = this.getAveragePosition(this._active);
} else {
helpers.each(this._data.datasets, function(dataset, datasetIndex) {
if (!helpers.isDatasetVisible(dataset)) {
return;
}
var currentElement = dataset.metaData[element._index];
if (currentElement) {
var yScale = element._yScale || element._scale; // handle radar || polarArea charts
tooltipItems.push({
xLabel: currentElement._xScale ? currentElement._xScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '',
yLabel: yScale ? yScale.getLabelForIndex(currentElement._index, currentElement._datasetIndex) : '',
index: element._index,
datasetIndex: datasetIndex
});
}
}, null, element._yScale.options.stacked);
helpers.each(this._active, function(active) {
if (active) {
labelColors.push({
borderColor: active._view.borderColor,
backgroundColor: active._view.backgroundColor
});
}
}, null, element._yScale.options.stacked);
tooltipPosition = this.getAveragePosition(this._active);
tooltipPosition.y = this._active[0]._yScale.getPixelForDecimal(0.5);
}
// Build the Text Lines
helpers.extend(this._model, {
title: this.getTitle(tooltipItems, this._data),
beforeBody: this.getBeforeBody(tooltipItems, this._data),
body: this.getBody(tooltipItems, this._data),
afterBody: this.getAfterBody(tooltipItems, this._data),
footer: this.getFooter(tooltipItems, this._data)
});
helpers.extend(this._model, {
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
labelColors: labelColors
});
// We need to determine alignment of
var tooltipSize = this.getTooltipSize(this._model);
this.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
helpers.extend(this._model, this.getBackgroundPoint(this._model, tooltipSize));
} else {
this._model.opacity = 0;
}
if (changed && this._options.tooltips.custom) {
this._options.tooltips.custom.call(this, this._model);
}
return this;
},
getTooltipSize: function getTooltipSize(vm) {
var ctx = this._chart.ctx;
var size = {
height: vm.yPadding * 2, // Tooltip Padding
width: 0
};
var combinedBodyLength = vm.body.length + vm.beforeBody.length + vm.afterBody.length;
size.height += vm.title.length * vm.titleFontSize; // Title Lines
size.height += (vm.title.length - 1) * vm.titleSpacing; // Title Line Spacing
size.height += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin
size.height += combinedBodyLength * vm.bodyFontSize; // Body Lines
size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
size.height += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin
size.height += vm.footer.length * (vm.footerFontSize); // Footer Lines
size.height += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing
// Width
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
helpers.each(vm.title, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
});
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
helpers.each(vm.beforeBody.concat(vm.afterBody), function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
});
helpers.each(vm.body, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0));
}, this);
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(vm.footer, function(line) {
size.width = Math.max(size.width, ctx.measureText(line).width);
});
size.width += 2 * vm.xPadding;
return size;
},
determineAlignment: function determineAlignment(size) {
if (this._model.y < size.height) {
this._model.yAlign = 'top';
} else if (this._model.y > (this._chart.height - size.height)) {
this._model.yAlign = 'bottom';
}
var lf, rf; // functions to determine left, right alignment
var olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart
var yf; // function to get the y alignment if the tooltip goes outside of the left or right edges
var _this = this;
var midX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
var midY = (this._chartInstance.chartArea.top + this._chartInstance.chartArea.bottom) / 2;
if (this._model.yAlign === 'center') {
lf = function(x) {
return x <= midX;
};
rf = function(x) {
return x > midX;
};
} else {
lf = function(x) {
return x <= (size.width / 2);
};
rf = function(x) {
return x >= (_this._chart.width - (size.width / 2));
};
}
olf = function(x) {
return x + size.width > _this._chart.width;
};
orf = function(x) {
return x - size.width < 0;
};
yf = function(y) {
return y <= midY ? 'top' : 'bottom';
};
if (lf(this._model.x)) {
this._model.xAlign = 'left';
// Is tooltip too wide and goes over the right side of the chart.?
if (olf(this._model.x)) {
this._model.xAlign = 'center';
this._model.yAlign = yf(this._model.y);
}
} else if (rf(this._model.x)) {
this._model.xAlign = 'right';
// Is tooltip too wide and goes outside left edge of canvas?
if (orf(this._model.x)) {
this._model.xAlign = 'center';
this._model.yAlign = yf(this._model.y);
}
}
},
getBackgroundPoint: function getBackgroundPoint(vm, size) {
// Background Position
var pt = {
x: vm.x,
y: vm.y
};
if (vm.xAlign === 'right') {
pt.x -= size.width;
} else if (vm.xAlign === 'center') {
pt.x -= (size.width / 2);
}
if (vm.yAlign === 'top') {
pt.y += vm.caretPadding + vm.caretSize;
} else if (vm.yAlign === 'bottom') {
pt.y -= size.height + vm.caretPadding + vm.caretSize;
} else {
pt.y -= (size.height / 2);
}
if (vm.yAlign === 'center') {
if (vm.xAlign === 'left') {
pt.x += vm.caretPadding + vm.caretSize;
} else if (vm.xAlign === 'right') {
pt.x -= vm.caretPadding + vm.caretSize;
}
} else {
if (vm.xAlign === 'left') {
pt.x -= vm.cornerRadius + vm.caretPadding;
} else if (vm.xAlign === 'right') {
pt.x += vm.cornerRadius + vm.caretPadding;
}
}
return pt;
},
drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {
var vm = this._view;
var ctx = this._chart.ctx;
var x1, x2, x3;
var y1, y2, y3;
if (vm.yAlign === 'center') {
// Left or right side
if (vm.xAlign === 'left') {
x1 = tooltipPoint.x;
x2 = x1 - vm.caretSize;
x3 = x1;
} else {
x1 = tooltipPoint.x + size.width;
x2 = x1 + vm.caretSize;
x3 = x1;
}
y2 = tooltipPoint.y + (size.height / 2);
y1 = y2 - vm.caretSize;
y3 = y2 + vm.caretSize;
} else {
if (vm.xAlign === 'left') {
x1 = tooltipPoint.x + vm.cornerRadius;
x2 = x1 + vm.caretSize;
x3 = x2 + vm.caretSize;
} else if (vm.xAlign === 'right') {
x1 = tooltipPoint.x + size.width - vm.cornerRadius;
x2 = x1 - vm.caretSize;
x3 = x2 - vm.caretSize;
} else {
x2 = tooltipPoint.x + (size.width / 2);
x1 = x2 - vm.caretSize;
x3 = x2 + vm.caretSize;
}
if (vm.yAlign === 'top') {
y1 = tooltipPoint.y;
y2 = y1 - vm.caretSize;
y3 = y1;
} else {
y1 = tooltipPoint.y + size.height;
y2 = y1 + vm.caretSize;
y3 = y1;
}
}
var bgColor = helpers.color(vm.backgroundColor);
ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.closePath();
ctx.fill();
},
drawTitle: function drawTitle(pt, vm, ctx, opacity) {
if (vm.title.length) {
ctx.textAlign = vm._titleAlign;
ctx.textBaseline = "top";
var titleColor = helpers.color(vm.titleColor);
ctx.fillStyle = titleColor.alpha(opacity * titleColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
helpers.each(vm.title, function(title, i) {
ctx.fillText(title, pt.x, pt.y);
pt.y += vm.titleFontSize + vm.titleSpacing; // Line Height and spacing
if (i + 1 === vm.title.length) {
pt.y += vm.titleMarginBottom - vm.titleSpacing; // If Last, add margin, remove spacing
}
});
}
},
drawBody: function drawBody(pt, vm, ctx, opacity) {
ctx.textAlign = vm._bodyAlign;
ctx.textBaseline = "top";
var bodyColor = helpers.color(vm.bodyColor);
ctx.fillStyle = bodyColor.alpha(opacity * bodyColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
// Before Body
helpers.each(vm.beforeBody, function(beforeBody) {
ctx.fillText(beforeBody, pt.x, pt.y);
pt.y += vm.bodyFontSize + vm.bodySpacing;
});
helpers.each(vm.body, function(body, i) {
// Draw Legend-like boxes if needed
if (this._options.tooltips.mode !== 'single') {
// Fill a white rect so that colours merge nicely if the opacity is < 1
ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
ctx.fillRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
// Border
ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
ctx.strokeRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
// Inner square
ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
ctx.fillRect(pt.x + 1, pt.y + 1, vm.bodyFontSize - 2, vm.bodyFontSize - 2);
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbaString(); // Return fill style for text
}
// Body Line
ctx.fillText(body, pt.x + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0), pt.y);
pt.y += vm.bodyFontSize + vm.bodySpacing;
}, this);
// After Body
helpers.each(vm.afterBody, function(afterBody) {
ctx.fillText(afterBody, pt.x, pt.y);
pt.y += vm.bodyFontSize;
});
pt.y -= vm.bodySpacing; // Remove last body spacing
},
drawFooter: function drawFooter(pt, vm, ctx, opacity) {
if (vm.footer.length) {
pt.y += vm.footerMarginTop;
ctx.textAlign = vm._footerAlign;
ctx.textBaseline = "top";
var footerColor = helpers.color(vm.footerColor);
ctx.fillStyle = footerColor.alpha(opacity * footerColor.alpha()).rgbString();
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
helpers.each(vm.footer, function(footer) {
ctx.fillText(footer, pt.x, pt.y);
pt.y += vm.footerFontSize + vm.footerSpacing;
});
}
},
draw: function draw() {
var ctx = this._chart.ctx;
var vm = this._view;
if (vm.opacity === 0) {
return;
}
var caretPadding = vm.caretPadding;
var tooltipSize = this.getTooltipSize(vm);
var pt = {
x: vm.x,
y: vm.y
};
// IE11/Edge does not like very small opacities, so snap to 0
var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
if (this._options.tooltips.enabled) {
// Draw Background
var bgColor = helpers.color(vm.backgroundColor);
ctx.fillStyle = bgColor.alpha(opacity * bgColor.alpha()).rgbString();
helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
ctx.fill();
// Draw Caret
this.drawCaret(pt, tooltipSize, opacity, caretPadding);
// Draw Title, Body, and Footer
pt.x += vm.xPadding;
pt.y += vm.yPadding;
// Titles
this.drawTitle(pt, vm, ctx, opacity);
// Body
this.drawBody(pt, vm, ctx, opacity);
// Footer
this.drawFooter(pt, vm, ctx, opacity);
}
}
});
};
+81
Ver Arquivo
@@ -0,0 +1,81 @@
"use strict";
module.exports = function(Chart, moment) {
var 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();
}
}
});
};
+161
Ver Arquivo
@@ -0,0 +1,161 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.elements.line = {
tension: 0.4,
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 3,
borderColor: Chart.defaults.global.defaultColor,
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
borderJoinStyle: 'miter',
fill: true // do we fill in the area between the line and its base axis
};
Chart.elements.Line = Chart.Element.extend({
lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {
var ctx = this._chart.ctx;
if (point._view.skip) {
skipHandler.call(this, previousPoint, point, nextPoint);
} else if (previousPoint._view.skip) {
previousSkipHandler.call(this, previousPoint, point, nextPoint);
} else if (point._view.tension === 0) {
ctx.lineTo(point._view.x, point._view.y);
} else {
// Line between points
ctx.bezierCurveTo(
previousPoint._view.controlPointNextX,
previousPoint._view.controlPointNextY,
point._view.controlPointPreviousX,
point._view.controlPointPreviousY,
point._view.x,
point._view.y
);
}
},
draw: function() {
var _this = this;
var vm = this._view;
var ctx = this._chart.ctx;
var first = this._children[0];
var last = this._children[this._children.length - 1];
function loopBackToStart(drawLineToCenter) {
if (!first._view.skip && !last._view.skip) {
// Draw a bezier line from last to first
ctx.bezierCurveTo(
last._view.controlPointNextX,
last._view.controlPointNextY,
first._view.controlPointPreviousX,
first._view.controlPointPreviousY,
first._view.x,
first._view.y
);
} else if (drawLineToCenter) {
// Go to center
ctx.lineTo(_this._view.scaleZero.x, _this._view.scaleZero.y);
}
}
ctx.save();
// If we had points and want to fill this line, do so.
if (this._children.length > 0 && vm.fill) {
// Draw the background first (so the border is always on top)
ctx.beginPath();
helpers.each(this._children, function(point, index) {
var previous = helpers.previousItem(this._children, index);
var next = helpers.nextItem(this._children, index);
// First point moves to it's starting position no matter what
if (index === 0) {
if (this._loop) {
ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);
} else {
ctx.moveTo(point._view.x, vm.scaleZero);
}
if (point._view.skip) {
if (!this._loop) {
ctx.moveTo(next._view.x, this._view.scaleZero);
}
} else {
ctx.lineTo(point._view.x, point._view.y);
}
} else {
this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
if (this._loop) {
// Go to center
ctx.lineTo(this._view.scaleZero.x, this._view.scaleZero.y);
} else {
ctx.lineTo(previousPoint._view.x, this._view.scaleZero);
ctx.moveTo(nextPoint._view.x, this._view.scaleZero);
}
}, function(previousPoint, point) {
// If we skipped the last point, draw a line to ourselves so that the fill is nice
ctx.lineTo(point._view.x, point._view.y);
});
}
}, this);
// For radial scales, loop back around to the first point
if (this._loop) {
loopBackToStart(true);
} else {
//Round off the line by going to the base of the chart, back to the start, then fill.
ctx.lineTo(this._children[this._children.length - 1]._view.x, vm.scaleZero);
ctx.lineTo(this._children[0]._view.x, vm.scaleZero);
}
ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor;
ctx.closePath();
ctx.fill();
}
// Now draw the line between all the points with any borders
ctx.lineCap = vm.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle;
// IE 9 and 10 do not support line dash
if (ctx.setLineDash) {
ctx.setLineDash(vm.borderDash || Chart.defaults.global.elements.line.borderDash);
}
ctx.lineDashOffset = vm.borderDashOffset || Chart.defaults.global.elements.line.borderDashOffset;
ctx.lineJoin = vm.borderJoinStyle || Chart.defaults.global.elements.line.borderJoinStyle;
ctx.lineWidth = vm.borderWidth || Chart.defaults.global.elements.line.borderWidth;
ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor;
ctx.beginPath();
helpers.each(this._children, function(point, index) {
var previous = helpers.previousItem(this._children, index);
var next = helpers.nextItem(this._children, index);
if (index === 0) {
ctx.moveTo(point._view.x, point._view.y);
} else {
this.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
ctx.moveTo(nextPoint._view.x, nextPoint._view.y);
}, function(previousPoint, point) {
// If we skipped the last point, move up to our point preventing a line from being drawn
ctx.moveTo(point._view.x, point._view.y);
});
}
}, this);
if (this._loop && this._children.length > 0) {
loopBackToStart();
}
ctx.stroke();
ctx.restore();
}
});
};
+153
Ver Arquivo
@@ -0,0 +1,153 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.elements.point = {
radius: 3,
pointStyle: 'circle',
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 (typeof vm.pointStyle === 'object' && ((vm.pointStyle.toString() === '[object HTMLImageElement]') || (vm.pointStyle.toString() === '[object HTMLCanvasElement]'))) {
ctx.drawImage(vm.pointStyle, vm.x - vm.pointStyle.width / 2, vm.y - vm.pointStyle.height / 2);
return;
}
if (!isNaN(vm.radius) && vm.radius > 0) {
ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor;
ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, Chart.defaults.global.elements.point.borderWidth);
ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor;
var radius = vm.radius;
var xOffset;
var yOffset;
switch (vm.pointStyle) {
// Default includes circle
default: ctx.beginPath();
ctx.arc(vm.x, vm.y, radius, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
break;
case 'triangle':
ctx.beginPath();
var edgeLength = 3 * radius / Math.sqrt(3);
var height = edgeLength * Math.sqrt(3) / 2;
ctx.moveTo(vm.x - edgeLength / 2, vm.y + height / 3);
ctx.lineTo(vm.x + edgeLength / 2, vm.y + height / 3);
ctx.lineTo(vm.x, vm.y - 2 * height / 3);
ctx.closePath();
ctx.fill();
break;
case 'rect':
ctx.fillRect(vm.x - 1 / Math.SQRT2 * radius, vm.y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
ctx.strokeRect(vm.x - 1 / Math.SQRT2 * radius, vm.y - 1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
break;
case 'rectRot':
ctx.translate(vm.x, vm.y);
ctx.rotate(Math.PI / 4);
ctx.fillRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
ctx.strokeRect(-1 / Math.SQRT2 * radius, -1 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius, 2 / Math.SQRT2 * radius);
ctx.setTransform(1, 0, 0, 1, 0, 0);
break;
case 'cross':
ctx.beginPath();
ctx.moveTo(vm.x, vm.y + radius);
ctx.lineTo(vm.x, vm.y - radius);
ctx.moveTo(vm.x - radius, vm.y);
ctx.lineTo(vm.x + radius, vm.y);
ctx.closePath();
break;
case 'crossRot':
ctx.beginPath();
xOffset = Math.cos(Math.PI / 4) * radius;
yOffset = Math.sin(Math.PI / 4) * radius;
ctx.moveTo(vm.x - xOffset, vm.y - yOffset);
ctx.lineTo(vm.x + xOffset, vm.y + yOffset);
ctx.moveTo(vm.x - xOffset, vm.y + yOffset);
ctx.lineTo(vm.x + xOffset, vm.y - yOffset);
ctx.closePath();
break;
case 'star':
ctx.beginPath();
ctx.moveTo(vm.x, vm.y + radius);
ctx.lineTo(vm.x, vm.y - radius);
ctx.moveTo(vm.x - radius, vm.y);
ctx.lineTo(vm.x + radius, vm.y);
xOffset = Math.cos(Math.PI / 4) * radius;
yOffset = Math.sin(Math.PI / 4) * radius;
ctx.moveTo(vm.x - xOffset, vm.y - yOffset);
ctx.lineTo(vm.x + xOffset, vm.y + yOffset);
ctx.moveTo(vm.x - xOffset, vm.y + yOffset);
ctx.lineTo(vm.x + xOffset, vm.y - yOffset);
ctx.closePath();
break;
case 'line':
ctx.beginPath();
ctx.moveTo(vm.x - radius, vm.y);
ctx.lineTo(vm.x + radius, vm.y);
ctx.closePath();
break;
case 'dash':
ctx.beginPath();
ctx.moveTo(vm.x, vm.y);
ctx.lineTo(vm.x + radius, vm.y);
ctx.closePath();
break;
}
ctx.stroke();
}
}
});
};
+106
Ver Arquivo
@@ -0,0 +1,106 @@
"use strict";
module.exports = function(Chart) {
var helpers = Chart.helpers;
Chart.defaults.global.elements.rectangle = {
backgroundColor: Chart.defaults.global.defaultColor,
borderWidth: 0,
borderColor: Chart.defaults.global.defaultColor,
borderSkipped: 'bottom'
};
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;
// Corner points, from bottom-left to bottom-right clockwise
// | 1 2 |
// | 0 3 |
var corners = [
[leftX, vm.base],
[leftX, top],
[rightX, top],
[rightX, vm.base]
];
// Find first (starting) corner with fallback to 'bottom'
var borders = ['bottom', 'left', 'top', 'right'];
var startCorner = borders.indexOf(vm.borderSkipped, 0);
if (startCorner === -1)
startCorner = 0;
function cornerAt(index) {
return corners[(startCorner + index) % 4];
}
// Draw rectangle from 'startCorner'
ctx.moveTo.apply(ctx, cornerAt(0));
for (var i = 1; i < 4; i++)
ctx.lineTo.apply(ctx, cornerAt(i));
ctx.fill();
if (vm.borderWidth) {
ctx.stroke();
}
},
height: function() {
var vm = this._view;
return vm.base - vm.y;
},
inRange: function(mouseX, mouseY) {
var vm = this._view;
var inRange = false;
if (vm) {
if (vm.y < vm.base) {
inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.y && mouseY <= vm.base);
} else {
inRange = (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2) && (mouseY >= vm.base && mouseY <= vm.y);
}
}
return inRange;
},
inLabelRange: function(mouseX) {
var vm = this._view;
if (vm) {
return (mouseX >= vm.x - vm.width / 2 && mouseX <= vm.x + vm.width / 2);
} else {
return false;
}
},
tooltipPosition: function() {
var vm = this._view;
return {
x: vm.x,
y: vm.y
};
}
});
};

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