├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bower.json ├── composer.json ├── dist ├── pivot_spec.js ├── pivot_spec.js.map ├── pivot_spec.min.js ├── pivot_spec.min.js.map ├── subtotal.css ├── subtotal.js ├── subtotal.js.map ├── subtotal.min.css ├── subtotal.min.js └── subtotal.min.js.map ├── docs ├── OptionsCombination.xlsx └── v1.10.0 │ ├── Getting-Started.md │ ├── Home.md │ ├── Pivottable.js-Parameters.md │ └── Subtotal.js-Renderer-Options.md ├── examples ├── 105_default.html ├── 110_collapse_rowscols.html ├── 137_as_fraction_of_parent_row.html ├── 139_as_fraction_of_parent_column.html ├── 155_custom_collapse_expand_arrow.html ├── 160_event_handlers.html ├── 170_hide_subtotal_on_expand.html ├── 180_disable_subtotal.html ├── 185_disable_expandcollapse.html ├── 190_disable_after.html ├── 195_rowsubtotal_at_bottom.html ├── 205_default.html ├── 210_collapse_rowscols.html ├── 237_as_fraction_of_parent_row.html ├── 239_as_fraction_of_parent_column.html ├── 255_custom_collapse_expand_arrow.html ├── 260_event_handlers.html ├── 270_hide_subtotal_on_expand.html ├── 280_disable_subtotal.html ├── 285_disable_expandcollapse.html ├── 290_disable_after.html ├── 295_rowsubtotal_at_bottom.html ├── css │ ├── gh-fork-ribbon.css │ └── gh-fork-ribbon.ie.css ├── data │ ├── montreal_2014.csv │ └── mps.json ├── index.html └── js │ └── show_code.js ├── gulpFile.js ├── images ├── subtotal-renderer-pivotui.png ├── subtotal_cdnjs.svg ├── subtotal_license.svg ├── subtotal_npm.svg ├── subtotal_tests.svg ├── tablewithsubtotalheatmap.png ├── tablewithsubtotalheatmapmedium.png └── tablewithsubtotalheatmapsmall.png ├── index.html ├── package.json ├── subtotal.coffee ├── subtotal.css └── tests ├── boot.js ├── index.html └── pivot_spec.coffee /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | *.log 4 | *.swp 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Issues 2 | 3 | [Issues](https://github.com/nagarajanchinnasamy/subtotal/issues/new) are the preferred way to communicate with the author and users of Subtotal.js, rather than private email. 4 | 5 | * If you have multiple questions, please create multiple issues 6 | * Please do not add a comment to an existing issue to ask an unrelated question: create a new issue instead 7 | * When creating issue to report a problem, please try to provide a replicable test case (set of steps and/or a URL demonstrating the problem) so that others can help you. 8 | 9 | ## Pull Requests 10 | 11 | [Pull requests](https://help.github.com/articles/using-pull-requests) to this project are very welcome! They are most likely to be merged in if they conform to this project's basic goals, scope and structure: 12 | 13 | * If accepted, you agree that your pull-requests will be released to the world under the same license as the rest of the code: the [MIT license](LICENSE.md). 14 | * It's probably best to log an issue (see above) to report a bug or ask how something was meant to be done before jumping in and modifying the code, if only to confirm that there isn't another way to do what you're aiming for, and to increase the odds that your pull request will be merged :) 15 | * Multiple small pull requests which aim to solve clearly-stated problems are preferable to large pull requests which make many unrelated changes 16 | * The code for this project is written in CoffeeScript and thereafter compiled to Javascript, so it would be best to submit modifications to the CoffeeScript source files rather than to the automatically-generated Javascript source files (please reach out if you've made some neat modifications to the Javascript and want help 'porting' back up to the CoffeeScript version). 17 | * Releases for this project are built using the Gulp build system, and the resulting build products (located under `dist`) are tested with the Jasmine test suite under `tests`. See the building/test section of the main [ReadMe](https://github.com/nagarajanchinnasamy/subtotal/blob/master/README.md) for details. 18 | * The aim of this project is to have a plugin for [PivotTable.js](https://github.com/nicolaskruchten/pivottable) that adheres to interface specifications as documented in that library. So, please ensure your changes do not break this contract. 19 | * This is a cross-browser, client-side library with very little (if any) browser-specific shim code, so please try to submit modifications that work with as many browsers as possible and which don't require any server-side components 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Nagarajan Chinnasamy, Mindtree and other contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://www.npmjs.com/package/subtotal) [](http://nagarajanchinnasamy.com/subtotal/tests/) [](https://github.com/nagarajanchinnasamy/subtotal/blob/master/LICENSE) 2 | 3 | 4 | # Subtotal.js 5 | 6 | [Subtotal.js](http://nagarajanchinnasamy.com/subtotal) is a JavaScript plugin for [PivotTable.js](https://pivottable.js.org/examples/). It renders rows and columns of a pivot table with subtotals and lets the user expand or collapse rows and columns. 7 | 8 | 9 | Subtotal.js is available under an MIT license from [NPM](https://www.npmjs.com/package/subtotal) and [Bower](http://bower.io/) under the name `subtotal`. On [packagist.org](https://packagist.org/packages/nagarajanchinnasamy/subtotal), it is `nagarajanchinnasamy/subtotal`. 10 | 11 | 12 |  13 | 14 | ## Where can I see the demo? 15 | 16 | You can see the live demo at [examples page](http://nagarajanchinnasamy.com/subtotal/examples/index.html). 17 | 18 | ## How can I get started? 19 | 20 | To know how to load and use this library, please refer to [Getting Started Wiki Page](https://github.com/nagarajanchinnasamy/subtotal/wiki/Getting-Started) 21 | 22 | ## API Documentation? 23 | 24 | Please refer to [Wiki Pages](https://github.com/nagarajanchinnasamy/subtotal/wiki) 25 | 26 | ## How can I build the code and run the tests? 27 | 28 | To install the development dependencies, just run `npm install`, which will create a `node_modules` directory with the files required to run the [Gulp](http://gulpjs.com/) build system. 29 | 30 | After modifying any of the `.coffee` files at the top of the repo, you can compile/minify the files into the `dist` directory by running `npm run build` 31 | 32 | Once that's done, you can point your browser to `tests/index.html` to run the [Jasmine](http://jasmine.github.io/) test suite. You can view the [current test results here](http://nagarajanchinnasamy.com/subtotal/tests). 33 | 34 | The easiest way to modify the code and work with the examples is to leave a `node_modules/gulp/bin/gulp.js watch serve` command running, which will automatically compile the CoffeeScript files when they are modified and will also run a local web server you can connect to to run the tests and examples. 35 | 36 | ## How can I contribute? 37 | 38 | Pull requests are welcome! Here are some [Contribution Guidelines](https://github.com/nagarajanchinnasamy/subtotal/blob/master/CONTRIBUTING.md). 39 | 40 | ## I have a question, how can I get in touch? 41 | 42 | Please first check the [issues](https://github.com/nagarajanchinnasamy/subtotal/issues) that are already raised and if you can't find what you're looking for there, then please [create a GitHub Issue](https://github.com/nagarajanchinnasamy/subtotal/issues/new). When creating an issue, please try to provide a replicable test case so that others can more easily help you. 43 | 44 | ## Copyright & Licence (MIT License) 45 | 46 | Subtotal.js is © 2016 Nagarajan Chinnasamy, Mindtree, other contributors 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 49 | 50 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 53 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subtotal", 3 | "description": "Subtotal.js is a JavaScript plugin for PivotTable.js. It renders subtotals of rows and columns with the ability to expand and collapse rows.", 4 | "version": "1.11.0-alpha.0", 5 | "main": [ 6 | "dist/subtotal.js" 7 | ], 8 | "license": "MIT", 9 | "ignore": [ 10 | ".gitignore", 11 | "gulpFile.js", 12 | "package.json", 13 | "bower.json", 14 | "subtotal.coffee" 15 | ], 16 | "keywords": [ 17 | "pivot", 18 | "crosstab", 19 | "grid", 20 | "table", 21 | "pivottable", 22 | "pivotgrid", 23 | "pivotchart", 24 | "jquery", 25 | "subtotal", 26 | "expand", 27 | "collapse", 28 | "summary" 29 | ], 30 | "homepage": "https://github.com/nagarajanchinnasamy/subtotal", 31 | "repository": { 32 | "type": "git", 33 | "url": "git://github.com/nagarajanchinnasamy/subtotal.git" 34 | }, 35 | "dependencies": { 36 | "pivottable": ">=2.7.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nagarajanchinnasamy/subtotal", 3 | "description": "Subtotal.js is a JavaScript plugin for PivotTable.js. It renders subtotals of rows and columns with the ability to expand and collapse rows.", 4 | "authors": [ 5 | { 6 | "name": "Nagarajan Chinnasamy", 7 | "email": "nagarajanchinnasamy@gmail.com", 8 | "homepage": "https://github.com/nagarajanchinnasamy" 9 | } 10 | ], 11 | "keywords": [ 12 | "pivot", 13 | "crosstab", 14 | "grid", 15 | "table", 16 | "pivottable", 17 | "pivotgrid", 18 | "pivotchart", 19 | "jquery", 20 | "jquery-plugin", 21 | "subtotal", 22 | "expand", 23 | "collapse", 24 | "summary" 25 | ], 26 | "type": "library", 27 | "license": "MIT", 28 | "minimum-stability": "stable", 29 | "homepage": "http://nagarajanchinnasamy.com/subtotal", 30 | "require": { 31 | "nicolaskruchten/pivottable": "^2.7.0" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /dist/pivot_spec.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var fixtureData, fixtureData2; 3 | 4 | fixtureData = [["name", "gender", "colour", "birthday", "trials", "successes"], ["Nick", "male", "blue", "1982-11-07", 103, 12], ["Jane", "female", "red", "1982-11-08", 95, 25], ["John", "male", "blue", "1982-12-08", 112, 30], ["Carol", "female", "yellow", "1983-11-11", 102, 14], ["Raj", "male", "blue", "1982-11-07", 103, 12], ["Rani", "female", "red", "1982-11-08", 95, 25], ["Joshi", "male", "blue", "1982-12-09", 112, 12], ["Vel", "male", "yellow", "1982-12-01", 112, 25], ["Sai", "male", "red", "1982-11-08", 112, 30], ["Geeth", "female", "blue", "1982-12-03", 112, 14], ["Malar", "male", "red", "1982-11-05", 112, 12], ["Nila", "male", "blue", "1982-12-07", 112, 25], ["Yaazhi", "male", "yellow", "1982-12-06", 112, 30], ["Mukhi", "male", "yellow", "1982-11-07", 112, 14]]; 5 | 6 | fixtureData2 = [["name", "gender", "colour", "birthday", "trials", "successes"], ["Nick", "male", "blue", "1982-11-07", 103, 12], ["Jane", "female", "red", "1982-11-08", 95, 25], ["John", "male", "blue", "1982-12-08", 112, 30], ["Carol", "female", "yellow", "1983-12-08", 102, 14]]; 7 | 8 | describe("$.pivotUI()", function() { 9 | describe("with no rows/cols, default count aggregator, subtotal renderer", function() { 10 | var table; 11 | table = null; 12 | beforeEach(function(done) { 13 | return table = $("
a | b |
---|---|
1 | 2 |
3 | 4 |
a | b |
---|---|
1 | 2 |
3 | 4 |
To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /examples/110_collapse_rowscols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/137_as_fraction_of_parent_row.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/139_as_fraction_of_parent_column.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/155_custom_collapse_expand_arrow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /examples/160_event_handlers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /examples/170_hide_subtotal_on_expand.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/180_disable_subtotal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/185_disable_expandcollapse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/190_disable_after.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /examples/195_rowsubtotal_at_bottom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/205_default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /examples/210_collapse_rowscols.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /examples/237_as_fraction_of_parent_row.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/239_as_fraction_of_parent_column.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /examples/255_custom_collapse_expand_arrow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/260_event_handlers.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Click on a value cell to view the list of contributors. Scroll down to view the code.
70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/270_hide_subtotal_on_expand.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/280_disable_subtotal.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/285_disable_expandcollapse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/290_disable_after.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /examples/295_rowsubtotal_at_bottom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |To expand and collapse rows and columns, click on ▶ and ◢ arrows in the table. Scroll down to view the code.
50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /examples/css/gh-fork-ribbon.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * "Fork me on GitHub" CSS ribbon v0.1.1 | MIT License 3 | * https://github.com/simonwhitaker/github-fork-ribbon-css 4 | */ 5 | 6 | /* Left will inherit from right (so we don't need to duplicate code) */ 7 | .github-fork-ribbon { 8 | /* The right and left classes determine the side we attach our banner to */ 9 | position: absolute; 10 | 11 | /* Add a bit of padding to give some substance outside the "stitching" */ 12 | padding: 2px 0; 13 | 14 | /* Set the base colour */ 15 | background-color: #a00; 16 | 17 | /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ 18 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.15))); 19 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 20 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 21 | background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 22 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 23 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 24 | 25 | /* Add a drop shadow */ 26 | -webkit-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 27 | -moz-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 28 | box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 29 | 30 | /* Set the font */ 31 | font: 700 13px "Helvetica Neue", Helvetica, Arial, sans-serif; 32 | 33 | z-index: 9999; 34 | pointer-events: auto; 35 | } 36 | 37 | .github-fork-ribbon a, 38 | .github-fork-ribbon a:hover { 39 | /* Set the text properties */ 40 | color: #fff; 41 | text-decoration: none; 42 | text-shadow: 0 -1px rgba(0, 0, 0, 0.5); 43 | text-align: center; 44 | 45 | /* Set the geometry. If you fiddle with these you'll also need 46 | to tweak the top and right values in .github-fork-ribbon. */ 47 | width: 200px; 48 | line-height: 20px; 49 | 50 | /* Set the layout properties */ 51 | display: inline-block; 52 | padding: 2px 0; 53 | 54 | /* Add "stitching" effect */ 55 | border-width: 1px 0; 56 | border-style: dotted; 57 | border-color: #fff; 58 | border-color: rgba(255, 255, 255, 0.7); 59 | } 60 | 61 | .github-fork-ribbon-wrapper { 62 | width: 150px; 63 | height: 150px; 64 | position: absolute; 65 | overflow: hidden; 66 | top: 0; 67 | z-index: 9999; 68 | pointer-events: none; 69 | } 70 | 71 | .github-fork-ribbon-wrapper.fixed { 72 | position: fixed; 73 | } 74 | 75 | .github-fork-ribbon-wrapper.left { 76 | left: 0; 77 | } 78 | 79 | .github-fork-ribbon-wrapper.right { 80 | right: 0; 81 | } 82 | 83 | .github-fork-ribbon-wrapper.left-bottom { 84 | position: fixed; 85 | top: inherit; 86 | bottom: 0; 87 | left: 0; 88 | } 89 | 90 | .github-fork-ribbon-wrapper.right-bottom { 91 | position: fixed; 92 | top: inherit; 93 | bottom: 0; 94 | right: 0; 95 | } 96 | 97 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 98 | top: 42px; 99 | right: -43px; 100 | 101 | -webkit-transform: rotate(45deg); 102 | -moz-transform: rotate(45deg); 103 | -ms-transform: rotate(45deg); 104 | -o-transform: rotate(45deg); 105 | transform: rotate(45deg); 106 | } 107 | 108 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 109 | top: 42px; 110 | left: -43px; 111 | 112 | -webkit-transform: rotate(-45deg); 113 | -moz-transform: rotate(-45deg); 114 | -ms-transform: rotate(-45deg); 115 | -o-transform: rotate(-45deg); 116 | transform: rotate(-45deg); 117 | } 118 | 119 | 120 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 121 | top: 80px; 122 | left: -43px; 123 | 124 | -webkit-transform: rotate(45deg); 125 | -moz-transform: rotate(45deg); 126 | -ms-transform: rotate(45deg); 127 | -o-transform: rotate(45deg); 128 | transform: rotate(45deg); 129 | } 130 | 131 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 132 | top: 80px; 133 | right: -43px; 134 | 135 | -webkit-transform: rotate(-45deg); 136 | -moz-transform: rotate(-45deg); 137 | -ms-transform: rotate(-45deg); 138 | -o-transform: rotate(-45deg); 139 | transform: rotate(-45deg); 140 | } 141 | -------------------------------------------------------------------------------- /examples/css/gh-fork-ribbon.ie.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * "Fork me on GitHub" CSS ribbon v0.1.1 | MIT License 3 | * https://github.com/simonwhitaker/github-fork-ribbon-css 4 | */ 5 | 6 | /* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and 7 | * http://www.useragentman.com/IETransformsTranslator */ 8 | 9 | .github-fork-ribbon { 10 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000'); 11 | } 12 | 13 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 14 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 15 | top: -22px; 16 | right: -62px; 17 | 18 | /* IE8+ */ 19 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 20 | /* IE6 and 7 */ 21 | filter: progid:DXImageTransform.Microsoft.Matrix( 22 | M11=0.7071067811865474, 23 | M12=-0.7071067811865477, 24 | M21=0.7071067811865477, 25 | M22=0.7071067811865474, 26 | SizingMethod='auto expand' 27 | ); 28 | } 29 | 30 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 31 | top: -22px; 32 | left: -22px; 33 | 34 | /* IE8+ */ 35 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 36 | /* IE6 and 7 */ 37 | filter: progid:DXImageTransform.Microsoft.Matrix( 38 | M11=0.7071067811865483, 39 | M12=0.7071067811865467, 40 | M21=-0.7071067811865467, 41 | M22=0.7071067811865483, 42 | SizingMethod='auto expand' 43 | ); 44 | } 45 | 46 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 47 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 48 | top: 12px; 49 | left: -22px; 50 | 51 | 52 | /* IE8+ */ 53 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 54 | /* IE6 and 7 */ 55 | /* filter: progid:DXImageTransform.Microsoft.Matrix( 56 | M11=0.7071067811865474, 57 | M12=-0.7071067811865477, 58 | M21=0.7071067811865477, 59 | M22=0.7071067811865474, 60 | SizingMethod='auto expand' 61 | ); 62 | */} 63 | 64 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 65 | top: 12px; 66 | right: -62px; 67 | 68 | /* IE8+ */ 69 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 70 | /* IE6 and 7 */ 71 | filter: progid:DXImageTransform.Microsoft.Matrix( 72 | M11=0.7071067811865483, 73 | M12=0.7071067811865467, 74 | M21=-0.7071067811865467, 75 | M22=0.7071067811865483, 76 | SizingMethod='auto expand' 77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /examples/data/montreal_2014.csv: -------------------------------------------------------------------------------- 1 | Date,Max Temp (C),Min Temp (C),Mean Temp (C),Total Rain (mm),Total Snow (cm) 2 | 2014-01-01,-16.5,-24.6,-20.6,0,0 3 | 2014-01-02,-22.6,-27.3,-25,0,1.4 4 | 2014-01-03,-19.2,-24.3,-21.8,0,0 5 | 2014-01-04,-8.6,-23.3,-16,0,0 6 | 2014-01-05,0.3,-12.6,-6.2,12.2,1.8 7 | 2014-01-06,7.1,-11.1,-2,14.3,0.4 8 | 2014-01-07,-11.1,-16.6,-13.9,0,0.2 9 | 2014-01-08,-8.7,-14.7,-11.7,0,0 10 | 2014-01-09,-7.8,-12.3,-10.1,0,0 11 | 2014-01-10,-4.5,-14.2,-9.4,0,0 12 | 2014-01-11,7.3,-6.4,0.5,6.2,0 13 | 2014-01-12,4.5,0.3,2.4,0,0 14 | 2014-01-13,5.1,-0.9,2.1,0,0 15 | 2014-01-14,4.2,-1.3,1.5,5.4,0 16 | 2014-01-15,1.9,-4.1,-1.1,0.2,0 17 | 2014-01-16,-0.5,-5.1,-2.8,0,0 18 | 2014-01-17,0.6,-5.2,-2.3,0,0.6 19 | 2014-01-18,2.4,-7,-2.3,0,0.2 20 | 2014-01-19,-2.2,-6.4,-4.3,0,1.4 21 | 2014-01-20,-6.4,-20.7,-13.6,0,1.6 22 | 2014-01-21,-19.1,-23.8,-21.5,0,0 23 | 2014-01-22,-17.6,-25.4,-21.5,0,0 24 | 2014-01-23,-17.5,-23.2,-20.4,0,0 25 | 2014-01-24,-9.7,-23.8,-16.8,0,0 26 | 2014-01-25,-5.3,-15.5,-10.4,0,2 27 | 2014-01-26,-13.8,-21.5,-17.7,0,0.4 28 | 2014-01-27,-6.4,-17.9,-12.2,0,5.6 29 | 2014-01-28,-10.8,-19.9,-15.4,0,0 30 | 2014-01-29,-9.6,-14.2,-11.9,0,0 31 | 2014-01-30,-4.4,-12.7,-8.6,0,0 32 | 2014-01-31,1.3,-7.1,-2.9,0,0 33 | 2014-02-01,-1.3,-10.9,-6.1,0,12 34 | 2014-02-02,-1.1,-7.9,-4.5,0,4.6 35 | 2014-02-03,-6.9,-15.3,-11.1,0,0 36 | 2014-02-04,-6.1,-16.8,-11.5,0,0 37 | 2014-02-05,-7.9,-15.6,-11.8,0,5.4 38 | 2014-02-06,-9.3,-20,-14.7,0,0.4 39 | 2014-02-07,-7.6,-12.9,-10.3,0,0 40 | 2014-02-08,-5.7,-12.3,-9,0,0 41 | 2014-02-09,-7.1,-12.5,-9.8,0,1.4 42 | 2014-02-10,-6.8,-16.1,-11.5,0,0.4 43 | 2014-02-11,-11.1,-19.6,-15.4,0,0 44 | 2014-02-12,-9.8,-23.1,-16.5,0,0 45 | 2014-02-13,-6.1,-18.4,-12.3,0,2 46 | 2014-02-14,-2.2,-6.1,-4.2,0,12.4 47 | 2014-02-15,-5.6,-11.8,-8.7,0,0 48 | 2014-02-16,-9.5,-15.8,-12.7,0,0 49 | 2014-02-17,-9.9,-17.4,-13.7,0,0 50 | 2014-02-18,-3.4,-15.6,-9.5,0,2.4 51 | 2014-02-19,1.5,-5.4,-2,0,0 52 | 2014-02-20,2.8,-4.9,-1.1,0,0 53 | 2014-02-21,4.2,-0.6,1.8,19.2,0 54 | 2014-02-22,6.1,-1.8,2.2,0,0 55 | 2014-02-23,1.7,-4.3,-1.3,0,0 56 | 2014-02-24,-4.3,-10.6,-7.5,0,0.2 57 | 2014-02-25,-9,-12.9,-11,0,0 58 | 2014-02-26,-9.7,-14.8,-12.3,0,1.6 59 | 2014-02-27,-6.9,-14.8,-10.9,0,0.4 60 | 2014-02-28,-12.1,-18.2,-15.2,0,0 61 | 2014-03-01,-3.4,-14.2,-8.8,0,2 62 | 2014-03-02,-5.5,-16.6,-11.1,0,0.6 63 | 2014-03-03,-13,-18.1,-15.6,0,0 64 | 2014-03-04,-11,-18.5,-14.8,0,1.4 65 | 2014-03-05,-9,-17.6,-13.3,0,0 66 | 2014-03-06,-6.9,-19.4,-13.2,0,0 67 | 2014-03-07,0.2,-17.8,-8.8,0,0 68 | 2014-03-08,3.3,-6.2,-1.5,0,0.8 69 | 2014-03-09,-3.8,-12.6,-8.2,0,3 70 | 2014-03-10,0.7,-5.4,-2.4,0,4 71 | 2014-03-11,5.2,0.2,2.7,0,0 72 | 2014-03-12,1.7,-11.9,-5.1,0,16.6 73 | 2014-03-13,-6.7,-15.6,-11.2,0,2.4 74 | 2014-03-14,2.1,-16.7,-7.3,0,0 75 | 2014-03-15,4.6,-8.4,-1.9,0.2,0.2 76 | 2014-03-16,-8.4,-14.1,-11.3,0,0 77 | 2014-03-17,-6.8,-16.8,-11.8,0,0 78 | 2014-03-18,-2.1,-13.8,-8,0,0 79 | 2014-03-19,3.2,-9,-2.9,1.4,0.4 80 | 2014-03-20,2.9,-0.3,1.3,2.4,0.2 81 | 2014-03-21,2.5,-3,-0.3,0,0.2 82 | 2014-03-22,0.6,-3.8,-1.6,0,9.6 83 | 2014-03-23,0,-13.6,-6.8,0,0 84 | 2014-03-24,-4.7,-16.5,-10.6,0,0 85 | 2014-03-25,-0.6,-11.7,-6.2,0,0 86 | 2014-03-26,-2.4,-10.4,-6.4,0,0 87 | 2014-03-27,-1.6,-13.1,-7.4,0,0.2 88 | 2014-03-28,4.1,-2.7,0.7,9.2,4.2 89 | 2014-03-29,3.2,0.5,1.9,0,0 90 | 2014-03-30,0.5,-1.4,-0.5,0,15.2 91 | 2014-03-31,6.2,-1.8,2.2,0,0 92 | 2014-04-01,5,-3.5,0.8,0,0 93 | 2014-04-02,5,1.2,3.1,0,0 94 | 2014-04-03,2.9,-2.2,0.4,0,0 95 | 2014-04-04,7,-3.4,1.8,16.8,0 96 | 2014-04-05,4.7,0.4,2.6,1.2,0 97 | 2014-04-06,7.1,-1.2,3,0,0 98 | 2014-04-07,13,-0.1,6.5,6.4,0 99 | 2014-04-08,5.2,2.6,3.9,22.6,0 100 | 2014-04-09,4.8,-0.9,2,0,0 101 | 2014-04-10,16.2,-1.6,7.3,4,0 102 | 2014-04-11,11.8,2.9,7.4,0,0 103 | 2014-04-12,14.3,1.5,7.9,0,0 104 | 2014-04-13,11.7,2.6,7.2,8.2,0 105 | 2014-04-14,24.5,2.2,13.4,9,0 106 | 2014-04-15,16.2,-5.1,5.6,8.6,0.4 107 | 2014-04-16,0.6,-7.3,-3.4,0,0 108 | 2014-04-17,7.7,-2.9,2.4,0,0 109 | 2014-04-18,10.8,1.7,6.3,0,0 110 | 2014-04-19,10.6,0.9,5.8,0.4,0 111 | 2014-04-20,14.1,-2.6,5.8,0,0 112 | 2014-04-21,19.2,7.4,13.3,1.2,0 113 | 2014-04-22,12.7,7,9.9,10.4,0 114 | 2014-04-23,11.8,3.6,7.7,0,0 115 | 2014-04-24,13.2,1.4,7.3,0,0 116 | 2014-04-25,11.9,-0.3,5.8,0,0 117 | 2014-04-26,8.4,2.8,5.6,11.4,0 118 | 2014-04-27,10.4,2.3,6.4,2,0 119 | 2014-04-28,12.3,1.8,7.1,0,0 120 | 2014-04-29,16.5,5.7,11.1,2.8,0 121 | 2014-04-30,10.6,5.1,7.9,30.8,0 122 | 2014-05-01,16.1,6.1,11.1,8.2,0 123 | 2014-05-02,13,8.1,10.6,0.6,0 124 | 2014-05-03,16.3,7.9,12.1,0.8,0 125 | 2014-05-04,12,7.3,9.7,19.4,0 126 | 2014-05-05,13.4,6.3,9.9,0,0 127 | 2014-05-06,15,4.2,9.6,0,0 128 | 2014-05-07,15.8,3.2,9.5,0,0 129 | 2014-05-08,16.8,5.2,11,0,0 130 | 2014-05-09,20.8,8.8,14.8,4.2,0 131 | 2014-05-10,23.8,11.9,17.9,4.4,0 132 | 2014-05-11,21.9,11.4,16.7,0,0 133 | 2014-05-12,22.4,9.1,15.8,0,0 134 | 2014-05-13,18.4,8.3,13.4,1.4,0 135 | 2014-05-14,24.9,13.6,19.3,0,0 136 | 2014-05-15,28.2,17.5,22.9,0,0 137 | 2014-05-16,22.2,10.3,16.3,29.8,0 138 | 2014-05-17,15.4,8.3,11.9,10.8,0 139 | 2014-05-18,16.6,6.3,11.5,0,0 140 | 2014-05-19,20.2,9.2,14.7,0,0 141 | 2014-05-20,22.8,8.7,15.8,0,0 142 | 2014-05-21,23.8,10.4,17.1,0,0 143 | 2014-05-22,19,12.9,16,1,0 144 | 2014-05-23,20.8,10.8,15.8,0,0 145 | 2014-05-24,21.4,11.4,16.4,0,0 146 | 2014-05-25,25.2,9.4,17.3,4.6,0 147 | 2014-05-26,22.8,16.3,19.6,3.6,0 148 | 2014-05-27,16.9,8.6,12.8,4.2,0 149 | 2014-05-28,16.1,8.1,12.1,0.6,0 150 | 2014-05-29,20.5,6.1,13.3,0,0 151 | 2014-05-30,22.6,12,17.3,2,0 152 | 2014-05-31,20.2,9.1,14.7,0,0 153 | 2014-06-01,25.2,9.7,17.5,0,0 154 | 2014-06-02,30.4,15.7,23.1,0,0 155 | 2014-06-03,28.1,19.1,23.6,22,0 156 | 2014-06-04,21.3,14,17.7,0.2,0 157 | 2014-06-05,17,13.4,15.2,0.6,0 158 | 2014-06-06,23,12.9,18,0,0 159 | 2014-06-07,27.5,13.3,20.4,0,0 160 | 2014-06-08,28,14.6,21.3,0,0 161 | 2014-06-09,27.9,19.2,23.6,0,0 162 | 2014-06-10,24.6,15.8,20.2,0.4,0 163 | 2014-06-11,24.1,13.1,18.6,10.4,0 164 | 2014-06-12,17.9,12.9,15.4,26.2,0 165 | 2014-06-13,19.9,16.8,18.4,41.4,0 166 | 2014-06-14,19.8,14.6,17.2,1.4,0 167 | 2014-06-15,23.6,13.6,18.6,0,0 168 | 2014-06-16,24.8,11.4,18.1,0,0 169 | 2014-06-17,27.2,14,20.6,23.4,0 170 | 2014-06-18,25.7,16.6,21.2,2,0 171 | 2014-06-19,24.6,14.6,19.6,0,0 172 | 2014-06-20,21.7,12.1,16.9,0,0 173 | 2014-06-21,22.1,10.4,16.3,0,0 174 | 2014-06-22,23.8,11.5,17.7,0,0 175 | 2014-06-23,26.8,13.4,20.1,0,0 176 | 2014-06-24,21.9,19.2,20.6,40,0 177 | 2014-06-25,24,18.2,21.1,0.2,0 178 | 2014-06-26,26.3,17,21.7,0,0 179 | 2014-06-27,28.4,15,21.7,0,0 180 | 2014-06-28,29.2,16.3,22.8,0,0 181 | 2014-06-29,30.7,19.1,24.9,0,0 182 | 2014-06-30,29.7,22.8,26.3,0,0 183 | 2014-07-01,33.2,21.6,27.4,0,0 184 | 2014-07-02,29.8,21.2,25.5,0,0 185 | 2014-07-03,24.4,18.9,21.7,0.6,0 186 | 2014-07-04,23.4,16,19.7,3.2,0 187 | 2014-07-05,27.7,14.5,21.1,0,0 188 | 2014-07-06,27.7,18.7,23.2,0,0 189 | 2014-07-07,23.4,19.5,21.5,10,0 190 | 2014-07-08,30.6,19,24.8,7,0 191 | 2014-07-09,23.5,17.7,20.6,0,0 192 | 2014-07-10,23.1,14.3,18.7,0,0 193 | 2014-07-11,25.4,13.4,19.4,0,0 194 | 2014-07-12,27.4,16,21.7,0,0 195 | 2014-07-13,23.9,19.6,21.8,11,0 196 | 2014-07-14,24.1,17.6,20.9,0,0 197 | 2014-07-15,21.9,17.6,19.8,2.8,0 198 | 2014-07-16,24.8,16.6,20.7,0,0 199 | 2014-07-17,23.4,14,18.7,0.2,0 200 | 2014-07-18,26.2,14,20.1,0,0 201 | 2014-07-19,27.5,16.5,22,0,0 202 | 2014-07-20,28,18.9,23.5,0,0 203 | 2014-07-21,29.4,20.8,25.1,0,0 204 | 2014-07-22,29.7,20.5,25.1,0,0 205 | 2014-07-23,26.4,17.7,22.1,11.4,0 206 | 2014-07-24,22.9,13.8,18.4,0,0 207 | 2014-07-25,25.8,14.7,20.3,0,0 208 | 2014-07-26,26,15.9,21,0.2,0 209 | 2014-07-27,25,18,21.5,10.2,0 210 | 2014-07-28,18.5,14.2,16.4,9.8,0 211 | 2014-07-29,21.3,12,16.7,0,0 212 | 2014-07-30,24,13.8,18.9,0.8,0 213 | 2014-07-31,21.8,14.3,18.1,12.8,0 214 | 2014-08-01,26.1,14.8,20.5,0,0 215 | 2014-08-02,27.8,16.1,22,0,0 216 | 2014-08-03,28,16.6,22.3,0,0 217 | 2014-08-04,27.7,18.3,23,0.6,0 218 | 2014-08-05,25.4,17.7,21.6,1.6,0 219 | 2014-08-06,25.6,14.9,20.3,0,0 220 | 2014-08-07,23.1,15.9,19.5,6.2,0 221 | 2014-08-08,27,14,20.5,0,0 222 | 2014-08-09,28.7,15.4,22.1,0,0 223 | 2014-08-10,28.6,16.6,22.6,0,0 224 | 2014-08-11,29.7,17.8,23.8,0,0 225 | 2014-08-12,27.9,19.1,23.5,2.2,0 226 | 2014-08-13,21.1,16,18.6,44.4,0 227 | 2014-08-14,17.6,12,14.8,0,0 228 | 2014-08-15,17.5,12.2,14.9,5.2,0 229 | 2014-08-16,18.5,14.6,16.6,13.2,0 230 | 2014-08-17,22.8,14.6,18.7,0,0 231 | 2014-08-18,22.2,11.7,17,0,0 232 | 2014-08-19,23.5,10.6,17.1,0,0 233 | 2014-08-20,27.3,12.8,20.1,0,0 234 | 2014-08-21,23.1,17.9,20.5,0,0 235 | 2014-08-22,23.8,17.3,20.6,0,0 236 | 2014-08-23,26,14.7,20.4,0,0 237 | 2014-08-24,27.7,14.5,21.1,0,0 238 | 2014-08-25,28.9,17.6,23.3,0,0 239 | 2014-08-26,28.6,17,22.8,0.4,0 240 | 2014-08-27,25.6,18.4,22,0,0 241 | 2014-08-28,21.9,14.2,18.1,0,0 242 | 2014-08-29,22.6,11.4,17,0,0 243 | 2014-08-30,27.3,16.7,22,0.2,0 244 | 2014-08-31,25.3,19.8,22.6,11.2,0 245 | 2014-09-01,25.9,18.7,22.3,0,0 246 | 2014-09-02,28.6,18.3,23.5,4.4,0 247 | 2014-09-03,25.5,18,21.8,0,0 248 | 2014-09-04,27.7,16.3,22,0.4,0 249 | 2014-09-05,30.8,20.1,25.5,3,0 250 | 2014-09-06,23.2,10.6,16.9,5,0 251 | 2014-09-07,22.1,10.6,16.4,0,0 252 | 2014-09-08,24.7,11.4,18.1,0,0 253 | 2014-09-09,23.1,14.3,18.7,0,0 254 | 2014-09-10,24.8,14.6,19.7,0,0 255 | 2014-09-11,25.1,10.1,17.6,7.2,0 256 | 2014-09-12,14.1,6.1,10.1,0,0 257 | 2014-09-13,12.6,5.9,9.3,19,0 258 | 2014-09-14,10.9,4.6,7.8,0,0 259 | 2014-09-15,18.3,4.8,11.6,0.2,0 260 | 2014-09-16,18.6,9.3,14,0.4,0 261 | 2014-09-17,17.2,8,12.6,2.6,0 262 | 2014-09-18,12.4,3.4,7.9,0.2,0 263 | 2014-09-19,13,1.2,7.1,0,0 264 | 2014-09-20,19.8,9.2,14.5,0.2,0 265 | 2014-09-21,23.2,14,18.6,6.2,0 266 | 2014-09-22,14,6.9,10.5,0,0 267 | 2014-09-23,17.2,7.3,12.3,1.2,0 268 | 2014-09-24,21.8,6.7,14.3,0,0 269 | 2014-09-25,22.8,10.8,16.8,0,0 270 | 2014-09-26,25.5,11.9,18.7,0,0 271 | 2014-09-27,25.5,12.8,19.2,0,0 272 | 2014-09-28,24.8,14.8,19.8,0,0 273 | 2014-09-29,18,8.7,13.4,0,0 274 | 2014-09-30,17.3,9.3,13.3,0,0 275 | 2014-10-01,16.6,10.4,13.5,0,0 276 | 2014-10-02,20.3,8.7,14.5,0,0 277 | 2014-10-03,23.1,8.8,16,0,0 278 | 2014-10-04,16.6,9.8,13.2,23.6,0 279 | 2014-10-05,13.7,7.9,10.8,0,0 280 | 2014-10-06,16.3,8,12.2,0.4,0 281 | 2014-10-07,18.2,11.9,15.1,4,0 282 | 2014-10-08,17.5,8.7,13.1,19.8,0 283 | 2014-10-09,12.5,5.2,8.9,0.8,0 284 | 2014-10-10,11.8,4.6,8.2,0,0 285 | 2014-10-11,13.1,2.6,7.9,0,0 286 | 2014-10-12,13.2,2.6,7.9,0,0 287 | 2014-10-13,17.8,2.2,10,0,0 288 | 2014-10-14,24.8,13.7,19.3,0,0 289 | 2014-10-15,23.6,18.2,20.9,6.4,0 290 | 2014-10-16,21.7,14.6,18.2,7.6,0 291 | 2014-10-17,18.4,14.3,16.4,0.4,0 292 | 2014-10-18,16.9,5.9,11.4,1.4,0 293 | 2014-10-19,7.5,3,5.3,0,0 294 | 2014-10-20,6.8,1.8,4.3,1.2,0 295 | 2014-10-21,7.4,5.6,6.5,3,0 296 | 2014-10-22,12.6,6,9.3,0,0 297 | 2014-10-23,8.6,6.9,7.8,5.8,0 298 | 2014-10-24,11.5,4.9,8.2,1,0 299 | 2014-10-25,13.1,5.2,9.2,3.8,0 300 | 2014-10-26,10.9,7.2,9.1,0.8,0 301 | 2014-10-27,11.2,5.7,8.5,0.2,0 302 | 2014-10-28,13.7,7,10.4,6.2,0 303 | 2014-10-29,14.2,8.5,11.4,0.6,0 304 | 2014-10-30,10,2.8,6.4,0,0 305 | 2014-10-31,7.2,1.5,4.4,0,0 306 | 2014-11-01,6.9,1.9,4.4,0,0 307 | 2014-11-02,7.6,-0.3,3.7,0,0 308 | 2014-11-03,6.3,-1,2.7,0,0 309 | 2014-11-04,11.7,4.3,8,2.4,0 310 | 2014-11-05,12.2,5.7,9,2,0 311 | 2014-11-06,8.3,2.6,5.5,3,0 312 | 2014-11-07,4.8,-0.2,2.3,1.8,0 313 | 2014-11-08,4.4,-1.4,1.5,0.2,0 314 | 2014-11-09,6.5,2.7,4.6,0,0 315 | 2014-11-10,7.1,3.5,5.3,0,0 316 | 2014-11-11,12.5,0.2,6.4,0,0 317 | 2014-11-12,8.4,1.6,5,3.8,0 318 | 2014-11-13,4.7,-0.8,2,0,0 319 | 2014-11-14,2.1,-4,-1,0,0 320 | 2014-11-15,1.6,-4.9,-1.7,0,0 321 | 2014-11-16,3.3,-0.6,1.4,0,0.8 322 | 2014-11-17,1.5,-0.6,0.5,0,12.6 323 | 2014-11-18,1.5,-4.7,-1.6,0,2 324 | 2014-11-19,-2,-7.7,-4.9,0,0.6 325 | 2014-11-20,-0.1,-5.1,-2.6,0,0.4 326 | 2014-11-21,-4.6,-8.2,-6.4,0,0 327 | 2014-11-22,3,-7.9,-2.5,3.4,0.4 328 | 2014-11-23,7.9,2.8,5.4,0,0 329 | 2014-11-24,18,6.8,12.4,16,0 330 | 2014-11-25,7.8,2,4.9,0,0 331 | 2014-11-26,2.5,-0.9,0.8,0,0 332 | 2014-11-27,-0.1,-3.8,-2,0,0 333 | 2014-11-28,-2.8,-8.2,-5.5,0,0.4 334 | 2014-11-29,-0.8,-8.3,-4.6,0,0 335 | 2014-11-30,6.8,-0.9,3,0.6,0 336 | 2014-12-01,6.2,-8.7,-1.3,0.2,0 337 | 2014-12-02,-3.2,-14.9,-9.1,0,6.2 338 | 2014-12-03,3.3,-3.2,0.1,5.4,0.6 339 | 2014-12-04,0.1,-11.3,-5.6,0,0 340 | 2014-12-05,-4.6,-13.1,-8.9,0,2.2 341 | 2014-12-06,-1.1,-6,-3.6,0,0.6 342 | 2014-12-07,-4.9,-12.9,-8.9,0,0 343 | 2014-12-08,-2.3,-13.9,-8.1,0,0 344 | 2014-12-09,0.2,-4.8,-2.3,0,6.8 345 | 2014-12-10,0.2,-0.8,-0.3,0,20 346 | 2014-12-11,0.4,-3.2,-1.4,0.2,4.8 347 | 2014-12-12,-1.7,-4.2,-3,0,2 348 | 2014-12-13,-1.6,-5.9,-3.8,0,0 349 | 2014-12-14,-0.9,-4.8,-2.9,0,0 350 | 2014-12-15,-0.1,-1.9,-1,0,0 351 | 2014-12-16,0.6,-1.4,-0.4,0,0 352 | 2014-12-17,0.6,-0.2,0.2,2,0.2 353 | 2014-12-18,0.4,-2.4,-1,0,2 354 | 2014-12-19,-2.4,-11.5,-7,0,0 355 | 2014-12-20,-7.7,-15.6,-11.7,0,0 356 | 2014-12-21,-7.2,-10.3,-8.8,0,0.2 357 | 2014-12-22,-5.5,-8.6,-7.1,0,0 358 | 2014-12-23,3.1,-5.8,-1.4,2.6,3 359 | 2014-12-24,6.2,2.3,4.3,32,0 360 | 2014-12-25,7.8,3.5,5.7,1,0 361 | 2014-12-26,4.5,1.4,3,0,0 362 | 2014-12-27,7.4,0.9,4.2,0.2,0 363 | 2014-12-28,8.3,-3.3,2.5,0.8,0 364 | 2014-12-29,-0.7,-11.1,-5.9,0,0 365 | 2014-12-30,-10.6,-14.5,-12.6,0,0 366 | 2014-12-31,-6.3,-14.9,-10.6,0,0 -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |An open-source JavaScript plugin for PivotTable.js to render rows and columns of a pivot table with subtotals and lets you expand and collapse subtotals.
42 |43 |
44 |").append(
9 | $("").text($(this).text())
10 | .css({"font-family": "Source Code Pro"})
11 | ));
12 | $('pre code').each(function(i, block) {
13 | hljs.highlightBlock(block);
14 | });
15 | });
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/gulpFile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | git = require('gulp-git'),
3 | bump = require('gulp-bump'),
4 | filter = require('gulp-filter'),
5 | tag_version = require('gulp-tag-version'),
6 | runSequence = require('run-sequence').use(gulp),
7 | spawn = require('child_process').spawn,
8 | coffee = require('gulp-coffee'),
9 | gutil = require('gulp-util'),
10 | uglify = require("gulp-uglify"),
11 | rename = require('gulp-rename'),
12 | sourcemaps = require('gulp-sourcemaps'),
13 | concat = require('gulp-concat'),
14 | cleanCSS = require('gulp-minify-css'),
15 | serve = require('gulp-serve');
16 | debug = require('gulp-debug');
17 |
18 | gulp.task('makeCss', function() {
19 | gulp.src('./subtotal.css')
20 | .pipe(gulp.dest('./dist/'))
21 |
22 | gulp.src('./subtotal.css')
23 | .pipe(cleanCSS())
24 | .pipe(concat('subtotal.min.css'))//trick to output to new file
25 | .pipe(gulp.dest('./dist/'))
26 | });
27 |
28 | gulp.task('makeJs', function() {
29 |
30 | gulp.src(['./*.coffee', './tests/*.coffee'])
31 | //compile to js (and create map files)
32 | .pipe(sourcemaps.init())
33 | .pipe(coffee()).on('error', gutil.log)
34 | .pipe(sourcemaps.write('./'))
35 | .pipe(gulp.dest('./dist'))
36 |
37 | //minify js files as well
38 | .pipe(filter('dist/*.js'))//filter, to avoid doing this processing on the map files generated above
39 | .pipe(rename({
40 | suffix: '.min'
41 | }))
42 | .pipe(sourcemaps.init({loadMaps: true}))//load the source maps generated in the first step
43 | .pipe(uglify())
44 | .pipe(sourcemaps.write('./'))
45 | // .pipe(debug())
46 | .pipe(gulp.dest('./dist'));
47 | });
48 |
49 |
50 |
51 | function inc(importance) {
52 | // get all the files to bump version in
53 | return gulp.src(['./package.json', './bower.json'])
54 | // bump the version number in those files
55 | .pipe(bump({type: importance}))
56 | // save it back to filesystem
57 | .pipe(gulp.dest('./'));
58 | }
59 |
60 | gulp.task('publish', function (done) {
61 | spawn('npm', ['publish'], { stdio: 'inherit' }).on('close', done);
62 | });
63 |
64 | gulp.task('push', function (done) {
65 | git.push('origin', 'master', {args: '--tags'}, function (err) {
66 | if (err) throw err;
67 | });
68 | });
69 |
70 |
71 | gulp.task('tag', function() {
72 | return gulp.src(['./package.json', './bower.json'])
73 | .pipe(git.commit('version bump'))
74 | // read only one file to get the version number
75 | .pipe(filter('package.json'))
76 | .pipe(tag_version());
77 | });
78 |
79 |
80 | gulp.task('bumpPatch', function() { return inc('patch'); })
81 | gulp.task('bumpMinor', function() { return inc('minor'); })
82 | gulp.task('bumpMajor', function() { return inc('major'); })
83 |
84 | gulp.task('patch', function() {
85 | runSequence('bumpPatch', 'default', 'tag', 'publish', 'push');
86 | });
87 | gulp.task('minor', function() {
88 | runSequence('bumpMinor', 'default', 'tag', 'publish', 'push');
89 | });
90 | gulp.task('major', function() {
91 | runSequence('bumpMajor', 'default', 'tag', 'publish', 'push');
92 | });
93 |
94 | gulp.task('serve', serve('.'));
95 |
96 | gulp.task('watch', function() {
97 | gulp.watch(['./*.coffee', './tests/*.coffee'], ['makeJs']);
98 | gulp.watch('./subtotal.css', ['makeCss']);
99 | });
100 |
101 | gulp.task('default', ['makeJs', 'makeCss']);
102 |
103 |
--------------------------------------------------------------------------------
/images/subtotal-renderer-pivotui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nagarajanchinnasamy/subtotal/74fd41a509c68cb545e0b0c75f037c4a2e2df344/images/subtotal-renderer-pivotui.png
--------------------------------------------------------------------------------
/images/subtotal_cdnjs.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/subtotal_license.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/subtotal_npm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/subtotal_tests.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/tablewithsubtotalheatmap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nagarajanchinnasamy/subtotal/74fd41a509c68cb545e0b0c75f037c4a2e2df344/images/tablewithsubtotalheatmap.png
--------------------------------------------------------------------------------
/images/tablewithsubtotalheatmapmedium.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nagarajanchinnasamy/subtotal/74fd41a509c68cb545e0b0c75f037c4a2e2df344/images/tablewithsubtotalheatmapmedium.png
--------------------------------------------------------------------------------
/images/tablewithsubtotalheatmapsmall.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nagarajanchinnasamy/subtotal/74fd41a509c68cb545e0b0c75f037c4a2e2df344/images/tablewithsubtotalheatmapsmall.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 | Page Redirection
10 |
11 |
12 | If you are not redirected automatically, follow the link to the main page
13 |
14 |
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "subtotal",
3 | "version": "1.11.0-alpha.0",
4 | "description": "Subtotal.js is a JavaScript plugin for PivotTable.js. It renders subtotals of rows and columns with the ability to expand and collapse rows.",
5 | "main": "dist/subtotal.js",
6 | "keywords": [
7 | "pivot",
8 | "crosstab",
9 | "grid",
10 | "table",
11 | "pivottable",
12 | "pivotgrid",
13 | "pivotchart",
14 | "jquery",
15 | "jquery-plugin",
16 | "subtotal",
17 | "expand",
18 | "collapse",
19 | "summary"
20 | ],
21 | "repository": {
22 | "type": "git",
23 | "url": "git://github.com/nagarajanchinnasamy/subtotal.git"
24 | },
25 | "author": "Nagarajan Chinnasamy",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/nagarajanchinnasamy/subtotal/issues"
29 | },
30 | "homepage": "https://github.com/nagarajanchinnasamy/subtotal",
31 | "dependencies": {
32 | "pivottable": ">=2.7.0"
33 | },
34 | "scripts": {
35 | "build": "gulp"
36 | },
37 | "devDependencies": {
38 | "gulp": "^3.9.1",
39 | "gulp-bump": "^2.5.1",
40 | "gulp-clean-css": "^3.9.0",
41 | "gulp-coffee": "^2.2.0",
42 | "gulp-concat": "^2.4.2",
43 | "gulp-debug": "^3.1.0",
44 | "gulp-filter": "^4.0.0",
45 | "gulp-git": "^1.12.0",
46 | "gulp-minify-css": "^1.2.4",
47 | "gulp-rename": "^1.2.0",
48 | "gulp-serve": "^1.2.0",
49 | "gulp-sourcemaps": "^1.2.8",
50 | "gulp-tag-version": "^1.2.1",
51 | "gulp-uglify": "^2.0.0",
52 | "gulp-util": "^3.0.1",
53 | "run-sequence": "^1.0.2"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/subtotal.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: Verdana;
3 | }
4 |
5 | /* AxisLabel */
6 | table.pvtTable .pvtAxisLabel {
7 | white-space: nowrap;
8 | }
9 | table.pvtTable .pvtAxisLabel.expanded {
10 | white-space: nowrap;
11 | cursor: zoom-out !important;
12 | }
13 | table.pvtTable .pvtAxisLabel.collapsed {
14 | white-space: nowrap;
15 | cursor: zoom-in !important;
16 | }
17 |
18 | /* RowLabel */
19 | table.pvtTable tbody tr th.pvtRowLabel {
20 | vertical-align: top !important;
21 | white-space: nowrap !important;
22 | background-color: white !important;
23 | border-width: 0px 0px thin 0px !important;
24 | }
25 | table.pvtTable tbody tr th.pvtRowLabel.rowexpanded {
26 | cursor: zoom-out !important;
27 | }
28 | table.pvtTable tbody tr th.pvtRowLabel.rowcollapsed {
29 | cursor: zoom-in !important;
30 | }
31 |
32 | /* RowLabelFiller */
33 | table.pvtTable .pvtRowLabelFiller {
34 | background-color: white;
35 | border-width: 0px 0px thin 0px !important;
36 | }
37 |
38 | /* RowSubtotal */
39 | table.pvtTable .pvtRowSubtotal {
40 | font-weight:bold;
41 | }
42 | table.pvtTable tr td.pvtRowSubtotal.rowcollapsed {
43 | background-color: #EFEFEF !important;
44 | }
45 |
46 | /* ColLabel */
47 | table.pvtTable thead tr th.pvtColLabel {
48 | white-space: nowrap;
49 | }
50 | table.pvtTable thead tr th.pvtColLabel.colexpanded {
51 | cursor: zoom-out !important;
52 | }
53 | table.pvtTable thead tr th.pvtColLabel.colcollapsed {
54 | cursor: zoom-in !important;
55 | }
56 |
57 | /* ColLabelFiller */
58 | table.pvtTable .pvtColLabelFiller {
59 | background-color: #EFEFEF !important;
60 | }
61 |
62 | /* ColSubtotal */
63 | table.pvtTable .pvtColSubtotal {
64 | font-weight:bold;
65 | }
66 | table.pvtTable tr td.pvtColSubtotal {
67 | background-color: #EFEFEF !important;
68 | }
69 |
70 |
71 | /*
72 | *
73 | * IMPORTANT: Please do not remove the lines below this point
74 | *
75 | */
76 | table.pvtTable tr .rowhide {
77 | display: none;
78 | }
79 |
80 | table.pvtTable tr .colhide {
81 | display: none;
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/tests/boot.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2008-2015 Pivotal Labs
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the
6 | "Software"), to deal in the Software without restriction, including
7 | without limitation the rights to use, copy, modify, merge, publish,
8 | distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to
10 | the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 | /**
24 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project.
25 |
26 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms.
27 |
28 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`.
29 |
30 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem
31 | */
32 |
33 | (function() {
34 |
35 | /**
36 | * ## Require & Instantiate
37 | *
38 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
39 | */
40 | window.jasmine = jasmineRequire.core(jasmineRequire);
41 |
42 | /**
43 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference.
44 | */
45 | jasmineRequire.html(jasmine);
46 |
47 | /**
48 | * Create the Jasmine environment. This is used to run all specs in a project.
49 | */
50 | var env = jasmine.getEnv();
51 |
52 | /**
53 | * ## The Global Interface
54 | *
55 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
56 | */
57 | var jasmineInterface = jasmineRequire.interface(jasmine, env);
58 |
59 | /**
60 | * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
61 | */
62 | extend(window, jasmineInterface);
63 |
64 | /**
65 | * ## Runner Parameters
66 | *
67 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
68 | */
69 |
70 | var queryString = new jasmine.QueryString({
71 | getWindowLocation: function() { return window.location; }
72 | });
73 |
74 | var catchingExceptions = queryString.getParam("catch");
75 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
76 |
77 | var throwingExpectationFailures = queryString.getParam("throwFailures");
78 | env.throwOnExpectationFailure(throwingExpectationFailures);
79 |
80 | var random = queryString.getParam("random");
81 | env.randomizeTests(random);
82 |
83 | var seed = queryString.getParam("seed");
84 | if (seed) {
85 | env.seed(seed);
86 | }
87 |
88 | /**
89 | * ## Reporters
90 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
91 | */
92 | var htmlReporter = new jasmine.HtmlReporter({
93 | env: env,
94 | onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); },
95 | onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); },
96 | onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); },
97 | addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); },
98 | getContainer: function() { return document.body; },
99 | createElement: function() { return document.createElement.apply(document, arguments); },
100 | createTextNode: function() { return document.createTextNode.apply(document, arguments); },
101 | timer: new jasmine.Timer()
102 | });
103 |
104 | /**
105 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript.
106 | */
107 | env.addReporter(jasmineInterface.jsApiReporter);
108 | env.addReporter(htmlReporter);
109 |
110 | /**
111 | * Filter which specs will be run by matching the start of the full name against the `spec` query param.
112 | */
113 | var specFilter = new jasmine.HtmlSpecFilter({
114 | filterString: function() { return queryString.getParam("spec"); }
115 | });
116 |
117 | env.specFilter = function(spec) {
118 | return specFilter.matches(spec.getFullName());
119 | };
120 |
121 | /**
122 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack.
123 | */
124 | window.setTimeout = window.setTimeout;
125 | window.setInterval = window.setInterval;
126 | window.clearTimeout = window.clearTimeout;
127 | window.clearInterval = window.clearInterval;
128 |
129 | /**
130 | * ## Execution
131 | *
132 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
133 | */
134 | var currentWindowOnload = window.onload;
135 |
136 | window.onload = function() {
137 | if (currentWindowOnload) {
138 | currentWindowOnload();
139 | }
140 | htmlReporter.initialize();
141 | //env.execute();
142 | };
143 |
144 | /**
145 | * Helper function for readability above.
146 | */
147 | function extend(destination, source) {
148 | for (var property in source) destination[property] = source[property];
149 | return destination;
150 | }
151 |
152 | }());
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Jasmine Spec Runner
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/tests/pivot_spec.coffee:
--------------------------------------------------------------------------------
1 | fixtureData = [
2 | ["name", "gender", "colour", "birthday", "trials", "successes"],
3 | ["Nick", "male", "blue", "1982-11-07", 103, 12],
4 | ["Jane", "female", "red", "1982-11-08", 95, 25],
5 | ["John", "male", "blue", "1982-12-08", 112, 30],
6 | ["Carol", "female", "yellow", "1983-11-11", 102, 14],
7 | ["Raj", "male", "blue", "1982-11-07", 103, 12],
8 | ["Rani", "female", "red", "1982-11-08", 95, 25],
9 | ["Joshi", "male", "blue", "1982-12-09", 112, 12],
10 | ["Vel", "male", "yellow", "1982-12-01", 112, 25],
11 | ["Sai", "male", "red", "1982-11-08", 112, 30],
12 | ["Geeth", "female", "blue", "1982-12-03", 112, 14],
13 | ["Malar", "male", "red", "1982-11-05", 112, 12],
14 | ["Nila", "male", "blue", "1982-12-07", 112, 25],
15 | ["Yaazhi", "male", "yellow", "1982-12-06", 112, 30],
16 | ["Mukhi", "male", "yellow", "1982-11-07", 112, 14]]
17 |
18 | fixtureData2 = [
19 | ["name", "gender", "colour", "birthday", "trials", "successes"],
20 | ["Nick", "male", "blue", "1982-11-07", 103, 12],
21 | ["Jane", "female", "red", "1982-11-08", 95, 25],
22 | ["John", "male", "blue", "1982-12-08", 112, 30],
23 | ["Carol", "female", "yellow", "1983-12-08", 102, 14]]
24 |
25 |
26 | describe "$.pivotUI()", ->
27 | describe "with no rows/cols, default count aggregator, subtotal renderer", ->
28 | table = null
29 |
30 | beforeEach (done) ->
31 | table = $("").pivotUI fixtureData, {
32 | dataClass: $.pivotUtilities.SubtotalPivotData,
33 | renderers: $.pivotUtilities.subtotal_renderers,
34 | onRefresh: done
35 | }
36 |
37 |
38 | it "has all the basic UI elements", (done) ->
39 | expect table.find("td.pvtAxisContainer").length
40 | .toBe 3
41 | expect table.find("td.pvtRendererArea").length
42 | .toBe 1
43 | expect table.find("td.pvtVals").length
44 | .toBe 1
45 | expect table.find("select.pvtRenderer").length
46 | .toBe 1
47 | expect table.find("select.pvtAggregator").length
48 | .toBe 1
49 | expect table.find("span.pvtAttr").length
50 | .toBe 6
51 | expect table.find("th.pvtTotalLabel").length
52 | .toBe 1
53 | expect table.find("td.pvtGrandTotal").length
54 | .toBe 1
55 | done()
56 |
57 | it "reflects its inputs", (done) ->
58 | expect table.find("td.pvtUnused span.pvtAttr").length
59 | .toBe 6
60 | expect table.find("select.pvtRenderer").val()
61 | .toBe "Table With Subtotal"
62 | expect table.find("select.pvtAggregator").val()
63 | .toBe "Count"
64 | done()
65 |
66 | it "renders a table", (done) ->
67 | expect table.find("table.pvtTable").length
68 | .toBe 1
69 | done()
70 |
71 | describe "its renderer output", ->
72 | it "has the correct type and number of cells", (done) ->
73 | expect table.find("th.pvtTotalLabel").length
74 | .toBe 1
75 | expect table.find("td.pvtGrandTotal").length
76 | .toBe 1
77 | done()
78 |
79 | it "has the correct textual representation", (done) ->
80 | expect table.find("table.pvtTable").text()
81 | .toBe ["Totals", "14"].join("")
82 | done()
83 |
84 | it "has a correct grand total with data value", (done) ->
85 | expect table.find("td.pvtGrandTotal").text()
86 | .toBe "14"
87 | expect table.find("td.pvtGrandTotal").data("value")
88 | .toBe 14
89 | done()
90 |
91 | describe "with collapsed rows and cols, subtotal_aggregators", ->
92 | table = null
93 |
94 | beforeEach (done) ->
95 | table = $("").pivotUI fixtureData,
96 | dataClass: $.pivotUtilities.SubtotalPivotData,
97 | rows: ["gender", "colour"],
98 | cols: ["birthday", "trials"],
99 | aggregators: $.pivotUtilities.subtotal_aggregators,
100 | vals: ["successes"],
101 | renderers: $.pivotUtilities.subtotal_renderers,
102 | rendererOptions: {
103 | collapseColsAt: 0,
104 | collapseRowsAt: 0
105 | },
106 | onRefresh: done
107 |
108 | it "has all the basic UI elements", (done) ->
109 | expect table.find("td.pvtAxisContainer").length
110 | .toBe 3
111 | expect table.find("td.pvtRendererArea").length
112 | .toBe 1
113 | expect table.find("td.pvtVals").length
114 | .toBe 1
115 | expect table.find("select.pvtRenderer").length
116 | .toBe 1
117 | expect table.find("select.pvtAggregator").length
118 | .toBe 1
119 | expect table.find("span.pvtAttr").length
120 | .toBe 6
121 | done()
122 |
123 | it "reflects its inputs", (done) ->
124 | expect table.find("td.pvtUnused span.pvtAttr").length
125 | .toBe 2
126 | expect table.find("td.pvtRows span.pvtAttr").length
127 | .toBe 2
128 | expect table.find("td.pvtCols span.pvtAttr").length
129 | .toBe 2
130 | expect table.find("select.pvtRenderer").val()
131 | .toBe "Table With Subtotal"
132 | expect table.find("select.pvtAggregator").val()
133 | .toBe "Sum As Fraction Of Parent Row"
134 | done()
135 |
136 | it "renders a table", (done) ->
137 | expect table.find("table.pvtTable").length
138 | .toBe 1
139 | done()
140 |
141 | describe "its renderer output", ->
142 | it "has the correct type and number of cells", (done) ->
143 | expect table.find("th.pvtAxisLabel").length
144 | .toBe 4
145 | expect table.find("th.pvtAxisLabel.collapsed").length
146 | .toBe 4
147 | expect table.find("th.pvtRowLabel.rowcollapsed").length
148 | .toBe 2
149 | expect table.find("th.pvtColLabel.colcollapsed").length
150 | .toBe 10
151 | expect table.find("th.pvtTotalLabel.rowTotal").length
152 | .toBe 1
153 | expect table.find("th.pvtTotalLabel.colTotal").length
154 | .toBe 1
155 | expect table.find("td.pvtVal.pvtColSubtotal.pvtRowSubtotal").length
156 | .toBe 20
157 | expect table.find("td.pvtTotal.rowTotal.pvtRowSubtotal").length
158 | .toBe 2
159 | expect table.find("td.pvtTotal.colTotal.pvtColSubtotal").length
160 | .toBe 10
161 | expect table.find("td.pvtGrandTotal").length
162 | .toBe 1
163 | done()
164 |
165 | it "has the correct textual representation", (done) ->
166 | expect table.find("th.pvtColLabel").text()
167 | .toBe " \u25B6 1982-11-05 \u25B6 1982-11-07 \u25B6 1982-11-08 \u25B6 1982-12-01 \u25B6 1982-12-03 \u25B6 1982-12-06 \u25B6 1982-12-07 \u25B6 1982-12-08 \u25B6 1982-12-09 \u25B6 1983-11-1111210311295112112112112112112112102"
168 | expect table.find("th.pvtRowLabel").text()
169 | .toBe " \u25B6 femaleblueredyellow \u25B6 maleblueredyellow"
170 | done()
171 |
172 | it "has a correct spot-checked cell with data value", (done) ->
173 | expect table.find("td.pvtVal.pvtRowSubtotal.row0.col3.rowcol0.colcol1").text()
174 | .toBe "17.9%"
175 | expect table.find("td.pvtVal.pvtTotal.colTotal.pvtColSubtotal.col3.colcol0").data("value")
176 | .toBe (50+30)/280
177 | done()
178 |
179 | describe "with row and col subtotal hidden on expand", ->
180 | table = null
181 |
182 | beforeEach (done) ->
183 | table = $("").pivotUI fixtureData,
184 | dataClass: $.pivotUtilities.SubtotalPivotData,
185 | rows: ["colour", "birthday", "name"],
186 | cols: ["trials", "gender", "successes"],
187 | aggregators: $.pivotUtilities.subtotal_aggregators,
188 | vals: ["successes"],
189 | renderers: $.pivotUtilities.subtotal_renderers,
190 | rendererOptions: {
191 | rowSubtotalDisplay: {
192 | hideOnExpand: true
193 | },
194 | colSubtotalDisplay: {
195 | hideOnExpand: true
196 | }
197 | },
198 | onRefresh: done
199 |
200 | it "has all the basic UI elements", (done) ->
201 | expect table.find("td.pvtAxisContainer").length
202 | .toBe 3
203 | expect table.find("td.pvtRendererArea").length
204 | .toBe 1
205 | expect table.find("td.pvtVals").length
206 | .toBe 1
207 | expect table.find("select.pvtRenderer").length
208 | .toBe 1
209 | expect table.find("select.pvtAggregator").length
210 | .toBe 1
211 | expect table.find("span.pvtAttr").length
212 | .toBe 6
213 | done()
214 |
215 | it "reflects its inputs", (done) ->
216 | expect table.find("td.pvtUnused span.pvtAttr").length
217 | .toBe 0
218 | expect table.find("td.pvtRows span.pvtAttr").length
219 | .toBe 3
220 | expect table.find("td.pvtCols span.pvtAttr").length
221 | .toBe 3
222 | expect table.find("select.pvtRenderer").val()
223 | .toBe "Table With Subtotal"
224 | expect table.find("select.pvtAggregator").val()
225 | .toBe "Sum As Fraction Of Parent Row"
226 | done()
227 |
228 | it "renders a table", (done) ->
229 | expect table.find("table.pvtTable").length
230 | .toBe 1
231 | done()
232 |
233 | describe "its renderer output", ->
234 | it "has the correct type and number of cells", (done) ->
235 | expect table.find("th.pvtAxisLabel").length
236 | .toBe 6
237 | expect table.find("th.pvtAxisLabel.collapsed").length
238 | .toBe 0
239 | expect table.find("th.pvtRowLabel.rowshow.rowcollapsed").length
240 | .toBe 0
241 | expect table.find("th.pvtColLabel.colshow.colcollapsed").length
242 | .toBe 0
243 | expect table.find("th.pvtRowLabel.rowshow.rowexpanded").length
244 | .toBe 28
245 | expect table.find("th.pvtColLabel.colshow.colexpanded").length
246 | .toBe 17
247 | expect table.find("th.pvtRowLabelFiller.rowhide.rowexpanded").length
248 | .toBe 14
249 | expect table.find("th.pvtColLabelFiller.colhide.colexpanded").length
250 | .toBe 9
251 | expect table.find("td.pvtColSubtotal.pvtRowSubtotal.colhide.colexpanded.rowhide.rowexpanded").length
252 | .toBe 9*14
253 | expect table.find("th.pvtTotalLabel.rowTotal").length
254 | .toBe 1
255 | expect table.find("th.pvtTotalLabel.colTotal").length
256 | .toBe 1
257 | expect table.find("td.pvtTotal.rowTotal.pvtRowSubtotal").length
258 | .toBe 14
259 | expect table.find("td.pvtTotal.colTotal.pvtColSubtotal").length
260 | .toBe 9
261 | expect table.find("td.pvtGrandTotal").length
262 | .toBe 1
263 | done()
264 |
265 | it "has the correct textual representation", (done) ->
266 | expect table.find("th.pvtColLabel").text()
267 | .toBe " \u25E2 95 \u25E2 102 \u25E2 103 \u25E2 112 \u25E2 female \u25E2 female \u25E2 male \u25E2 female \u25E2 male2514121412142530"
268 | expect table.find("th.pvtRowLabel").text()
269 | .toBe " \u25E2 blue \u25E2 1982-11-07NickRaj \u25E2 1982-12-03Geeth \u25E2 1982-12-07Nila \u25E2 1982-12-08John \u25E2 1982-12-09Joshi \u25E2 red \u25E2 1982-11-05Malar \u25E2 1982-11-08JaneRaniSai \u25E2 yellow \u25E2 1982-11-07Mukhi \u25E2 1982-12-01Vel \u25E2 1982-12-06Yaazhi \u25E2 1983-11-11Carol"
270 | done()
271 |
272 | it "has a correct spot-checked cell with data value", (done) ->
273 | expect table.find("td.pvtVal.rowshow.colshow.row10.col5.rowcol2.colcol2").text()
274 | .toBe "100.0%"
275 | expect table.find("td.pvtVal[data-rownode=\"1\"][data-colnode=\"6\"]").text()
276 | .toBe "50.0%"
277 | done()
278 |
279 | describe "with row subtotal displayed at bottom", ->
280 | table = null
281 |
282 | beforeEach (done) ->
283 | table = $("").pivotUI fixtureData,
284 | dataClass: $.pivotUtilities.SubtotalPivotData,
285 | rows: ["colour", "birthday"],
286 | cols: ["gender", "successes"]
287 | vals: ["successes"],
288 | renderers: $.pivotUtilities.subtotal_renderers,
289 | rendererOptions: {
290 | rowSubtotalDisplay: {
291 | displayOnTop: false
292 | }
293 | },
294 | onRefresh: done
295 |
296 | it "has all the basic UI elements", (done) ->
297 | expect table.find("td.pvtAxisContainer").length
298 | .toBe 3
299 | expect table.find("td.pvtRendererArea").length
300 | .toBe 1
301 | expect table.find("td.pvtVals").length
302 | .toBe 1
303 | expect table.find("select.pvtRenderer").length
304 | .toBe 1
305 | expect table.find("select.pvtAggregator").length
306 | .toBe 1
307 | expect table.find("span.pvtAttr").length
308 | .toBe 6
309 | done()
310 |
311 | it "reflects its inputs", (done) ->
312 | expect table.find("td.pvtUnused span.pvtAttr").length
313 | .toBe 2
314 | expect table.find("td.pvtRows span.pvtAttr").length
315 | .toBe 2
316 | expect table.find("td.pvtCols span.pvtAttr").length
317 | .toBe 2
318 | expect table.find("select.pvtRenderer").val()
319 | .toBe "Table With Subtotal"
320 | done()
321 |
322 | it "renders a table", (done) ->
323 | expect table.find("table.pvtTable").length
324 | .toBe 1
325 | done()
326 |
327 | describe "its renderer output", ->
328 | it "has the correct type and number of cells", (done) ->
329 | expect table.find(".pvtTable tbody tr:first-child th").length
330 | .toBe 1
331 | expect table.find(".pvtTable tbody tr:first-child th").attr("rowspan")
332 | .toBe "7"
333 | expect table.find("tr:nth-child(7) th.pvtRowLabelFiller").length
334 | .toBe 1
335 | expect table.find("th.pvtTotalLabel.rowTotal").length
336 | .toBe 1
337 | expect table.find("th.pvtTotalLabel.colTotal").length
338 | .toBe 1
339 | expect table.find("td.pvtTotal.rowTotal.pvtRowSubtotal").length
340 | .toBe 3
341 | expect table.find("td.pvtTotal.colTotal.pvtColSubtotal").length
342 | .toBe 2
343 | expect table.find("td.pvtGrandTotal").length
344 | .toBe 1
345 | done()
346 |
347 | it "has the correct textual representation", (done) ->
348 | expect table.find("th.pvtColLabel").text()
349 | .toBe " \u25E2 female \u25E2 male142512142530"
350 | expect table.find("th.pvtRowLabel").text()
351 | .toBe " \u25E2 blue1982-11-071982-12-031982-12-071982-12-081982-12-09 \u25E2 red1982-11-051982-11-08 \u25E2 yellow1982-11-071982-12-011982-12-061983-11-11"
352 | done()
353 |
354 | it "has a correct spot-checked cell with data value", (done) ->
355 | expect table.find("tr:nth-child(7) td.pvtTotal").text()
356 | .toBe "6"
357 | expect table.find("td.pvtVal.row5.rowcol0.pvtRowSubtotal.col0.colcol0.pvtColSubtotal").text()
358 | .toBe "2"
359 | expect table.find("td.pvtVal[data-rownode=\"13\"][data-colnode=\"7\"]").text()
360 | .toBe "3"
361 | done()
362 |
363 | describe "$.pivot()", ->
364 | describe "with no rows/cols, default count aggregator, subtotal renderer", ->
365 | table = $("").pivot fixtureData, {
366 | dataClass: $.pivotUtilities.SubtotalPivotData,
367 | renderer: $.pivotUtilities.subtotal_renderers["Table With Subtotal"]
368 | }
369 |
370 | it "has all the basic UI elements", ->
371 | expect table.find("th.pvtTotalLabel").length
372 | .toBe 1
373 | expect table.find("td.pvtGrandTotal").length
374 | .toBe 1
375 |
376 | it "renders a table", ->
377 | expect table.find("table.pvtTable").length
378 | .toBe 1
379 |
380 | describe "its renderer output", ->
381 | it "has the correct type and number of cells", ->
382 | expect table.find("th.pvtTotalLabel").length
383 | .toBe 1
384 | expect table.find("td.pvtGrandTotal").length
385 | .toBe 1
386 |
387 | it "has the correct textual representation", ->
388 | expect table.find("table.pvtTable").text()
389 | .toBe ["Totals", "14"].join("")
390 |
391 | it "has a correct grand total with data value", ->
392 | expect table.find("td.pvtGrandTotal").text()
393 | .toBe "14"
394 | expect table.find("td.pvtGrandTotal").data("value")
395 | .toBe 14
396 |
397 | describe "with rows/cols, subtotal_aggregator", ->
398 | table = $("").pivot fixtureData,
399 | dataClass: $.pivotUtilities.SubtotalPivotData,
400 | rows: ["gender", "colour"],
401 | cols: ["birthday", "trials"],
402 | aggregator: $.pivotUtilities.subtotal_aggregators["Sum As Fraction Of Parent Column"](["successes"]),
403 | renderer: $.pivotUtilities.subtotal_renderers["Table With Subtotal"]
404 |
405 | it "renders a table", ->
406 | expect table.find("table.pvtTable").length
407 | .toBe 1
408 |
409 | describe "its renderer output", ->
410 | it "has the correct type and number of cells", ->
411 | expect table.find("th.pvtAxisLabel").length
412 | .toBe 4
413 | expect table.find("th.collapsed").length
414 | .toBe 0
415 | expect table.find("th.expanded, th.rowexpanded, th.colexpanded").length
416 | .toBe 4+(2*5)+(10*2)+12
417 | expect table.find("th.pvtAxisLabel.expanded").length
418 | .toBe 4
419 | expect table.find("th.pvtRowLabel.rowexpanded").length
420 | .toBe 8
421 | expect table.find("th.pvtColLabel.colexpanded").length
422 | .toBe 22
423 | expect table.find("th.pvtTotalLabel.rowTotal").length
424 | .toBe 1
425 | expect table.find("th.pvtTotalLabel.colTotal").length
426 | .toBe 1
427 | expect table.find("td.pvtVal.pvtColSubtotal.pvtRowSubtotal").length
428 | .toBe 20
429 | expect table.find("td.pvtTotal.rowTotal.pvtRowSubtotal").length
430 | .toBe 2
431 | expect table.find("td.pvtTotal.colTotal.pvtColSubtotal").length
432 | .toBe 10
433 | expect table.find("td.pvtGrandTotal").length
434 | .toBe 1
435 |
436 | it "has the correct textual representation", ->
437 | expect table.find("th.pvtColLabel").text()
438 | .toBe " \u25E2 1982-11-05 \u25E2 1982-11-07 \u25E2 1982-11-08 \u25E2 1982-12-01 \u25E2 1982-12-03 \u25E2 1982-12-06 \u25E2 1982-12-07 \u25E2 1982-12-08 \u25E2 1982-12-09 \u25E2 1983-11-1111210311295112112112112112112112102"
439 | expect table.find("th.pvtRowLabel").text()
440 | .toBe " \u25E2 femaleblueredyellow \u25E2 maleblueredyellow"
441 |
442 | it "has a correct spot-checked cell with data value", ->
443 | expect table.find("td.pvtVal.pvtTotal.colTotal.col3.colcol1").text()
444 | .toBe "62.5%"
445 | expect table.find("td.pvtVal.pvtTotal.colTotal.col4.colcol1").data("value")
446 | .toBe 30/80
447 |
448 | describe "$.pivotUtilities", ->
449 |
450 | describe ".SubtotalPivotData()", ->
451 | sumOverSumOpts =
452 | rows: [], cols: []
453 | aggregator: $.pivotUtilities.aggregators["Sum over Sum"](["a","b"])
454 | filter: -> true
455 | sorters: ->
456 |
457 | describe "with array-of-array input", ->
458 | aoaInput = [ ["a","b"], [1,2], [3,4] ]
459 | pd = new $.pivotUtilities.SubtotalPivotData aoaInput, sumOverSumOpts
460 |
461 | it "has the correct grand total value", ->
462 | expect pd.getAggregator([],[]).value()
463 | .toBe (1+3)/(2+4)
464 |
465 | describe "with array-of-object input", ->
466 | aosInput = [ {a:1, b:2}, {a:3, b:4} ]
467 | pd = new $.pivotUtilities.SubtotalPivotData aosInput, sumOverSumOpts
468 |
469 | it "has the correct grand total value", ->
470 | expect pd.getAggregator([],[]).value()
471 | .toBe (1+3)/(2+4)
472 |
473 | describe "with function input", ->
474 | functionInput = (record) ->
475 | record a:1, b:2
476 | record a:3, b:4
477 | pd = new $.pivotUtilities.SubtotalPivotData functionInput, sumOverSumOpts
478 |
479 | it "has the correct grand total value", ->
480 | expect pd.getAggregator([],[]).value()
481 | .toBe (1+3)/(2+4)
482 |
483 | describe "with jQuery table element input", ->
484 | tableInput = $ """
485 |
486 |
487 | a b
488 |
489 |
490 | 1 2
491 | 3 4
492 |
493 |
494 | """
495 |
496 | pd = new $.pivotUtilities.SubtotalPivotData tableInput, sumOverSumOpts
497 |
498 | it "has the correct grand total value", ->
499 | expect pd.getAggregator([],[]).value()
500 | .toBe (1+3)/(2+4)
501 |
502 |
503 | describe "with rows/cols, no filters/sorters, count aggregator", ->
504 | pd = new $.pivotUtilities.SubtotalPivotData fixtureData2,
505 | rows: ["name", "colour"],
506 | cols: ["trials", "successes"],
507 | aggregator: $.pivotUtilities.aggregators["Count"](),
508 | filter: -> true
509 | sorters: ->
510 |
511 | it "has correctly-ordered row keys", ->
512 | expect pd.getRowKeys()
513 | .toEqual [ [ 'Carol', 'yellow' ], [ 'Jane', 'red' ], [ 'John', 'blue' ], [ 'Nick', 'blue' ] ]
514 |
515 | it "has correctly-ordered col keys", ->
516 | expect pd.getColKeys()
517 | .toEqual [ [ 95, 25 ], [ 102, 14 ], [ 103, 12 ], [ 112, 30 ] ]
518 |
519 | it "can be iterated over", ->
520 | numNotNull = 0
521 | numNull = 0
522 | for r in pd.getRowKeys()
523 | for c in pd.getColKeys()
524 | if pd.getAggregator(r, c).value()?
525 | numNotNull++
526 | else
527 | numNull++
528 | expect numNotNull
529 | .toBe 4
530 | expect numNull
531 | .toBe 12
532 |
533 | it "has a correct spot-checked aggregator", ->
534 | spots = [ {spot: [['Carol', 'yellow'], [102, 14]], val: 1}, {spot: [['Jane', 'red'], [95, 25]], val: 1}, {spot: [['John', 'blue'], [112, 30]], val: 1}, {spot: [['Nick', 'blue'], [103, 12]], val: 1} ]
535 | for s in spots
536 | agg = pd.getAggregator(s.spot[0],s.spot[1])
537 | val = agg.value()
538 | expect(val).toBe 1
539 | expect(agg.format(val)).toBe "" + s.val
540 |
541 | it "has correct spot-checked aggregators for subtotal-rows and subtotal-columns", ->
542 | spots = [ {spot: [['Carol'], [102]], val: 1}, {spot: [['Jane'], [95]], val: 1}, {spot: [['John'], [112]], val: 1}, {spot: [['Nick'], [103]], val: 1} ]
543 | for s in spots
544 | agg = pd.getAggregator(s.spot[0], s.spot[1])
545 | val = agg.value()
546 | expect(val).toBe s.val
547 | expect(agg.format(val)).toBe "" + s.val
548 |
549 | it "has correct row-total for subtotal-rows", ->
550 | for hdr in ['Carol', 'Jane', 'John', 'Nick']
551 | agg = pd.getAggregator([hdr],[])
552 | val = agg.value()
553 | expect(val).toBe 1
554 | expect(agg.format(val)).toBe "1"
555 |
556 | it "has correct column-total for subtotal-columns", ->
557 | for hdr in [95, 102, 103, 112]
558 | agg = pd.getAggregator([],[hdr])
559 | val = agg.value()
560 | expect(val).toBe 1
561 | expect(agg.format(val)).toBe "1"
562 |
563 | it "has a correct grand total aggregator", ->
564 | agg = pd.getAggregator([],[])
565 | val = agg.value()
566 | expect(val).toBe 4
567 | expect(agg.format(val)).toBe "4"
568 |
--------------------------------------------------------------------------------