Browse Source

Merge remote-tracking branch 'upstream/master' into feature/multi-arc-gauge

# Conflicts:
#	src/arc.js
#	src/data.js
pull/1355/head
Gökhan Özen 8 years ago
parent
commit
013f0666a7
  1. 7
      .bmp.yml
  2. 3
      .editorconfig
  3. 4
      .gitignore
  4. 16
      .jshintrc
  5. 24
      .travis.yml
  6. 44
      CONTRIBUTING.md
  7. 114
      Gruntfile.coffee
  8. 20
      README.md
  9. 4
      bower.json
  10. 12
      c3.css
  11. 13935
      c3.js
  12. 2
      c3.min.css
  13. 6
      c3.min.js
  14. 9
      circle.yml
  15. 7
      codecov.yml
  16. 4
      component.json
  17. 6
      htdocs/index.html
  18. 3
      htdocs/samples/chart_gauge.html
  19. 32
      htdocs/samples/different_category_datasets.html
  20. 27
      htdocs/samples/point_show.html
  21. 27
      karma.conf.js
  22. 4388
      package-lock.json
  23. 60
      package.json
  24. 7
      spec/api.axis-spec.js
  25. 53
      spec/api.data-spec.js
  26. 3
      spec/api.focus-spec.js
  27. 7
      spec/api.grid-spec.js
  28. 6
      spec/api.load-spec.js
  29. 247
      spec/api.region-spec.js
  30. 12
      spec/api.zoom-spec.js
  31. 110
      spec/arc-spec.js
  32. 153
      spec/axis-spec.js
  33. 19
      spec/c3-helper.js
  34. 40
      spec/core-spec.js
  35. 355
      spec/data-spec.js
  36. 38
      spec/domain-spec.js
  37. 45
      spec/grid-spec.js
  38. 20
      spec/interaction-spec.js
  39. 53
      spec/legend-spec.js
  40. 16
      spec/shape.bar-spec.js
  41. 105
      spec/shape.line-spec.js
  42. 50
      spec/svg-helper.js
  43. 334
      spec/tooltip-spec.js
  44. 30
      spec/type-spec.js
  45. 3
      src/api.axis.js
  46. 2
      src/api.category.js
  47. 2
      src/api.chart.js
  48. 2
      src/api.color.js
  49. 2
      src/api.data.js
  50. 6
      src/api.flow.js
  51. 3
      src/api.focus.js
  52. 2
      src/api.grid.js
  53. 3
      src/api.group.js
  54. 2
      src/api.legend.js
  55. 6
      src/api.load.js
  56. 3
      src/api.region.js
  57. 4
      src/api.selection.js
  58. 2
      src/api.show.js
  59. 3
      src/api.tooltip.js
  60. 2
      src/api.transform.js
  61. 2
      src/api.x.js
  62. 3
      src/api.zoom.js
  63. 53
      src/arc.js
  64. 24
      src/axis.js
  65. 2
      src/c3.axis.js
  66. 2
      src/cache.js
  67. 2
      src/category.js
  68. 101
      src/class-utils.js
  69. 100
      src/class.js
  70. 2
      src/clip.js
  71. 3
      src/color.js
  72. 14
      src/config.js
  73. 46
      src/core.js
  74. 55
      src/data.convert.js
  75. 26
      src/data.js
  76. 5
      src/data.load.js
  77. 3
      src/domain.js
  78. 4
      src/drag.js
  79. 3
      src/format.js
  80. 4
      src/grid.js
  81. 4
      src/head.js
  82. 58
      src/index.js
  83. 3
      src/interaction.js
  84. 4
      src/legend.js
  85. 849
      src/polyfill.js
  86. 15
      src/region.js
  87. 2
      src/scale.js
  88. 7
      src/selection.js
  89. 6
      src/shape.bar.js
  90. 4
      src/shape.js
  91. 16
      src/shape.line.js
  92. 14
      src/size.js
  93. 10
      src/subchart.js
  94. 9
      src/tail.js
  95. 3
      src/text.js
  96. 2
      src/title.js
  97. 100
      src/tooltip.js
  98. 3
      src/type.js
  99. 2
      src/ua.js
  100. 62
      src/util.js
  101. Some files were not shown because too many files have changed in this diff Show More

7
.bmp.yml

@ -0,0 +1,7 @@
---
version: 0.4.13
commit: 'chore(version): bump to v%.%.%'
files:
src/core.js: 'version: "%.%.%"'
package.json: '"version": "%.%.%"'
component.json: '"version": "%.%.%"'

3
.editorconfig

@ -8,3 +8,6 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.yml]
indent_size = 2

4
.gitignore vendored

@ -6,3 +6,7 @@ d3.min.js
components
build
.sass-cache
.idea/
# coverage report
/coverage

16
.jshintrc

@ -1,15 +1,14 @@
{
"bitwise": true,
"esversion": 6,
"eqeqeq": true,
"curly": true,
"strict": true,
"strict": false,
"trailing": true,
"white": true,
"maxlen": 210,
"undef": true,
"unused": true,
"indent": 4,
"eqnull": true,
"expr": true,
"newcap": false,
@ -17,15 +16,10 @@
"bitwise": false,
"browser": true,
"jasmine": true,
"globals": {
"jasmine": false,
"describe": false,
"beforeEach": false,
"beforeAll": false,
"it": false,
"expect": false,
"d3": false
"d3": false,
"require": false
}
}

24
.travis.yml

@ -1,5 +1,25 @@
language: node_js
node_js:
- 6
dist: trusty
sudo: false
addons:
apt:
packages:
- google-chrome-stable
before_script:
- npm install -g grunt-cli
- gem install sass
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start &
- sleep 3
after_success:
- npm run codecov
notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/b90b361c0bc91a778bcc
on_success: change # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: never # options: [always|never|change] default: always

44
CONTRIBUTING.md

@ -0,0 +1,44 @@
## Filing an issue
Before filing an issue, please [search the queue](https://github.com/c3js/c3/issues) to make sure it hasn't already been reported.
If a bug, please include the following —
1. What version of C3?
1. What browsers have you confirmed it in?
1. Can you isolate the issue by providing a jsFiddle demonstrating it in a minimalist capacity?
Please *do not* ask for support using the issue queue. For support, please ask [on chat](https://gitter.im/c3js/c3) or [the mailing list](groups.google.com/forum/#!forum/c3js).
## Setup
1. **Clone the repo from GitHub**
git clone https://github.com/c3js/c3.git
cd c3
2. **Acquire build dependencies.** Make sure you have [Node.js](http://nodejs.org/) installed on your workstation. This is only needed to _build_ C3 from sources. C3 itself has no dependency on Node.js once it is built. Now run:
npm install -g grunt-cli
npm install
The first `npm` command sets up the popular [Grunt](http://gruntjs.com/) build tool. You might need to run this command with `sudo` if you're on Linux or Mac OS X, or in an Administrator command prompt on Windows. The second `npm` command fetches the remaining build dependencies.
## Building C3 from sources
npm run build
## Distribution
npm run dist
Now you'll find the built files in `c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`.
## Running the tests
npm run test
This command will automatically run the specification suite and report its results.
If you want to see specs running live in browser (e.g., for debugging), simply open `http://localhost:9876/` in your browser when phantomjs starts.
## Contributing your changes
Add something about PRs here, indicate that PRs should not bump the version number & the build output files (`c3.js`, `c3.min.js`, `c3.css` & `c3.min.css`) should be excluded

114
Gruntfile.coffee

@ -1,114 +0,0 @@
module.exports = (grunt) ->
require('load-grunt-tasks') grunt, pattern: ['grunt-contrib-*', 'grunt-sass']
grunt.initConfig
watch:
concat:
tasks: 'concat'
files: ['src/*.js']
sass:
tasks: 'sass'
files: ['src/scss/*.scss']
concat:
dist:
options:
process: (src, filepath) ->
if filepath != 'src/head.js' && filepath != 'src/tail.js'
lines = []
src.split('\n').forEach (line) ->
lines.push( (if line.length > 0 then ' ' else '') + line)
src = lines.join('\n')
return src
src: [
'src/head.js',
'src/core.js',
'src/config.js',
'src/scale.js',
'src/domain.js',
'src/data.js',
'src/data.convert.js',
'src/data.load.js',
'src/category.js',
'src/interaction.js',
'src/size.js',
'src/shape.js',
'src/shape.line.js',
'src/shape.bar.js',
'src/text.js',
'src/type.js',
'src/grid.js',
'src/tooltip.js',
'src/legend.js',
'src/title.js',
'src/axis.js',
'src/clip.js',
'src/arc.js',
'src/region.js',
'src/drag.js',
'src/selection.js',
'src/subchart.js',
'src/zoom.js',
'src/color.js',
'src/format.js',
'src/cache.js',
'src/class.js',
'src/util.js',
'src/api.focus.js',
'src/api.show.js',
'src/api.zoom.js',
'src/api.load.js',
'src/api.flow.js',
'src/api.selection.js',
'src/api.transform.js',
'src/api.group.js',
'src/api.grid.js',
'src/api.region.js',
'src/api.data.js',
'src/api.category.js',
'src/api.color.js',
'src/api.x.js',
'src/api.axis.js',
'src/api.legend.js',
'src/api.chart.js',
'src/api.tooltip.js',
'src/c3.axis.js',
'src/ua.js',
'src/polyfill.js',
'src/tail.js'
]
dest: 'c3.js'
jshint:
c3: 'c3.js'
spec: 'spec/*.js'
options:
jshintrc: '.jshintrc'
jasmine:
c3:
src: 'c3.js'
options:
specs: 'spec/*-spec.js'
helpers: 'spec/*-helper.js'
styles: 'c3.css'
vendor: 'https://rawgit.com/mbostock/d3/v3.5.0/d3.min.js'
uglify:
c3:
files:
'c3.min.js': 'c3.js'
cssmin:
c3:
src: 'c3.css'
dest: 'c3.min.css'
sass:
options:
sourcemap: 'none'
c3:
files:
'c3.css': 'src/scss/main.scss'
grunt.registerTask 'default', ['concat', 'jshint', 'jasmine', 'sass', 'cssmin', 'uglify']

20
README.md

@ -1,4 +1,4 @@
c3 [![Build Status](https://travis-ci.org/masayuki0812/c3.svg?branch=master)](https://travis-ci.org/masayuki0812/c3) [![Dependency Status](https://david-dm.org/masayuki0812/c3.svg)](https://david-dm.org/masayuki0812/c3) [![devDependency Status](https://david-dm.org/masayuki0812/c3/dev-status.svg)](https://david-dm.org/masayuki0812/c3#info=devDependencies) [![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/masayuki0812/c3/blob/master/LICENSE)
c3 [![Build Status](https://travis-ci.org/c3js/c3.svg?branch=master)](https://travis-ci.org/c3js/c3) [![Dependency Status](https://david-dm.org/c3js/c3.svg)](https://david-dm.org/c3js/c3) [![devDependency Status](https://david-dm.org/c3js/c3/dev-status.svg)](https://david-dm.org/c3js/c3#info=devDependencies) [![license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat)](https://github.com/c3js/c3/blob/master/LICENSE) [![codecov.io](https://codecov.io/github/c3js/c3/coverage.svg?branch=master)](https://codecov.io/github/c3js/c3?branch=master)
==
c3 is a D3-based reusable chart library that enables deeper integration of charts into web applications.
@ -11,25 +11,25 @@ Follow the link for more information: [http://c3js.org](http://c3js.org/)
+ [Examples](http://c3js.org/examples.html)
Additional samples can be found in this repository:
+ [https://github.com/masayuki0812/c3/tree/master/htdocs/samples](https://github.com/masayuki0812/c3/tree/master/htdocs/samples)
+ [https://github.com/c3js/c3/tree/master/htdocs/samples](https://github.com/c3js/c3/tree/master/htdocs/samples)
You can run these samples as:
```
$ cd c3/htdocs
$ python -m SimpleHTTPServer 8080
$ npm run serve
```
## Google Group
For general C3.js-related discussion, please visit our [Google Group at https://groups.google.com/forum/#!forum/c3js](https://groups.google.com/forum/#!forum/c3js).
## Gitter
[![Join the chat at https://gitter.im/masayuki0812/c3](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/masayuki0812/c3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Join the chat at https://gitter.im/c3js/c3](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/c3js/c3?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Using the issue queue
The [issue queue](https://github.com/masayuki0812/c3/issues) is to be used for reporting defects and problems with C3.js, in addition to feature requests and ideas. It is **not** a catch-all support forum. **For general support enquiries, please use the [Google Group](https://groups.google.com/forum/#!forum/c3js) at https://groups.google.com/forum/#!forum/c3js.** All questions involving the interplay between C3.js and any other library (such as AngularJS) should be posted there first!
The [issue queue](https://github.com/c3js/c3/issues) is to be used for reporting defects and problems with C3.js, in addition to feature requests and ideas. It is **not** a catch-all support forum. **For general support enquiries, please use the [Google Group](https://groups.google.com/forum/#!forum/c3js) at https://groups.google.com/forum/#!forum/c3js.** All questions involving the interplay between C3.js and any other library (such as AngularJS) should be posted there first!
Before reporting an issue, please do the following:
1. [Search for existing issues](https://github.com/masayuki0812/c3/issues) to ensure you're not posting a duplicate.
1. [Search for existing issues](https://github.com/c3js/c3/issues) to ensure you're not posting a duplicate.
1. [Search the Google Group](https://groups.google.com/forum/#!forum/c3js) to ensure it hasn't been addressed there already.
@ -39,16 +39,14 @@ Before reporting an issue, please do the following:
## Pull requests
Pull requests are welcome, though please post an issue first to see whether such a change is desirable.
If you choose to submit a pull request, please do not bump the version number unless asked to, and please include test cases for any new features!
If you choose to submit a pull request, please do not bump the version number unless asked to, and please include test cases for any new features. Squash all your commits as well, please.
## Playground
Please fork this fiddle:
+ [http://jsfiddle.net/masayuki0812/7kYJu/](http://jsfiddle.net/masayuki0812/7kYJu/)
## Dependency
+ [D3.js](https://github.com/mbostock/d3) `<=3.5.0`
+ [D3.js](https://github.com/mbostock/d3) `~3.5.0`
## License
MIT
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=masayuki0812&url=https://github.com/masayuki0812/c3&title=c3&language=javascript&tags=github&category=software)

4
bower.json

@ -20,12 +20,12 @@
"bower_components",
"htdocs",
"spec",
"src",
"src/**/*.js",
"package.json",
"component.json",
"Gruntfile.*"
],
"dependencies": {
"d3": "<=3.5.0"
"d3": "~3.5.0"
}
}

12
c3.css

@ -1,7 +1,7 @@
/*-- Chart --*/
.c3 svg {
font: 10px sans-serif;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
-webkit-tap-highlight-color: transparent; }
.c3 path, .c3 line {
fill: none;
@ -12,7 +12,11 @@
-moz-user-select: none;
user-select: none; }
.c3-legend-item-tile, .c3-xgrid-focus, .c3-ygrid, .c3-event-rect, .c3-bars path {
.c3-legend-item-tile,
.c3-xgrid-focus,
.c3-ygrid,
.c3-event-rect,
.c3-bars path {
shape-rendering: crispEdges; }
.c3-chart-arc path {
@ -71,11 +75,11 @@
/*-- Region --*/
.c3-region {
fill: steelblue;
fill-opacity: 0.1; }
fill-opacity: .1; }
/*-- Brush --*/
.c3-brush .extent {
fill-opacity: 0.1; }
fill-opacity: .1; }
/*-- Select - Drag --*/
/*-- Legend --*/

13935
c3.js

File diff suppressed because it is too large Load Diff

2
c3.min.css vendored

@ -1 +1 @@
.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:gray;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #CCC}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#FFF}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max,.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}
.c3 svg{font:10px sans-serif;-webkit-tap-highlight-color:transparent}.c3 line,.c3 path{fill:none;stroke:#000}.c3 text{-webkit-user-select:none;-moz-user-select:none;user-select:none}.c3-bars path,.c3-event-rect,.c3-legend-item-tile,.c3-xgrid-focus,.c3-ygrid{shape-rendering:crispEdges}.c3-chart-arc path{stroke:#fff}.c3-chart-arc text{fill:#fff;font-size:13px}.c3-grid line{stroke:#aaa}.c3-grid text{fill:#aaa}.c3-xgrid,.c3-ygrid{stroke-dasharray:3 3}.c3-text.c3-empty{fill:grey;font-size:2em}.c3-line{stroke-width:1px}.c3-circle._expanded_{stroke-width:1px;stroke:#fff}.c3-selected-circle{fill:#fff;stroke-width:2px}.c3-bar{stroke-width:0}.c3-bar._expanded_{fill-opacity:.75}.c3-target.c3-focused{opacity:1}.c3-target.c3-focused path.c3-line,.c3-target.c3-focused path.c3-step{stroke-width:2px}.c3-target.c3-defocused{opacity:.3!important}.c3-region{fill:#4682b4;fill-opacity:.1}.c3-brush .extent{fill-opacity:.1}.c3-legend-item{font-size:12px}.c3-legend-item-hidden{opacity:.15}.c3-legend-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.c3-title{font:14px sans-serif}.c3-tooltip-container{z-index:10}.c3-tooltip{border-collapse:collapse;border-spacing:0;background-color:#fff;empty-cells:show;-webkit-box-shadow:7px 7px 12px -9px #777;-moz-box-shadow:7px 7px 12px -9px #777;box-shadow:7px 7px 12px -9px #777;opacity:.9}.c3-tooltip tr{border:1px solid #ccc}.c3-tooltip th{background-color:#aaa;font-size:14px;padding:2px 5px;text-align:left;color:#fff}.c3-tooltip td{font-size:13px;padding:3px 6px;background-color:#fff;border-left:1px dotted #999}.c3-tooltip td>span{display:inline-block;width:10px;height:10px;margin-right:6px}.c3-tooltip td.value{text-align:right}.c3-area{stroke-width:0;opacity:.2}.c3-chart-arcs-title{dominant-baseline:middle;font-size:1.3em}.c3-chart-arcs .c3-chart-arcs-background{fill:#e0e0e0;stroke:none}.c3-chart-arcs .c3-chart-arcs-gauge-unit{fill:#000;font-size:16px}.c3-chart-arcs .c3-chart-arcs-gauge-max{fill:#777}.c3-chart-arcs .c3-chart-arcs-gauge-min{fill:#777}.c3-chart-arc .c3-gauge-value{fill:#000}

6
c3.min.js vendored

File diff suppressed because one or more lines are too long

9
circle.yml

@ -0,0 +1,9 @@
machine:
node:
verison: 6
dependencies:
pre:
- curl -L -o google-chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- sudo dpkg -i google-chrome.deb
- sudo sed -i 's|HERE/chrome\"|HERE/chrome\" --disable-setuid-sandbox|g' /opt/google/chrome/google-chrome
- rm google-chrome.deb

7
codecov.yml

@ -0,0 +1,7 @@
coverage:
status:
project:
default:
threshold: 0.4
patch: no
change: no

4
component.json

@ -2,10 +2,10 @@
"name": "c3",
"repo": "masayuki0812/c3",
"description": "A D3-based reusable chart library",
"version": "0.4.11-rc4",
"version": "0.4.13",
"keywords": [],
"dependencies": {
"mbostock/d3": "v3.5.0"
"mbostock/d3": "v3.5.6"
},
"development": {},
"license": "MIT",

6
htdocs/index.html

@ -119,6 +119,9 @@
<a href="./samples/custom_x_categorized.html">
Chart with category data on category axis
</a>
<a href="./samples/different_category_datasets.html">
Chart with different category datasets
</a>
</div>
<div class="col-md-4">
<h3>Additional Axis</h3>
@ -330,6 +333,9 @@
<a href="./samples/point_r.html">
Change radius of data point
</a>
<a href="./samples/point_show.html">
Show points based on condition
</a>
</div>
<div class="col-md-4">
<h3>Bar</h3>

3
htdocs/samples/chart_gauge.html

@ -26,6 +26,9 @@
// format: function(value, ratio) {
// return value;
// },
// extents: function (value, isMax) {
// return value + '%';
// },
// show: false // to turn off the min/max labels.
},
// min: 0, // 0 is default, //can handle negative min e.g. vacuum / voltage / current flow / rate of change

32
htdocs/samples/different_category_datasets.html

@ -0,0 +1,32 @@
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script>
var chart = c3.generate({
data: {
xs: {
data1: "cat1",
data2: "cat2",
},
columns: [
["cat1", "a", "b", "c", "d"],
["data1", 30, 200, 100, 400],
["cat2", "b", "a", "c", "d", "e", "f"],
["data2", 400, 60, 200, 800, 10, 10]
]
},
axis: {
x: {
type: "category"
}
}
});
</script>
</body>
</html>

27
htdocs/samples/point_show.html

@ -0,0 +1,27 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 300, 200, 600, 250, 150]
]
},
point: {
show: function(d) {
return d.value > 200;
}
}
});
</script>
</body>
</html>

27
karma.conf.js

@ -0,0 +1,27 @@
const path = require('path');
module.exports = function(config) {
config.set({
frameworks: ['jasmine', 'browserify'],
files: [
'c3.css',
'spec/*-helper.js',
'spec/*-spec.js'
],
preprocessors: {
'spec/c3-helper.js': ['browserify']
},
browserify: {
debug: true,
transform: [['babelify', { presets: ['es2015'], plugins: ['istanbul'] }]]
},
reporters: ['spec', 'coverage-istanbul'],
coverageIstanbulReporter: {
reports: ['html', 'lcovonly', 'text-summary']
},
autoWatch: true,
browsers: ['Chrome'],
singleRun: true,
browserNoActivityTimeout: 120000,
})
};

4388
package-lock.json generated

File diff suppressed because it is too large Load Diff

60
package.json

@ -1,36 +1,68 @@
{
"name": "c3",
"version": "0.4.11-rc4",
"version": "0.4.13",
"description": "D3-based reusable chart library",
"main": "c3.js",
"scripts": {
"test": "grunt"
"serve": "static -p 8080 htdocs/",
"prepublish": "npm run dist",
"lint": "jshint --reporter=node_modules/jshint-stylish src/ spec/",
"build": "npm run build:js && npm run build:css",
"build:js": "npm run build:js:rollup && npm run build:js:uglify",
"build:js:rollup": "rollup -f umd --name c3 --globals d3:d3 src/index.js > c3.js",
"build:js:uglify": "uglifyjs c3.js --compress --mangle -o c3.min.js",
"build:css": "npm run build:css:sass && npm run build:css:min",
"build:css:sass": "node-sass src/scss/main.scss > c3.css",
"build:css:min": "cleancss -o c3.min.css c3.css",
"test": "npm run build && npm run lint && karma start karma.conf.js",
"dist": "npm run build",
"codecov": "codecov"
},
"repository": {
"type": "git",
"url": "git://github.com/masayuki0812/c3.git"
"url": "git://github.com/c3js/c3.git"
},
"keywords": [
"d3",
"chart",
"graph"
],
"author": "Masayuki Tanaka",
"authors": [
"Masayuki Tanaka",
"Ændrew Rininsland",
"Yoshiya Hinosawa"
],
"license": "MIT",
"gitHead": "84e03109d9a590f9c8ef687c03d751f666080c6f",
"readmeFilename": "README.md",
"dependencies": {
"d3": "<=3.5.0"
"d3": "~3.5.0"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-cssmin": "^0.10.0",
"grunt-contrib-jasmine": "~0.8.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-sass": "^0.17.0",
"load-grunt-tasks": "~0.2.0"
"babel-plugin-istanbul": "^4.1.4",
"babel-preset-es2015": "^6.24.1",
"babelify": "^7.3.0",
"browserify": "^14.4.0",
"clean-css-cli": "^4.1.3",
"codecov": "^2.2.0",
"jasmine-core": "^2.3.4",
"jshint": "^2.9.4",
"jshint-stylish": "^2.1.0",
"karma": "^1.7.0",
"karma-browserify": "^5.1.1",
"karma-chrome-launcher": "^2.1.1",
"karma-coverage-istanbul-reporter": "^1.3.0",
"karma-jasmine": "^1.1.0",
"karma-spec-reporter": "0.0.31",
"node-sass": "^4.5.3",
"node-static": "^0.7.9",
"rollup": "^0.41.6",
"uglify-js": "^3.0.15",
"watchify": "^3.9.0"
},
"nyc": {
"exclude": [
"src/polyfill.js"
]
}
}

7
spec/api.axis-spec.js

@ -9,7 +9,7 @@ describe('c3 api axis', function () {
describe('axis.labels', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -31,10 +31,9 @@ describe('c3 api axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should update y axis label', function () {
it('updates y axis label', function () {
chart.axis.labels({y: 'New Y Axis Label'});
var label = d3.select('.c3-axis-y-label');
expect(label.text()).toBe('New Y Axis Label');
@ -42,7 +41,7 @@ describe('c3 api axis', function () {
expect(label.attr('dy')).toBe('1.2em');
});
it('should update y axis label', function () {
it('updates y axis label', function () {
chart.axis.labels({y2: 'New Y2 Axis Label'});
var label = d3.select('.c3-axis-y2-label');
expect(label.text()).toBe('New Y2 Axis Label');

53
spec/api.data-spec.js

@ -30,6 +30,7 @@ describe('c3 api data', function () {
};
beforeEach(function (done) {
jasmine.addMatchers(customMatchers);
chart = window.initChart(chart, args, done);
});
@ -116,8 +117,8 @@ describe('c3 api data', function () {
it('should return data.colors specified as argument', function () {
var results = chart.data.colors();
expect(results.data1).toBe('#FF0000');
expect(results.data2).toBe('#00FF00');
expect(results.data1).toBeHexOrRGB('#FF0000');
expect(results.data2).toBeHexOrRGB('#00FF00');
});
it('should return data.colors specified as api', function () {
@ -125,15 +126,15 @@ describe('c3 api data', function () {
data1: '#00FF00',
data2: '#FF0000'
});
expect(results.data1).toBe('#00FF00');
expect(results.data2).toBe('#FF0000');
expect(results.data1).toBeHexOrRGB('#00FF00');
expect(results.data2).toBeHexOrRGB('#FF0000');
});
it('should set data.colors specified as api', function () {
expect(d3.select('.c3-line-data1').style('stroke')).toBe("#00ff00");
expect(d3.select('.c3-line-data2').style('stroke')).toBe("#ff0000");
expect(d3.select('.c3-legend-item-data1 .c3-legend-item-tile').style('stroke')).toBe("#00ff00");
expect(d3.select('.c3-legend-item-data2 .c3-legend-item-tile').style('stroke')).toBe("#ff0000");
expect(d3.select('.c3-line-data1').style('stroke')).toBeHexOrRGB("#00ff00");
expect(d3.select('.c3-line-data2').style('stroke')).toBeHexOrRGB("#ff0000");
expect(d3.select('.c3-legend-item-data1 .c3-legend-item-tile').style('stroke')).toBeHexOrRGB("#00ff00");
expect(d3.select('.c3-legend-item-data2 .c3-legend-item-tile').style('stroke')).toBeHexOrRGB("#ff0000");
});
});
@ -162,3 +163,39 @@ describe('c3 api data', function () {
});
});
var customMatchers = {
toBeHexOrRGB: function(util, customEqualityTesters) {
'use strict';
function rgb2hex(rgb){
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
return (rgb && rgb.length === 4) ? "#" +
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) +
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : '';
}
return {
compare: function(actual, expected){
if (expected === undefined) {
expected = '';
}
var result = {};
actual = actual.match('rgb') ? rgb2hex(actual) : actual;
expected = expected.match('rgb') ? rgb2hex(expected) : expected;
result.pass = util.equals(actual, expected, customEqualityTesters);
if (result.pass) {
result.message = "Expected " + actual + " not to be quite so goofy";
} else {
result.message = "Expected " + actual + " to be goofy, but it was not very goofy";
}
return result;
}
};
}
};

3
spec/api.focus-spec.js

@ -378,11 +378,10 @@ describe('c3 api focus', function () {
describe('when legend.show = false', function () {
it('should update args to hide legend', function () {
beforeAll(function () {
args.legend = {
show: false
};
expect(true).toBeTruthy();
});
it('should focus all targets without showing legend', function (done) {

7
spec/api.grid-spec.js

@ -9,7 +9,7 @@ describe('c3 api grid', function () {
describe('ygrid.add and ygrid.remove', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -17,10 +17,9 @@ describe('c3 api grid', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should update y grids', function (done) {
it('updates y grids', function (done) {
var main = chart.internal.main,
expectedGrids = [
{
@ -62,7 +61,7 @@ describe('c3 api grid', function () {
}, 1200);
});
it("should update x ygrids even if it's zoomed", function (done) {
it('updates x ygrids even if zoomed', function (done) {
var main = chart.internal.main,
expectedGrids = [
{

6
spec/api.load-spec.js

@ -11,7 +11,7 @@ describe('c3 api load', function () {
describe('as column', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -20,7 +20,6 @@ describe('c3 api load', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should load additional data', function (done) {
@ -46,7 +45,7 @@ describe('c3 api load', function () {
describe('category data', function () {
it('should update arg to category data', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -62,7 +61,6 @@ describe('c3 api load', function () {
}
}
};
expect(true).toBeTruthy();
});
describe('as column', function () {

247
spec/api.region-spec.js

@ -0,0 +1,247 @@
describe('c3 api region', function () {
'use strict';
var chart, args;
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
});
describe('api.region', function () {
beforeAll(function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
]
},
regions: [
{
axis: 'y',
start: 300,
end: 400,
class: 'green',
},
{
axis: 'y',
start: 0,
end: 100,
class: 'green',
}
]
};
});
it('updates regions', function (done) {
var main = chart.internal.main,
expectedRegions = [
{
axis: 'y',
start: 250,
end: 350,
class: 'red'
},
{
axis: 'y',
start: 25,
end: 75,
class: 'red'
}
],
regions;
// Call regions API
chart.regions(expectedRegions);
setTimeout(function () {
regions = main.selectAll('.c3-region');
expect(regions.size()).toBe(expectedRegions.length);
regions.each(function (d, i) {
var region = d3.select(this),
rect = region.select('rect'),
y = +rect.attr('y'),
height = +rect.attr('height'),
expectedClass = 'red',
unexpectedClass = 'green',
expectedStart = Math.round(chart.internal.y(expectedRegions[i].start)),
expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),
expectedY = expectedEnd,
expectedHeight = expectedStart - expectedEnd;
expect(y).toBeCloseTo(expectedY, -1);
expect(height).toBeCloseTo(expectedHeight, -1);
expect(region.classed(expectedClass)).toBeTruthy();
expect(region.classed(unexpectedClass)).toBeFalsy();
});
}, 500);
setTimeout(function () {
done();
}, 1000);
});
});
describe('api.region.add', function () {
beforeAll(function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
]
},
regions: [
{
axis: 'y',
start: 300,
end: 400,
class: 'green',
},
{
axis: 'y',
start: 0,
end: 100,
class: 'green',
}
]
};
});
it('should add regions', function (done) {
var main = chart.internal.main,
expectedRegions = [
{
axis: 'y',
start: 300,
end: 400,
class: 'green',
},
{
axis: 'y',
start: 0,
end: 100,
class: 'green',
},
{
axis: 'y',
start: 250,
end: 350,
class: 'red'
},
{
axis: 'y',
start: 25,
end: 75,
class: 'red'
}
],
expectedClasses = [
'green',
'green',
'red',
'red',
],
regions;
// Call regions API
chart.regions(expectedRegions);
setTimeout(function () {
regions = main.selectAll('.c3-region');
expect(regions.size()).toBe(expectedRegions.length);
regions.each(function (d, i) {
var region = d3.select(this),
rect = region.select('rect'),
y = +rect.attr('y'),
height = +rect.attr('height'),
expectedClass = expectedClasses[i],
expectedStart = Math.round(chart.internal.y(expectedRegions[i].start)),
expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),
expectedY = expectedEnd,
expectedHeight = expectedStart - expectedEnd;
expect(y).toBeCloseTo(expectedY, -1);
expect(height).toBeCloseTo(expectedHeight, -1);
expect(region.classed(expectedClass)).toBeTruthy();
});
}, 500);
setTimeout(function () {
done();
}, 1000);
});
});
describe('api.region.remove', function () {
beforeAll(function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
]
},
regions: [
{
axis: 'y',
start: 300,
end: 400,
class: 'green',
},
{
axis: 'y',
start: 0,
end: 100,
class: 'green',
},
{
axis: 'y',
start: 250,
end: 350,
class: 'red'
},
]
};
});
it('should remove regions', function (done) {
var main = chart.internal.main,
expectedRegions = [
{
axis: 'y',
start: 250,
end: 350,
class: 'red'
},
],
expectedClasses = ['red'],
regions;
// Call regions API
chart.regions(expectedRegions);
setTimeout(function () {
regions = main.selectAll('.c3-region');
expect(regions.size()).toBe(expectedRegions.length);
regions.each(function (d, i) {
var region = d3.select(this),
rect = region.select('rect'),
y = +rect.attr('y'),
height = +rect.attr('height'),
expectedClass = expectedClasses[i],
expectedStart = Math.round(chart.internal.y(expectedRegions[i].start)),
expectedEnd = Math.round(chart.internal.y(expectedRegions[i].end)),
expectedY = expectedEnd,
expectedHeight = expectedStart - expectedEnd;
expect(y).toBeCloseTo(expectedY, -1);
expect(height).toBeCloseTo(expectedHeight, -1);
expect(region.classed(expectedClass)).toBeTruthy();
});
}, 500);
setTimeout(function () {
done();
}, 1000);
});
});
});

12
spec/api.zoom-spec.js

@ -9,7 +9,7 @@ describe('c3 api zoom', function () {
describe('zoom', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -22,7 +22,6 @@ describe('c3 api zoom', function () {
enabled: true
}
};
expect(true).toBeTruthy();
});
it('should be zoomed properly', function () {
@ -41,7 +40,8 @@ describe('c3 api zoom', function () {
expect(domain[1]).toBe(target[1]);
});
it('should load timeseries data', function () {
describe('with timeseries data', function () {
beforeAll(function(){
args = {
data: {
x: 'date',
@ -59,7 +59,6 @@ describe('c3 api zoom', function () {
enabled: true
}
};
expect(true).toBeTruthy();
});
it('should be zoomed properly', function () {
@ -77,12 +76,12 @@ describe('c3 api zoom', function () {
expect(+domain[0]).toBe(+chart.internal.parseDate(target[0]));
expect(+domain[1]).toBe(+chart.internal.parseDate(target[1]));
});
});
});
describe('unzoom', function () {
it('should load indexed data', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -93,7 +92,6 @@ describe('c3 api zoom', function () {
enabled: true
}
};
expect(true).toBeTruthy();
});
it('should be unzoomed properly', function () {

110
spec/arc-spec.js

@ -9,7 +9,7 @@ describe('c3 chart arc', function () {
describe('show pie chart', function () {
it('should update args to have pie chart', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -20,7 +20,6 @@ describe('c3 chart arc', function () {
type: 'pie'
}
};
expect(true).toBeTruthy();
});
it('should have correct classes', function () {
@ -47,13 +46,13 @@ describe('c3 chart arc', function () {
expect(d3.select('.c3-arc-data3').attr('d')).toMatch(/M1\..+,211\..+A211\..+,211\..+ 0 0,1 -124\..+,-171\..+L0,0Z/);
});
it('should set args with data id that can be converted to a color', function () {
describe('with data id that can be converted to a color', function () {
beforeAll(function(){
args.data.columns = [
['black', 30],
['data2', 150],
['data3', 120]
];
expect(true).toBeTruthy();
});
it('should have correct d even if data id can be converted to a color', function (done) {
@ -63,7 +62,8 @@ describe('c3 chart arc', function () {
}, 500);
});
it('should update args to have empty pie chart', function () {
describe('with empty pie chart', function(){
beforeAll(function () {
args = {
data: {
columns: [
@ -74,7 +74,6 @@ describe('c3 chart arc', function () {
type: 'pie'
}
};
expect(true).toBeTruthy();
});
it('should have correct d attribute', function () {
@ -94,7 +93,106 @@ describe('c3 chart arc', function () {
expect(arcs.data2.attr('d').indexOf('NaN')).toBe(-1);
expect(arcs.data3.attr('d').indexOf('NaN')).toBe(-1);
});
});
});
});
describe('show gauge', function () {
describe('with a 180 degree gauge', function(){
beforeAll(function () {
args = {
gauge: {
width: 10,
max: 10,
expand: true
},
data: {
columns: [
['data', 8]
],
type: 'gauge'
}
};
});
it('should have correct d for Pi radian gauge', function () {
var chartArc = d3.select('.c3-chart-arcs'),
data = chartArc.select('.c3-chart-arc.c3-target.c3-target-data')
.select('g.c3-shapes.c3-shapes-data.c3-arcs.c3-arcs-data')
.select('path.c3-shape.c3-shape.c3-arc.c3-arc-data');
expect(data.attr('d')).toMatch(/M-304,-3\..+A304,304 0 0,1 245\..+,-178\..+L237\..+,-172\..+A294,294 0 0,0 -294,-3\..+Z/);
});
});
describe('with a 2 Pi radian gauge that starts at Pi/2', function() {
beforeAll(function(){
args = {
gauge: {
width: 10,
max: 10,
expand: true,
fullCircle: true
},
data: {
columns: [
['data', 8]
],
type: 'gauge',
fullCircle: true,
startingAngle: Math.PI/2
}
};
});
it('should have correct d for 2 Pi radian gauge starting at Pi/2', function() {
var chartArc = d3.select('.c3-chart-arcs'),
data = chartArc.select('.c3-chart-arc.c3-target.c3-target-data')
.select('g.c3-shapes.c3-shapes-data.c3-arcs.c3-arcs-data')
.select('path.c3-shape.c3-shape.c3-arc.c3-arc-data');
// This test has bee updated to make tests pass. @TODO double-check this test is accurate.
expect(data.attr('d')).toMatch(/M-221.*?,-2\..+A221.*?,221.*? 0 1,1 -68.*?,210.*?L-65.*?,201.*?A211.*?,211.*? 0 1,0 -211.*?,-2.*?Z/);
});
describe('with labels use custom text', function() {
beforeAll(function(){
args = {
gauge: {
width: 10,
max: 100,
expand: true,
label: {
extents: function (value, isMax) {
if (isMax) {
return 'Max: ' + value + '%';
}
return 'Min: ' + value + '%';
}
}
},
data: {
columns: [
['data', 8]
],
type: 'gauge',
fullCircle: true,
startingAngle: Math.PI/2
}
};
});
it('should show custom min/max guage labels', function () {
var chartArc = d3.select('.c3-chart-arcs'),
min = chartArc.select('.c3-chart-arcs-gauge-min'),
max = chartArc.select('.c3-chart-arcs-gauge-max');
expect(min.text()).toMatch('Min: 0%');
expect(max.text()).toMatch('Max: 100%');
});
});
});
});
});

153
spec/axis-spec.js

@ -33,45 +33,47 @@ describe('c3 chart axis', function () {
describe('axis.y.tick.count', function () {
it('should update args to have only 1 tick on y axis', function () {
describe('with only 1 tick on y axis', function () {
beforeAll(function(){
args.axis.y.tick.count = 1;
expect(true).toBeTruthy();
});
it('should have only 1 tick on y axis', function () {
var ticksSize = d3.select('.c3-axis-y').selectAll('g.tick').size();
expect(ticksSize).toBe(1);
});
});
it('should update args to have 2 ticks on y axis', function () {
describe('with 2 ticks on y axis', function () {
beforeAll(function(){
args.axis.y.tick.count = 2;
expect(true).toBeTruthy();
});
it('should have 2 ticks on y axis', function () {
var ticksSize = d3.select('.c3-axis-y').selectAll('g.tick').size();
expect(ticksSize).toBe(2);
});
});
it('should update args to have 3 ticks on y axis', function () {
describe('with 3 ticks on y axis', function () {
beforeAll(function(){
args.axis.y.tick.count = 3;
expect(true).toBeTruthy();
});
it('should have 3 ticks on y axis', function () {
var ticksSize = d3.select('.c3-axis-y').selectAll('g.tick').size();
expect(ticksSize).toBe(3);
});
});
});
describe('axis.y.tick.values', function () {
var values = [100, 500];
it('should update args to have only 2 ticks on y axis', function () {
describe('with only 2 ticks on y axis', function () {
beforeAll(function(){
args.axis.y.tick.values = values;
expect(true).toBeTruthy();
});
it('should have only 2 tick on y axis', function () {
@ -85,12 +87,11 @@ describe('c3 chart axis', function () {
expect(+text).toBe(values[i]);
});
});
});
});
describe('axis y timeseries', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -107,7 +108,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have 7 ticks on y axis', function () {
@ -126,12 +126,12 @@ describe('c3 chart axis', function () {
});
});
it('should update args to set axis.y.time', function () {
describe('with axis.y.time', function () {
beforeAll(function(){
args.axis.y.tick.time = {
value : 'seconds',
interval : 60
};
expect(true).toBeTruthy();
});
it('should have 4 ticks on y axis', function () {
@ -150,10 +150,11 @@ describe('c3 chart axis', function () {
});
});
});
});
describe('axis.x.tick.values', function () {
describe('function is provided', function () {
var tickGenerator = function (/*domain*/) {
var tickGenerator = function () {
var values = [];
for (var i = 0; i <= 300; i += 50) {
values.push(i);
@ -167,7 +168,7 @@ describe('c3 chart axis', function () {
}
};
chart = window.c3.generate(args);
window.generatedTicks = tickGenerator();
window.generatedTicks = tickGenerator(); // This should be removed from window
});
it('should use function to generate ticks', function () {
@ -185,7 +186,7 @@ describe('c3 chart axis', function () {
describe('not rotated', function () {
it('should update args successfully', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -202,7 +203,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should construct indexed x axis properly', function () {
@ -222,7 +222,8 @@ describe('c3 chart axis', function () {
});
});
it('should set axis.x.tick.format', function () {
describe('should set axis.x.tick.format', function () {
beforeAll(function(){
args.axis.x = {
tick: {
format: function () {
@ -230,7 +231,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should split x axis tick text to multiple lines', function () {
@ -287,13 +287,14 @@ describe('c3 chart axis', function () {
});
});
});
});
it('should set big values in y', function () {
describe('should set big values in y', function () {
beforeAll(function(){
args.data.columns = [
['data1', 3000000000000000, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
];
expect(true).toBeTruthy();
});
it('should not split y axis tick text to multiple lines', function () {
@ -303,14 +304,13 @@ describe('c3 chart axis', function () {
expect(tspans.size()).toBe(1);
});
});
});
});
describe('rotated', function () {
it('should update args to rotate axis', function () {
beforeAll(function () {
args.axis.rotated = true;
expect(true).toBeTruthy();
});
it('should split x axis tick text to multiple lines', function () {
@ -367,7 +367,7 @@ describe('c3 chart axis', function () {
describe('not rotated', function () {
it('should update args successfully', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -383,7 +383,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should locate ticks properly', function () {
@ -429,9 +428,8 @@ describe('c3 chart axis', function () {
describe('rotated', function () {
it('should update args to rotate axis', function () {
beforeAll(function () {
args.axis.rotated = true;
expect(true).toBeTruthy();
});
it('should locate ticks on rotated axis properly', function () {
@ -480,11 +478,10 @@ describe('c3 chart axis', function () {
describe('as null', function () {
it('should update args not to split ticks', function () {
beforeAll(function () { //'without split ticks',
args.axis.x.tick = {
multiline: false
};
expect(true).toBeTruthy();
});
it('should split x tick', function () {
@ -497,11 +494,10 @@ describe('c3 chart axis', function () {
describe('as value', function () {
it('should update args not to split ticks', function () {
beforeAll(function () { // 'without split ticks',
args.axis.x.tick = {
width: 150
};
expect(true).toBeTruthy();
});
it('should split x tick to 2 lines properly', function () {
@ -531,11 +527,10 @@ describe('c3 chart axis', function () {
describe('with axis.x.tick.format', function () {
it('should update args to use axis.x.tick.format', function () {
beforeAll(function () { // 'with axis.x.tick.format',
args.axis.x.tick.format = function () {
return ['this is a very long tick text', 'on category axis'];
};
expect(true).toBeTruthy();
});
it('should have multiline tick text', function () {
@ -556,7 +551,7 @@ describe('c3 chart axis', function () {
describe('not rotated', function () {
it('should update args successfully', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -575,7 +570,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should rotate tick texts', function () {
@ -593,7 +587,49 @@ describe('c3 chart axis', function () {
var box = chart.internal.main.select('.c3-axis-x').node().getBoundingClientRect(),
height = chart.internal.getHorizontalAxisHeight('x');
expect(box.height).toBeGreaterThan(50);
expect(height).toBeCloseTo(70, -1);
expect(height).toBeCloseTo(76, -1.3); // @TODO make this test better
});
});
});
describe('axis.y.tick.rotate', function () {
describe('not rotated', function () {
beforeAll(function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 100, 600],
['data2', 50, 20, 10, 40, 15, 25],
]
},
axis: {
rotated: true,
y: {
tick: {
rotate: 45
}
}
}
};
});
it('should rotate tick texts', function () {
chart.internal.main.selectAll('.c3-axis-y g.tick').each(function () {
var tick = d3.select(this),
text = tick.select('text'),
tspan = text.select('tspan');
expect(text.attr('transform')).toBe('rotate(45)');
expect(text.attr('y')).toBe('4');
expect(tspan.attr('dx')).toBeCloseTo('5.6', 0);
});
});
it('should have automatically calculated y axis width', function () {
var box = chart.internal.main.select('.c3-axis-y').node().getBoundingClientRect();
expect(box.width).toBeCloseTo(590, 1);
});
});
@ -603,7 +639,7 @@ describe('c3 chart axis', function () {
describe('axis.x.tick.fit = true', function () {
it('should set args for indexed data', function () {
beforeAll(function () { // 'should set args for indexed data',
args = {
data: {
columns: [
@ -613,7 +649,6 @@ describe('c3 chart axis', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should show fitted ticks on indexed data', function () {
@ -621,7 +656,8 @@ describe('c3 chart axis', function () {
expect(ticks.size()).toBe(6);
});
it('should set args for x-based data', function () {
describe('should set args for x-based data', function () {
beforeAll(function(){
args = {
data: {
x: 'x',
@ -633,7 +669,6 @@ describe('c3 chart axis', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should show fitted ticks on indexed data', function () {
@ -647,12 +682,13 @@ describe('c3 chart axis', function () {
var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick');
expect(ticks.size()).toBe(6);
});
});
});
describe('axis.x.tick.fit = false', function () {
it('should set args for indexed data', function () {
describe('should set args for indexed data', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -669,15 +705,17 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should show fitted ticks on indexed data', function () {
var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick');
expect(ticks.size()).toBe(11);
});
});
it('should set args for x-based data', function () {
describe('should set args for x-based data', function () {
beforeAll(function(){
args.data = {
x: 'x',
columns: [
@ -687,7 +725,6 @@ describe('c3 chart axis', function () {
['data3', 150, 120, 110, 140, 115, 125]
]
};
expect(true).toBeTruthy();
});
it('should show fitted ticks on indexed data', function () {
@ -701,13 +738,13 @@ describe('c3 chart axis', function () {
var ticks = chart.internal.main.selectAll('.c3-axis-x g.tick');
expect(ticks.size()).toBe(10);
});
});
});
});
describe('axis.y.inner', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -721,7 +758,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should not have inner y axis', function () {
@ -733,9 +769,9 @@ describe('c3 chart axis', function () {
});
});
it('should update args to have inner y axis', function () {
describe('with inner y axis', function () {
beforeAll(function(){
args.axis.y.inner = true;
expect(true).toBeTruthy();
});
it('should have inner y axis', function () {
@ -746,12 +782,12 @@ describe('c3 chart axis', function () {
expect(+d3.select(this).attr('x')).toBeGreaterThan(0);
});
});
});
});
describe('axis.y2.inner', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -766,7 +802,6 @@ describe('c3 chart axis', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should not have inner y axis', function () {
@ -778,9 +813,9 @@ describe('c3 chart axis', function () {
});
});
it('should update args to have inner y axis', function () {
describe('with inner y axis', function () {
beforeAll(function(){
args.axis.y2.inner = true;
expect(true).toBeTruthy();
});
it('should have inner y axis', function () {
@ -791,7 +826,7 @@ describe('c3 chart axis', function () {
expect(+d3.select(this).attr('x')).toBeLessThan(0);
});
});
});
});
});

19
spec/c3-helper.js

@ -1,4 +1,8 @@
function initDom() {
import c3 from '../src';
window.c3 = c3;
window.initDom = function () {
'use strict';
var div = document.createElement('div');
@ -7,10 +11,9 @@ function initDom() {
div.style.height = '480px';
document.body.appendChild(div);
document.body.style.margin = '0px';
}
typeof initDom !== 'undefined';
};
function setMouseEvent(chart, name, x, y, element) {
window.setMouseEvent = function(chart, name, x, y, element) {
'use strict';
var paddingLeft = chart.internal.main.node().transform.baseVal.getItem(0).matrix.e,
@ -20,10 +23,9 @@ function setMouseEvent(chart, name, x, y, element) {
false, false, false, false, 0, null);
chart.internal.d3.event = event;
if (element) { element.dispatchEvent(event); }
}
typeof setMouseEvent !== 'undefined';
};
function initChart(chart, args, done) {
window.initChart = function (chart, args, done) {
'use strict';
if (typeof chart === 'undefined') {
@ -43,5 +45,4 @@ function initChart(chart, args, done) {
}, 10);
return chart;
}
typeof initChart !== 'undefined';
};

40
spec/core-spec.js

@ -4,6 +4,9 @@ describe('c3 chart', function () {
var chart;
var args = {
svg: {
classname: 'customclass'
},
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
@ -24,16 +27,23 @@ describe('c3 chart', function () {
expect(svg).not.toBeNull();
});
it('should set 3rd party property to Function', function () {
describe('should set 3rd party property to Function', function () {
beforeAll(function(){
Function.prototype.$extIsFunction = true;
expect(true).toBeTruthy();
});
it('should be created even if 3rd party property has been set', function () {
var svg = d3.select('#chart svg');
expect(svg).not.toBeNull();
});
it('should be created with a custom class', function () {
var svg = d3.select('#chart svg');
expect(svg.attr('class')).not.toBeNull();
expect(svg.attr('class')).toBe('customclass');
});
});
});
describe('size', function () {
@ -53,11 +63,11 @@ describe('c3 chart', function () {
describe('bindto', function () {
describe('selector', function () {
it('update args', function () {
beforeAll(function(){
d3.select('#chart').html('');
args.bindto = '#chart';
expect(true).toBeTruthy();
});
it('should be created', function () {
var svg = d3.select('#chart svg');
expect(svg.size()).toBe(1);
@ -65,10 +75,9 @@ describe('c3 chart', function () {
});
describe('d3.selection object', function () {
it('update args', function () {
beforeAll(function () {
d3.select('#chart').html('');
args.bindto = d3.select('#chart');
expect(true).toBeTruthy();
});
it('should be created', function () {
var svg = d3.select('#chart svg');
@ -77,11 +86,11 @@ describe('c3 chart', function () {
});
describe('null', function () {
it('update args', function () {
beforeAll(function () {
d3.select('#chart').html('');
args.bindto = null;
expect(true).toBeTruthy();
});
it('should not be created', function () {
var svg = d3.select('#chart svg');
expect(svg.size()).toBe(0);
@ -89,22 +98,20 @@ describe('c3 chart', function () {
});
describe('empty string', function () {
it('update args', function () {
beforeAll(function () {
d3.select('#chart').html('');
args.bindto = '';
expect(true).toBeTruthy();
});
it('should not be created', function () {
var svg = d3.select('#chart svg');
expect(svg.size()).toBe(0);
});
});
});
describe('empty data', function () {
it('should upaate args for empty data', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -113,7 +120,6 @@ describe('c3 chart', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should generate a chart', function () {
@ -121,7 +127,8 @@ describe('c3 chart', function () {
expect(ticks.size()).toBe(0);
});
it('should upaate args for empty data', function () {
describe('more empty data', function () {
beforeAll(function(){
args = {
data: {
x: 'x',
@ -137,14 +144,13 @@ describe('c3 chart', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should generate a chart', function () {
var ticks = chart.internal.main.select('.c3-axis-x').selectAll('g.tick');
expect(ticks.size()).toBe(0);
});
});
});
});

355
spec/data-spec.js

@ -9,7 +9,7 @@ describe('c3 chart data', function () {
describe('load json', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
json: {
@ -18,20 +18,20 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should draw correctly', function () {
var expectedCx = [6, 299, 593],
expectedCy = [370, 390, 331];
expectedCy = [371, 391, 332];
d3.selectAll('.c3-circles-data1 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0);
});
});
it('should update args', function () {
describe('more data', function(){
beforeAll(function () {
args = {
data: {
json: [{
@ -57,28 +57,116 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should draw correctly', function () {
var expectedCx = {443: [98, 294, 490], 995: [98, 294, 490]},
expectedCy = {443: [193, 351, 36], 995: [390, 429, 351]};
expectedCy = {443: [194, 351, 36], 995: [391, 430, 351]};
d3.selectAll('.c3-circles-443 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0);
});
d3.selectAll('.c3-circles-995 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0);
});
});
});
describe('with nested JSON args', function () {
beforeAll(function(){
args = {
data: {
json: [{
"date": "2014-06-03",
"443": "3000",
"995": {"996": "500"},
"112": ["600"],
"223": [{"224": "100"}],
"334": [[],[{"335": "300"}]],
"556": {"557" : {"558" : ["1000"]}}
}, {
"date": "2014-06-04",
"443": "1000",
"112": ["700"],
"223": [{"224": "200"}],
"556": {"557" : {"558" : ["2000"]}}
}, {
"date": "2014-06-05",
"995": {"996": "1000"},
"112": ["800"],
"223": [{"224": "300"}],
"443": "5000",
"334": [[],[{"335": "500"}]],
"556": {"557" : {"558" : ["3000"]}}
}],
keys: {
x: 'date',
value: [ "443","995.996","112[0]","223[0].224","334[1][0].335","556.557.558[0]"]
}
},
axis: {
x: {
type: "category"
}
}
};
});
it('should draw nested JSON correctly', function () {
var expectedCx = [98, 294, 490],
expectedCy = {
443: [181, 326, 36],
995: [362, 398, 326],
112: [354, 347, 340],
223: [391, 383, 376],
334: [376, 398, 362],
556: [326, 253, 181]
};
d3.selectAll('.c3-circles-443 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0);
});
d3.selectAll('.c3-circles-995-996 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0);
});
d3.selectAll('.c3-circles-112-0- .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[112][i], 0);
});
d3.selectAll('.c3-circles-223-0--224 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[223][i], 0);
});
d3.selectAll('.c3-circles-334-1--0--335 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[334][i], 0);
});
d3.selectAll('.c3-circles-556-557-558-0- .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[556][i], 0);
});
});
});
});
describe('function in data.order', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -91,7 +179,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should return false in isOrderAsc and isOrderDesc functions', function () {
@ -99,9 +186,68 @@ describe('c3 chart data', function () {
});
});
describe('data.xs', function () {
describe('addHiddenTargetIds if not already hidden', function () {
it('should update args', function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 150, 120, 110, 140, 115, 125]
]
}
};
expect(true).toBeTruthy();
});
it('length of hiddenTargetIds should not change if same key added twice', function () {
chart.internal.addHiddenTargetIds('data1');
expect(chart.internal.hiddenTargetIds.length).toBe(1);
chart.internal.addHiddenTargetIds('data1');
expect(chart.internal.hiddenTargetIds.length).toBe(1);
chart.hide('data1');
expect(chart.internal.hiddenTargetIds.length).toBe(1);
chart.internal.addHiddenTargetIds('data2');
expect(chart.internal.hiddenTargetIds.length).toBe(2);
chart.show();
chart.hide(['data1', 'data2']);
expect(chart.internal.hiddenTargetIds.length).toBe(2);
chart.show();
chart.hide();
expect(chart.internal.hiddenTargetIds.length).toBe(2);
});
});
describe('addHiddenLegendIds if not already hidden', function () {
it('should update args', function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 150, 120, 110, 140, 115, 125]
]
}
};
expect(true).toBeTruthy();
});
it('length of hiddenLegendIds should not change if same key added twice', function () {
chart.internal.addHiddenLegendIds('data1');
expect(chart.internal.hiddenLegendIds.length).toBe(1);
chart.internal.addHiddenLegendIds('data1');
expect(chart.internal.hiddenLegendIds.length).toBe(1);
chart.hide('data1', {withLegend: true});
expect(chart.internal.hiddenLegendIds.length).toBe(1);
chart.hide('data2', {withLegend: true});
expect(chart.internal.hiddenLegendIds.length).toBe(2);
chart.show(['data1', 'data2'], {withLegend: true});
chart.hide(['data1', 'data2'], {withLegend: true});
expect(chart.internal.hiddenLegendIds.length).toBe(2);
});
});
describe('data.xs', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -111,7 +257,6 @@ describe('c3 chart data', function () {
],
}
};
expect(true).toBeTruthy();
});
describe('normal x', function () {
@ -136,7 +281,7 @@ describe('c3 chart data', function () {
describe('timeseries x', function () {
describe('without xFormat', function () {
it('should load timeseries data successfully', function () {
beforeAll(function () {
args = {
data: {
x : 'date',
@ -152,7 +297,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have correct number of xs', function () {
@ -174,7 +318,7 @@ describe('c3 chart data', function () {
describe('with xFormat', function () {
describe('timeseries x with xFormat', function () {
it('should load timeseries data successfully', function () {
beforeAll(function () {
args = {
data: {
x : 'date',
@ -191,7 +335,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have correct number of xs', function () {
@ -216,8 +359,7 @@ describe('c3 chart data', function () {
describe('milliseconds timeseries x', function () {
describe('as date string', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
x : 'date',
@ -238,7 +380,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have correct number of xs', function () {
@ -266,7 +407,7 @@ describe('c3 chart data', function () {
describe('as unixtime number', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
x : 'date',
@ -285,7 +426,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have correct number of xs', function () {
@ -311,7 +451,7 @@ describe('c3 chart data', function () {
describe('on line chart', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -324,7 +464,6 @@ describe('c3 chart data', function () {
labels: true,
}
};
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -349,9 +488,9 @@ describe('c3 chart data', function () {
});
});
it('should update args to be stacked', function () {
describe('with stacked', function () {
beforeAll(function(){
args.data.groups = [['data1', 'data2'], ['data3', 'data4']];
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -375,12 +514,12 @@ describe('c3 chart data', function () {
});
});
});
});
});
describe('on area chart', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -393,7 +532,6 @@ describe('c3 chart data', function () {
labels: true,
}
};
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -418,9 +556,9 @@ describe('c3 chart data', function () {
});
});
it('should update args to be stacked', function () {
describe('with stacked', function () {
beforeAll(function(){
args.data.groups = [['data1', 'data2'], ['data3', 'data4']];
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -444,12 +582,13 @@ describe('c3 chart data', function () {
});
});
});
});
});
describe('on bar chart', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -462,7 +601,6 @@ describe('c3 chart data', function () {
labels: true,
}
};
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -487,9 +625,9 @@ describe('c3 chart data', function () {
});
});
it('should update args to be stacked', function () {
describe('with stacked', function () {
beforeAll(function(){
args.data.groups = [['data1', 'data2'], ['data3', 'data4']];
expect(true).toBeTruthy();
});
it('should locate data labels in correct position', function () {
@ -513,12 +651,13 @@ describe('c3 chart data', function () {
});
});
});
});
});
describe('for all targets', function () {
it('should update args to show data label for all data', function () {
describe('with data label for all data', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -529,7 +668,6 @@ describe('c3 chart data', function () {
labels: true
}
};
expect(true).toBeTruthy();
});
it('should have data labels on all data', function () {
@ -543,14 +681,15 @@ describe('c3 chart data', function () {
expect(d3.select(this).text()).toBe(args.data.columns[2][i + 1] + '');
});
});
});
});
describe('for each target', function () {
describe('as true', function () {
it('should update args to show data label for only data1', function () {
describe('with data label for only data1', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -565,7 +704,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have data labels on all data', function () {
@ -580,10 +718,12 @@ describe('c3 chart data', function () {
});
});
});
});
describe('as function', function () {
it('should update args to show data label for only data1', function () {
describe('with data label for only data1', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -598,7 +738,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have data labels on all data', function () {
@ -613,12 +752,14 @@ describe('c3 chart data', function () {
});
});
});
});
});
describe('with small values', function () {
it('should update args to show data label', function () {
describe('with data label', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -627,7 +768,6 @@ describe('c3 chart data', function () {
labels: true
}
};
expect(true).toBeTruthy();
});
it('should have proper y domain', function () {
@ -636,12 +776,13 @@ describe('c3 chart data', function () {
expect(domain[1]).toBeCloseTo(0.45);
});
});
});
describe('with positive values and null', function () {
describe('on not rotated axis', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -658,7 +799,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -678,9 +818,9 @@ describe('c3 chart data', function () {
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -699,17 +839,17 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
describe('on rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args.data.type = 'bar';
args.axis = {
rotated: true
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -728,10 +868,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -750,7 +891,7 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
});
@ -759,7 +900,8 @@ describe('c3 chart data', function () {
describe('on not rotated axis', function () {
it('should update args', function () {
describe('type bar', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -776,7 +918,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -795,10 +936,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -817,17 +959,17 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
describe('on rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args.data.type = 'bar';
args.axis = {
rotated: true
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -846,10 +988,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -868,7 +1011,7 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
});
@ -877,7 +1020,8 @@ describe('c3 chart data', function () {
describe('on non rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -894,7 +1038,6 @@ describe('c3 chart data', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -913,10 +1056,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -936,20 +1080,21 @@ describe('c3 chart data', function () {
});
});
});
});
describe('on rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args.data.type = 'bar';
args.axis = {
rotated: true
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(-254, -1);
expect(domain[0]).toBeCloseTo(-259, -1);
expect(domain[1]).toBeCloseTo(260, -1);
});
@ -963,15 +1108,16 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(-254, -1);
expect(domain[0]).toBeCloseTo(-259, -1);
expect(domain[1]).toBeCloseTo(260, -1);
});
@ -986,6 +1132,7 @@ describe('c3 chart data', function () {
});
});
});
});
});
@ -993,7 +1140,8 @@ describe('c3 chart data', function () {
describe('on non rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -1006,7 +1154,6 @@ describe('c3 chart data', function () {
type: 'bar',
}
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -1025,10 +1172,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -1047,23 +1195,23 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
describe('on rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args.data.type = 'bar';
args.axis = {
rotated: true
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(0, -1);
expect(domain[1]).toBeCloseTo(888, -1);
expect(domain[1]).toBeCloseTo(888, -1.2);
});
it('should locate labels above each data point', function () {
@ -1076,16 +1224,17 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(-87, -1);
expect(domain[1]).toBeCloseTo(887, -1);
expect(domain[1]).toBeCloseTo(887, -1.2);
});
it('should locate labels above each data point', function () {
@ -1099,6 +1248,7 @@ describe('c3 chart data', function () {
});
});
});
});
});
@ -1106,7 +1256,8 @@ describe('c3 chart data', function () {
describe('on non rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -1119,7 +1270,6 @@ describe('c3 chart data', function () {
type: 'bar',
}
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -1138,10 +1288,11 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
@ -1160,22 +1311,22 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
});
describe('on rotated axis', function () {
it('should update args', function () {
describe('data type bar', function () {
beforeAll(function(){
args.data.type = 'bar';
args.axis = {
rotated: true
};
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(-894, -1);
expect(domain[0]).toBeCloseTo(-899, -1);
expect(domain[1]).toBeCloseTo(0, -1);
});
@ -1189,16 +1340,17 @@ describe('c3 chart data', function () {
expect(+text.attr('x')).toBeCloseTo(expectedXs[i], -2);
});
});
});
it('should update args', function () {
describe('data type line', function () {
beforeAll(function(){
args.data.type = 'line';
expect(true).toBeTruthy();
});
it('should have y domain with proper padding', function () {
var domain = chart.internal.y.domain();
expect(domain[0]).toBeCloseTo(-894, -1);
expect(domain[1]).toBeCloseTo(94, -1);
expect(domain[0]).toBeCloseTo(-899, -1);
expect(domain[1]).toBeCloseTo(101, -1.2);
});
it('should locate labels above each data point', function () {
@ -1212,6 +1364,7 @@ describe('c3 chart data', function () {
});
});
});
});
});

38
spec/domain-spec.js

@ -22,9 +22,9 @@ describe('c3 chart domain', function () {
describe('axis.y.min', function () {
it('should change axis.y.min to -100', function () {
describe('should change axis.y.min to -100', function () {
beforeAll(function(){
args.axis.y.min = -100;
expect(true).toBeTruthy();
});
it('should be set properly when smaller than max of data', function () {
@ -32,10 +32,11 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBe(-150);
expect(domain[1]).toBe(450);
});
});
it('should change axis.y.min to 500', function () {
describe('should change axis.y.min to 500', function () {
beforeAll(function(){
args.axis.y.min = 500;
expect(true).toBeTruthy();
});
it('should be set properly when bigger than max of data', function () {
@ -43,19 +44,18 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBe(499);
expect(domain[1]).toBe(511);
});
});
it('should change axis.y.min to undefined', function () {
afterAll(function(){
args.axis.y.min = undefined;
expect(true).toBeTruthy();
});
});
describe('axis.y.max', function () {
it('should change axis.y.max to 1000', function () {
describe('should change axis.y.max to 1000', function () {
beforeAll(function(){
args.axis.y.max = 1000;
expect(true).toBeTruthy();
});
it('should be set properly when bigger than min of data', function () {
@ -63,10 +63,11 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBe(-89);
expect(domain[1]).toBe(1099);
});
});
it('should change axis.y.max to 0', function () {
describe('should change axis.y.max to 0', function () {
beforeAll(function(){
args.axis.y.max = 0;
expect(true).toBeTruthy();
});
it('should be set properly when smaller than min of data', function () {
@ -74,12 +75,13 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBe(-11);
expect(domain[1]).toBe(1);
});
});
});
describe('axis.y.padding', function () {
it('should change axis.y.max to 1000', function () {
describe('should change axis.y.max to 1000', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -93,7 +95,6 @@ describe('c3 chart domain', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should be set properly when bigger than min of data', function () {
@ -101,8 +102,11 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBeCloseTo(-9, -1);
expect(domain[1]).toBeCloseTo(69, -1);
});
});
it('should change axis.y.max to 1000 with top/bottom padding', function () {
describe('should change axis.y.max to 1000 with top/bottom padding', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -119,7 +123,6 @@ describe('c3 chart domain', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should be set properly when bigger than min of data', function () {
@ -127,7 +130,6 @@ describe('c3 chart domain', function () {
expect(domain[0]).toBeCloseTo(-9, -1);
expect(domain[1]).toBeCloseTo(69, -1);
});
});
});
});

45
spec/grid-spec.js

@ -9,7 +9,7 @@ describe('c3 chart grid', function () {
describe('y grid show', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -28,16 +28,15 @@ describe('c3 chart grid', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should not show y grids', function () {
expect(chart.internal.main.select('.c3-ygrids').size()).toBe(0);
});
it('should update args to show y grids', function () {
describe('with y grids', function () {
beforeAll(function(){
args.grid.y.show = true;
expect(true).toBeTruthy();
});
it('should show y grids', function () {
@ -45,10 +44,11 @@ describe('c3 chart grid', function () {
expect(ygrids.size()).toBe(1);
expect(ygrids.selectAll('.c3-ygrid').size()).toBe(9);
});
});
it('should update args to show only 3 y grids', function () {
describe('with only 3 y grids', function () {
beforeAll(function(){
args.grid.y.ticks = 3;
expect(true).toBeTruthy();
});
it('should show only 3 y grids', function () {
@ -56,10 +56,11 @@ describe('c3 chart grid', function () {
expect(ygrids.size()).toBe(1);
expect(ygrids.selectAll('.c3-ygrid').size()).toBe(3);
});
});
it('should update args to show y grids depending on y axis ticks', function () {
describe('with y grids depending on y axis ticks', function () {
beforeAll(function(){
args.axis.y.tick.count = 5;
expect(true).toBeTruthy();
});
it('should show grids depending on y axis ticks', function () {
@ -76,12 +77,13 @@ describe('c3 chart grid', function () {
});
});
});
});
describe('y grid lines', function () {
describe('position', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -98,7 +100,6 @@ describe('c3 chart grid', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should show 3 grid lines', function () {
@ -127,7 +128,8 @@ describe('c3 chart grid', function () {
});
});
it('should update args', function () {
describe('three gridlines', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -147,7 +149,6 @@ describe('c3 chart grid', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should show 3 grid lines', function () {
@ -175,7 +176,7 @@ describe('c3 chart grid', function () {
expect(+dx).toBe(expectedDxs[i]);
});
});
});
});
});
@ -183,7 +184,7 @@ describe('c3 chart grid', function () {
describe('position', function () {
it('should have correct height', function () {
beforeAll(function () { // 'should have correct height',
args = {
data: {
columns: [
@ -200,7 +201,6 @@ describe('c3 chart grid', function () {
}
},
};
expect(true).toBeTruthy();
});
it('should show 3 grid lines', function () {
@ -229,7 +229,8 @@ describe('c3 chart grid', function () {
});
});
it('should update args', function () {
describe('three grid lines', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -249,7 +250,6 @@ describe('c3 chart grid', function () {
}
},
};
expect(true).toBeTruthy();
});
it('should show 3 grid lines', function () {
@ -277,12 +277,13 @@ describe('c3 chart grid', function () {
expect(+dx).toBe(expectedDxs[i]);
});
});
});
});
describe('with padding.top', function () {
it('should have correct height', function () {
describe('should have correct height', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -300,7 +301,6 @@ describe('c3 chart grid', function () {
top: 50
}
};
expect(true).toBeTruthy();
});
it('should show x grid lines', function () {
@ -315,12 +315,12 @@ describe('c3 chart grid', function () {
expect(t.text()).toBe(expectedText[i]);
});
});
});
});
describe('on category axis', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -343,7 +343,6 @@ describe('c3 chart grid', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should show x grid lines', function () {

20
spec/interaction-spec.js

@ -11,7 +11,7 @@ describe('c3 chart interaction', function () {
describe('custom x', function () {
it('should generate bar chart', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -22,7 +22,6 @@ describe('c3 chart interaction', function () {
type: 'bar'
}
};
expect(true).toBeTruthy();
});
it('should have 4 event rects properly', function () {
@ -35,7 +34,8 @@ describe('c3 chart interaction', function () {
});
});
it('should generate bar chart with only one data', function () {
describe('should generate bar chart with only one data', function () {
beforeAll(function(){
args = {
data: {
x: 'x',
@ -46,7 +46,6 @@ describe('c3 chart interaction', function () {
type: 'bar'
}
};
expect(true).toBeTruthy();
});
it('should have 1 event rects properly', function () {
@ -59,10 +58,10 @@ describe('c3 chart interaction', function () {
});
});
});
});
describe('timeseries', function () {
it('should generate line chart with timeseries', function () {
beforeAll(function () {
args = {
data: {
x: 'x',
@ -72,7 +71,6 @@ describe('c3 chart interaction', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should have 4 event rects properly', function () {
@ -86,7 +84,8 @@ describe('c3 chart interaction', function () {
});
it('should generate line chart with only 1 data timeseries', function () {
describe('should generate line chart with only 1 data timeseries', function () {
beforeAll(function(){
args = {
data: {
x: 'x',
@ -96,7 +95,6 @@ describe('c3 chart interaction', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should have 1 event rects properly', function () {
@ -108,9 +106,7 @@ describe('c3 chart interaction', function () {
expect(box.width).toBeCloseTo(598, -2);
});
});
});
});
});
});

53
spec/legend-spec.js

@ -9,7 +9,7 @@ describe('c3 chart legend', function () {
describe('legend when multiple charts rendered', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -19,10 +19,10 @@ describe('c3 chart legend', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should update args with long data names', function () {
describe('long data names', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -32,7 +32,6 @@ describe('c3 chart legend', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should have properly computed legend width', function () {
@ -45,10 +44,11 @@ describe('c3 chart legend', function () {
});
});
});
});
describe('legend position', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -57,19 +57,19 @@ describe('c3 chart legend', function () {
]
}
};
expect(true).toBeTruthy();
});
it('should be located on the center of chart', function () {
var box = chart.internal.legend.node().getBoundingClientRect();
expect(box.left + box.right).toBe(640);
expect(box.left + box.right).toBe(638);
});
});
describe('legend as inset', function () {
it('should change the legend to "inset" successfully', function () {
describe('should change the legend to "inset" successfully', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -84,7 +84,6 @@ describe('c3 chart legend', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should be positioned properly', function () {
@ -97,28 +96,32 @@ describe('c3 chart legend', function () {
var box = d3.select('.c3-legend-background').node().getBoundingClientRect();
expect(box.height).toBe(48);
});
});
it('should change the legend step to 1 successfully', function () {
describe('should change the legend step to 1 successfully', function () {
beforeAll(function(){
args.legend.inset.step = 1;
expect(true).toBeTruthy();
});
it('should have automatically calculated height', function () {
var box = d3.select('.c3-legend-background').node().getBoundingClientRect();
expect(box.height).toBe(28);
});
});
it('should change the legend step to 2 successfully', function () {
describe('should change the legend step to 2 successfully', function () {
beforeAll(function(){
args.legend.inset.step = 2;
expect(true).toBeTruthy();
});
it('should have automatically calculated height', function () {
var box = d3.select('.c3-legend-background').node().getBoundingClientRect();
expect(box.height).toBe(48);
});
});
it('should update args to have only one series', function () {
describe('with only one series', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -129,7 +132,6 @@ describe('c3 chart legend', function () {
position: 'inset'
}
};
expect(true).toBeTruthy();
});
it('should locate legend properly', function () {
@ -137,12 +139,12 @@ describe('c3 chart legend', function () {
expect(box.height).toBe(28);
expect(box.width).toBeGreaterThan(64);
});
});
});
describe('legend.hide', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -154,7 +156,6 @@ describe('c3 chart legend', function () {
hide: true
}
};
expect(true).toBeTruthy();
});
it('should not show legends', function () {
@ -163,7 +164,8 @@ describe('c3 chart legend', function () {
});
});
it('should update args', function () {
describe('hidden legend', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -175,19 +177,19 @@ describe('c3 chart legend', function () {
hide: 'data2'
}
};
expect(true).toBeTruthy();
});
it('should not show legends', function () {
expect(d3.select('.c3-legend-item-data1').style('visibility')).toBe('visible');
expect(d3.select('.c3-legend-item-data2').style('visibility')).toBe('hidden');
});
});
});
describe('legend.show', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -199,7 +201,6 @@ describe('c3 chart legend', function () {
show: false
}
};
expect(true).toBeTruthy();
});
it('should not initially have rendered any legend items', function () {
@ -218,7 +219,7 @@ describe('c3 chart legend', function () {
});
describe('custom legend size', function() {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -235,7 +236,6 @@ describe('c3 chart legend', function () {
}
}
};
expect(true).toBeTruthy();
});
it('renders the legend item with the correct width and height', function () {
@ -248,7 +248,7 @@ describe('c3 chart legend', function () {
});
describe('custom legend padding', function() {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -260,14 +260,13 @@ describe('c3 chart legend', function () {
padding: 10
}
};
expect(true).toBeTruthy();
});
it('renders the correct amount of padding on the legend element', function () {
d3.selectAll('.c3-legend-item-padded1 .c3-legend-item-tile, .c3-legend-item-padded2 .c3-legend-item-tile').each(function (el, index) {
var itemWidth = d3.select(this).node().parentNode.getBBox().width,
textBoxWidth = d3.select(d3.select(this).node().parentNode).select('text').node().getBBox().width,
tileWidth = 15, // default value is 10, plus 5 more for padding
tileWidth = 17, // default value is 10, plus 7 more for padding @TODO verify this, seems PhantomJS@^2 adds another 1px to each side
expectedWidth = textBoxWidth + tileWidth + (index ? 0 : 10) + args.legend.padding;
expect(itemWidth).toBe(expectedWidth);

16
spec/shape.bar-spec.js

@ -12,7 +12,7 @@ describe('c3 chart shape bar', function () {
describe('with groups', function () {
describe('with indexed data', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -25,7 +25,6 @@ describe('c3 chart shape bar', function () {
type: 'bar'
},
};
expect(true).toBeTruthy();
});
it('should be stacked', function () {
var expectedBottom = [275, 293, 365, 281, 395, 290];
@ -37,7 +36,7 @@ describe('c3 chart shape bar', function () {
});
describe('with timeseries data', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
x: 'date',
@ -57,7 +56,6 @@ describe('c3 chart shape bar', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should be stacked', function () {
var expectedBottom = [275, 293, 365, 281, 395, 290];
@ -69,7 +67,7 @@ describe('c3 chart shape bar', function () {
});
describe('with category data', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
x: 'date',
@ -89,8 +87,8 @@ describe('c3 chart shape bar', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should be stacked', function () {
var expectedBottom = [275, 293, 365, 281, 395, 290];
chart.internal.main.selectAll('.c3-bars-data1 .c3-bar').each(function (d, i) {
@ -106,7 +104,7 @@ describe('c3 chart shape bar', function () {
describe('with normal axis', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -120,7 +118,6 @@ describe('c3 chart shape bar', function () {
rotated: false
}
};
expect(true).toBeTruthy();
});
it('should not be within bar', function () {
@ -151,9 +148,8 @@ describe('c3 chart shape bar', function () {
describe('with rotated axis', function () {
it('should change the chart as axis rotated', function () {
beforeAll(function () {
args.axis.rotated = true;
expect(true).toBeTruthy();
});
it('should not be within bar', function () {

105
spec/shape.line-spec.js

@ -7,9 +7,11 @@ describe('c3 chart shape line', function () {
chart = window.initChart(chart, args, done);
});
var parseSvgPath = window.parseSvgPath;
describe('shape-rendering for line chart', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -20,7 +22,15 @@ describe('c3 chart shape line', function () {
type: 'line'
}
};
expect(true).toBeTruthy();
});
it("Should render the lines correctly", function(done) {
setTimeout(function () {
var target = chart.internal.main.select('.c3-chart-line.c3-target-data1');
var commands = parseSvgPath( target.select('.c3-line-data1').attr('d'));
expect(commands.length).toBe(6);
done();
}, 500);
});
it("should not have shape-rendering when it's line chart", function () {
@ -30,32 +40,35 @@ describe('c3 chart shape line', function () {
});
});
it('should change to step chart', function () {
describe('should change to step chart', function () {
beforeAll(function(){
args.data.type = 'step';
expect(true).toBeTruthy();
});
it("should have shape-rendering = crispedges when it's step chart", function () {
d3.selectAll('.c3-line').each(function () {
var style = d3.select(this).style('shape-rendering');
var style = d3.select(this).style('shape-rendering').toLowerCase();
expect(style).toBe('crispedges');
});
});
});
it('should change to spline chart', function () {
describe('should change to spline chart', function () {
beforeAll(function(){
args.data.type = 'spline';
expect(true).toBeTruthy();
});
it('should use cardinal interpolation by default', function () {
expect(chart.internal.config.spline_interpolation_type).toBe('cardinal');
});
});
});
describe('point.show option', function () {
it('should change args to include null data', function () {
describe('should change args to include null data', function () {
beforeAll(function(){
args = {
data: {
columns: [
@ -66,7 +79,6 @@ describe('c3 chart shape line', function () {
type: 'line'
}
};
expect(true).toBeTruthy();
});
it('should not show the circle for null', function (done) {
@ -79,35 +91,73 @@ describe('c3 chart shape line', function () {
}, 500);
});
it('should change args to include null data on scatter plot', function () {
it('should not draw a line segment for null data', function(done) {
setTimeout(function () {
var target = chart.internal.main.select('.c3-chart-line.c3-target-data1');
var commands = parseSvgPath( target.select('.c3-line-data1').attr('d'));
var segments = 0;
for(var i = 0; i < commands.length; i++) {
(commands[i].command === 'L') ? segments++ : null;
}
expect(segments).toBe(3);
done();
}, 500);
});
// it('should change args to include null data on scatter plot', function () {
// args = {
// data: {
// columns: [
// ['data1', 30, null, 100, 400, -150, 250],
// ['data2', 50, 20, 10, 40, 15, 25],
// ['data3', -150, 120, 110, 140, 115, 125]
// ],
// type: 'scatter'
// }
// };
// expect(true).toBeTruthy();
// });
// it('should not show the circle for null', function (done) {
// setTimeout(function () {
// var target = chart.internal.main.select('.c3-chart-line.c3-target-data1');
// expect(+target.select('.c3-circle-0').style('opacity')).toBe(0.5);
// expect(+target.select('.c3-circle-1').style('opacity')).toBe(0);
// expect(+target.select('.c3-circle-2').style('opacity')).toBe(0.5);
// done();
// }, 500);
// });
});
describe('should allow passing a function', function() {
beforeAll(function(){
args = {
data: {
columns: [
['data1', 30, null, 100, 400, -150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', -150, 120, 110, 140, 115, 125]
['data1', 30, 50, 100]
],
type: 'scatter'
type: 'line'
},
point: {
show: function(d) {
return d.value > 50;
}
}
};
expect(true).toBeTruthy();
});
it('should not show the circle for null', function (done) {
setTimeout(function () {
it('should show point if function returns true', function() {
var target = chart.internal.main.select('.c3-chart-line.c3-target-data1');
expect(+target.select('.c3-circle-0').style('opacity')).toBe(0.5);
expect(+target.select('.c3-circle-0').style('opacity')).toBe(0);
expect(+target.select('.c3-circle-1').style('opacity')).toBe(0);
expect(+target.select('.c3-circle-2').style('opacity')).toBe(0.5);
done();
}, 500);
expect(+target.select('.c3-circle-2').style('opacity')).toBe(1);
});
});
});
describe('spline.interpolation option', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -123,22 +173,21 @@ describe('c3 chart shape line', function () {
}
}
};
expect(true).toBeTruthy();
});
it('should update interpolation function', function() {
it('updates interpolation function', function() {
expect(chart.internal.getInterpolate(chart.data()[0])).toBe('monotone');
});
it('should not use a non-valid interpolation', function () {
describe('should not use a non-valid interpolation', function () {
beforeAll(function(){
args.spline.interpolation.type = 'foo';
expect(true).toBeTruthy();
});
it('should use cardinal interpolation when given option is not valid', function() {
expect(chart.internal.getInterpolate(chart.data()[0])).toBe('cardinal');
});
});
});
});

50
spec/svg-helper.js

@ -0,0 +1,50 @@
/**
* Parse the d property of an SVG path into an array of drawing commands.
* @param {String} d SvgPath d attribute.]
* @return {Array} an array of drawing commands.
*/
function parseSvgPath(d) { //jshint ignore:line
'use strict';
var commands = [];
var commandTokens = ['M','L','I','H','V','C','S','Q','T','A'];
var command;
var in_x = false;
var in_y = false;
var x = '';
var y = '';
for(var i = 0; i <= d.length; i++) {
if (commandTokens.indexOf(d[i]) !== -1) {
if (in_x || in_y) {
commands.push({command: command, x: x, y: y});
x = '';
y = '';
}
command = d[i];
in_x = true;
in_y = false;
}
else {
if (d[i] === ',') {
if (in_y) {
commands.push({command: command, x: x, y: y});
x = '';
y = '';
}
in_x = !in_x;
in_y = !in_y;
}
else if (in_x) {
x += d[i];
}
else if (in_y) {
y += d[i];
}
}
}
if (d[i] !== ',' && in_y) {
commands.push({command: command, x: x, y: y});
}
return commands;
}

334
spec/tooltip-spec.js

@ -2,16 +2,20 @@ describe('c3 chart tooltip', function () {
'use strict';
var chart;
var tooltipConfiguration;
var tooltipConfiguration = {};
var dataOrder = 'desc';
var dataGroups;
var args = function () {
return {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', 150, 120, 110, 140, 115, 125]
['data1', 30, 200, 100, 400, 150, 250], // 1130
['data2', 50, 20, 10, 40, 15, 25], // 160
['data3', 150, 120, 110, 140, 115, 125] // 760
],
order: dataOrder,
groups: dataGroups,
},
tooltip: tooltipConfiguration
};
@ -19,6 +23,8 @@ describe('c3 chart tooltip', function () {
beforeEach(function (done) {
chart = window.initChart(chart, args(), done);
dataOrder = 'desc';
dataGroups = undefined;
});
describe('tooltip position', function () {
@ -45,9 +51,8 @@ describe('c3 chart tooltip', function () {
describe('with left margin', function () {
it('should set left margin', function () {
beforeAll(function () {
d3.select('#chart').style('margin-left', '300px');
expect(true).toBeTruthy();
});
it('should show tooltip on proper position', function () {
@ -119,4 +124,321 @@ describe('c3 chart tooltip', function () {
}
});
});
describe('tooltip with data_order as desc with grouped data', function() {
beforeAll(function() {
dataOrder = 'desc';
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each data in descending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data1'); // 1130
expect(classes[2]).toBe('c3-tooltip-name--data3'); // 760
expect(classes[3]).toBe('c3-tooltip-name--data2'); // 160
});
});
describe('tooltip with data_order as asc with grouped data', function() {
beforeAll(function() {
dataOrder = 'asc';
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each data in ascending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2'); // 160
expect(classes[2]).toBe('c3-tooltip-name--data3'); // 760
expect(classes[3]).toBe('c3-tooltip-name--data1'); // 1130
});
});
describe('tooltip with data_order as NULL with grouped data', function() {
beforeAll(function() {
dataOrder = null;
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each data in given order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data1');
expect(classes[2]).toBe('c3-tooltip-name--data2');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with data_order as Function with grouped data', function() {
beforeAll(function() {
var order = [ 'data2', 'data1', 'data3' ];
dataOrder = function(data1, data2) {
return order.indexOf(data1.id) - order.indexOf(data2.id);
};
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each data in order given by function', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with data_order as Array with grouped data', function() {
beforeAll(function() {
dataOrder = [ 'data2', 'data1', 'data3' ];
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each data in order given by array', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with data_order as desc with un-grouped data', function() {
beforeAll(function() {
dataOrder = 'desc';
});
it('should display each tooltip value descending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data3'); // 110
expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100
expect(classes[3]).toBe('c3-tooltip-name--data2'); // 10
});
});
describe('tooltip with data_order as asc with un-grouped data', function() {
beforeAll(function() {
dataOrder = 'asc';
});
it('should display each tooltip value in ascending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2'); // 10
expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100
expect(classes[3]).toBe('c3-tooltip-name--data3'); // 110
});
});
describe('tooltip with data_order as NULL with un-grouped data', function() {
beforeAll(function() {
dataOrder = null;
});
it('should display each tooltip value in given data order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data1');
expect(classes[2]).toBe('c3-tooltip-name--data2');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with data_order as Function with un-grouped data', function() {
beforeAll(function() {
var order = [ 'data2', 'data1', 'data3' ];
dataOrder = function(data1, data2) {
return order.indexOf(data1.id) - order.indexOf(data2.id);
};
});
it('should display each tooltip value in data order given by function', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with data_order as Array with un-grouped data', function() {
beforeAll(function() {
dataOrder = [ 'data2', 'data1', 'data3' ];
});
it('should display each tooltip value in data order given by array', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with tooltip_order as desc', function() {
beforeAll(function() {
tooltipConfiguration = {
order: 'desc'
};
// this should be ignored
dataOrder = 'asc';
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each tooltip value descending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data3'); // 110
expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100
expect(classes[3]).toBe('c3-tooltip-name--data2'); // 10
});
});
describe('tooltip with tooltip_order as asc', function() {
beforeAll(function() {
tooltipConfiguration = {
order: 'asc'
};
// this should be ignored
dataOrder = 'desc';
dataGroups = [ [ 'data1', 'data2', 'data3' ]];
});
it('should display each tooltip value in ascending order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2'); // 10
expect(classes[2]).toBe('c3-tooltip-name--data1'); // 100
expect(classes[3]).toBe('c3-tooltip-name--data3'); // 110
});
});
describe('tooltip with tooltip_order as NULL', function() {
beforeAll(function() {
tooltipConfiguration = {
order: null
};
});
it('should display each tooltip value in given order', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data1');
expect(classes[2]).toBe('c3-tooltip-name--data2');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with tooltip_order as Function', function() {
beforeAll(function() {
var order = [ 'data2', 'data1', 'data3' ];
tooltipConfiguration = {
order: function(data1, data2) {
return order.indexOf(data1.id) - order.indexOf(data2.id);
}
};
});
it('should display each tooltip value in data order given by function', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
describe('tooltip with tooltip_order as Array', function() {
beforeAll(function() {
tooltipConfiguration = {
order: [ 'data2', 'data1', 'data3' ]
};
});
it('should display each tooltip value in data order given by array', function() {
window.setMouseEvent(chart, 'mousemove', 100, 100, d3.select('.c3-event-rect-2').node());
var classes = d3.selectAll('.c3-tooltip tr')[0].map(function(node) {
return node.className;
});
expect(classes[0]).toBe(''); // header
expect(classes[1]).toBe('c3-tooltip-name--data2');
expect(classes[2]).toBe('c3-tooltip-name--data1');
expect(classes[3]).toBe('c3-tooltip-name--data3');
});
});
});

30
spec/type-spec.js

@ -11,7 +11,7 @@ describe('c3 chart types', function () {
describe('with data', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -22,48 +22,48 @@ describe('c3 chart types', function () {
type: 'pie'
}
};
expect(true).toBeTruthy();
});
it('should return true', function () {
expect(chart.internal.hasArcType()).toBeTruthy();
});
it('should change chart type to "bar"', function () {
describe('should change chart type to "bar"', function () {
beforeAll(function(){
args.data.type = 'bar';
expect(true).toBeTruthy();
});
it('should return false', function () {
expect(chart.internal.hasArcType()).toBeFalsy();
});
});
});
describe('with empty data', function () {
it('should update args to have empty data', function () {
beforeAll(function () {
args = {
data: {
columns: [],
type: 'pie'
}
};
expect(true).toBeTruthy();
});
it('should return true', function () {
expect(chart.internal.hasArcType()).toBeTruthy();
});
it('should change chart type to "bar"', function () {
describe('should change chart type to "bar"', function () {
beforeAll(function(){
args.data.type = 'bar';
expect(true).toBeTruthy();
});
it('should return false', function () {
expect(chart.internal.hasArcType()).toBeFalsy();
});
});
});
@ -71,7 +71,7 @@ describe('c3 chart types', function () {
describe('internal.hasType', function () {
it('should update args', function () {
beforeAll(function () {
args = {
data: {
columns: [
@ -82,7 +82,6 @@ describe('c3 chart types', function () {
type: 'pie'
}
};
expect(true).toBeTruthy();
});
it('should return true for "pie" type', function () {
@ -97,9 +96,9 @@ describe('c3 chart types', function () {
expect(chart.internal.hasType('bar')).toBeFalsy();
});
it('should unload successfully', function () {
describe('should unload successfully', function () {
beforeAll(function(){
chart.unload([]);
expect(true).toBeTruthy();
});
it('should return true for "pie" type even if no data', function () {
@ -114,9 +113,9 @@ describe('c3 chart types', function () {
expect(chart.internal.hasType('bar')).toBeFalsy();
});
it('should change chart type to "bar" successfully', function () {
describe('should change chart type to "bar" successfully', function () {
beforeAll(function(){
args.data.type = 'bar';
expect(true).toBeTruthy();
});
it('should return false for "pie" type even if no data', function () {
@ -130,7 +129,8 @@ describe('c3 chart types', function () {
it('should return true for "bar" type even if no data', function () {
expect(chart.internal.hasType('bar')).toBeTruthy();
});
});
});
});

3
src/api.axis.js

@ -1,3 +1,6 @@
import { c3_chart_fn } from './core';
import { isValue, isDefined } from './util';
c3_chart_fn.axis = function () {};
c3_chart_fn.axis.labels = function (labels) {
var $$ = this.internal;

2
src/api.category.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.category = function (i, category) {
var $$ = this.internal, config = $$.config;
if (arguments.length > 1) {

2
src/api.chart.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.resize = function (size) {
var $$ = this.internal, config = $$.config;
config.size_width = size ? size.width : null;

2
src/api.color.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
// TODO: fix
c3_chart_fn.color = function (id) {
var $$ = this.internal;

2
src/api.data.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.data = function (targetIds) {
var targets = this.internal.data.targets;
return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {

6
src/api.flow.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_fn, c3_chart_internal_fn } from './core';
import { isValue, isDefined, diffDomain } from './util';
c3_chart_fn.flow = function (args) {
var $$ = this.internal,
targets, data, notfoundIds = [], orgDataCount = $$.getMaxDataCount(),
@ -202,7 +206,7 @@ c3_chart_internal_fn.generateFlow = function (args) {
translateX = diffDomain(domain) / 2;
}
}
} else if (flow.orgDataCount === 1 || flowStart.x === flowEnd.x) {
} else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
} else {
if ($$.isTimeSeries()) {

3
src/api.focus.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_fn } from './core';
c3_chart_fn.focus = function (targetIds) {
var $$ = this.internal, candidates;

2
src/api.grid.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.xgrids = function (grids) {
var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_x_lines; }

3
src/api.group.js

@ -1,3 +1,6 @@
import { c3_chart_fn } from './core';
import { isUndefined } from './util';
c3_chart_fn.groups = function (groups) {
var $$ = this.internal, config = $$.config;
if (isUndefined(groups)) { return config.data_groups; }

2
src/api.legend.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.legend = function () {};
c3_chart_fn.legend.show = function (targetIds) {
var $$ = this.internal;

6
src/api.load.js

@ -1,9 +1,15 @@
import { c3_chart_fn } from './core';
c3_chart_fn.load = function (args) {
var $$ = this.internal, config = $$.config;
// update xs if specified
if (args.xs) {
$$.addXs(args.xs);
}
// update names if exists
if ('names' in args) {
c3_chart_fn.data.names.bind(this)(args.names);
}
// update classes if exists
if ('classes' in args) {
Object.keys(args.classes).forEach(function (id) {

3
src/api.region.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_fn } from './core';
c3_chart_fn.regions = function (regions) {
var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; }

4
src/api.selection.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_fn } from './core';
import { isDefined } from './util';
c3_chart_fn.selected = function (targetId) {
var $$ = this.internal, d3 = $$.d3;
return d3.merge(

2
src/api.show.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.show = function (targetIds, options) {
var $$ = this.internal, targets;

3
src/api.tooltip.js

@ -1,3 +1,6 @@
import { c3_chart_fn } from './core';
import { isValue } from './util';
c3_chart_fn.tooltip = function () {};
c3_chart_fn.tooltip.show = function (args) {
var $$ = this.internal, index, mouse;

2
src/api.transform.js

@ -1,3 +1,5 @@
import { c3_chart_fn, c3_chart_internal_fn } from './core';
c3_chart_fn.transform = function (type, targetIds) {
var $$ = this.internal,
options = ['pie', 'donut'].indexOf(type) >= 0 ? {withTransform: true} : null;

2
src/api.x.js

@ -1,3 +1,5 @@
import { c3_chart_fn } from './core';
c3_chart_fn.x = function (x) {
var $$ = this.internal;
if (arguments.length) {

3
src/api.zoom.js

@ -1,3 +1,6 @@
import { c3_chart_fn } from './core';
import { isDefined } from './util';
c3_chart_fn.zoom = function (domain) {
var $$ = this.internal;
if (domain) {

53
src/arc.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isFunction } from './util';
c3_chart_internal_fn.initPie = function () {
var $$ = this, d3 = $$.d3, config = $$.config;
$$.pie = d3.layout.pie().value(function (d) {
@ -29,7 +33,12 @@ c3_chart_internal_fn.updateArc = function () {
c3_chart_internal_fn.updateAngle = function (d) {
var $$ = this, config = $$.config,
found = false, index = 0,
gMin = config.gauge_min, gMax = config.gauge_max, gTic, gValue;
gMin, gMax, gTic, gValue;
if (!config) {
return null;
}
$$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {
if (! found && t.data.id === d.data.id) {
found = true;
@ -45,9 +54,11 @@ c3_chart_internal_fn.updateAngle = function (d) {
d.endAngle = d.startAngle;
}
if ($$.isGaugeType(d.data)) {
gTic = (Math.PI) / (gMax - gMin);
gMin = config.gauge_min;
gMax = config.gauge_max;
gTic = (Math.PI * (config.gauge_fullCircle ? 2 : 1)) / (gMax - gMin);
gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : (gMax - gMin);
d.startAngle = -1 * (Math.PI / 2);
d.startAngle = config.gauge_startingAngle;
d.endAngle = d.startAngle + gTic * gValue;
}
return found ? d : null;
@ -101,8 +112,13 @@ c3_chart_internal_fn.transformForArcLabel = function (d) {
x = isNaN(c[0]) ? 0 : c[0];
y = isNaN(c[1]) ? 0 : c[1];
h = Math.sqrt(x * x + y * y);
// TODO: ratio should be an option?
if ($$.hasType('donut') && config.donut_label_ratio) {
ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio;
} else if ($$.hasType('pie') && config.pie_label_ratio) {
ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio;
} else {
ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
}
translate = "translate(" + (x * ratio) + ',' + (y * ratio) + ")";
}
else if (updated && hasGauge && $$.visibleTargetCount > 1) {
@ -116,7 +132,8 @@ c3_chart_internal_fn.transformForArcLabel = function (d) {
c3_chart_internal_fn.getArcRatio = function (d) {
var $$ = this,
whole = $$.hasType('gauge') ? Math.PI : (Math.PI * 2);
config = $$.config,
whole = Math.PI * ($$.hasType('gauge') && !config.gauge_fullCircle ? 1 : 2);
return d ? (d.endAngle - d.startAngle) / whole : null;
};
@ -142,6 +159,13 @@ c3_chart_internal_fn.textForArcLabel = function (d) {
return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio);
};
c3_chart_internal_fn.textForGaugeMinMax = function (value, isMax) {
var $$ = this,
format = $$.getGaugeLabelExtents();
return format ? format(value, isMax) : value;
};
c3_chart_internal_fn.expandArc = function (targetIds) {
var $$ = this, interval;
@ -241,6 +265,11 @@ c3_chart_internal_fn.getArcLabelFormat = function () {
return format;
};
c3_chart_internal_fn.getGaugeLabelExtents = function () {
var $$ = this, config = $$.config;
return config.gauge_label_extents;
};
c3_chart_internal_fn.getArcTitle = function () {
var $$ = this;
return $$.hasType('donut') ? $$.config.donut_title : "";
@ -291,7 +320,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
.style("opacity", 0)
.each(function (d) {
if ($$.isGaugeType(d.data)) {
d.startAngle = d.endAngle = -1 * (Math.PI / 2);
d.startAngle = d.endAngle = config.gauge_startingAngle;
}
this._current = d;
});
@ -435,8 +464,8 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
var d = {
data: [{value: config.gauge_max}],
startAngle: -1 * (Math.PI / 2),
endAngle: Math.PI / 2,
startAngle: config.gauge_startingAngle,
endAngle: -1 * config.gauge_startingAngle,
index: index++
};
return $$.getArc(d, true, true);
@ -445,13 +474,13 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
.attr("dy", ".75em")
.text(config.gauge_label_show ? config.gauge_units : '');
$$.arcs.select('.' + CLASS.chartArcsGaugeMin)
.attr("dx", -1 * ($$.innerRadius + (($$.radius - $$.innerRadius) / 2)) + "px")
.attr("dx", -1 * ($$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2))) + "px")
.attr("dy", "1.2em")
.text(config.gauge_label_show ? config.gauge_min : '');
.text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : '');
$$.arcs.select('.' + CLASS.chartArcsGaugeMax)
.attr("dx", $$.innerRadius + (($$.radius - $$.innerRadius) / 2) + "px")
.attr("dx", $$.innerRadius + (($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px")
.attr("dy", "1.2em")
.text(config.gauge_label_show ? config.gauge_max : '');
.text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : '');
}
};
c3_chart_internal_fn.initGauge = function () {

24
src/axis.js

@ -1,4 +1,9 @@
function Axis(owner) {
import CLASS from './class';
import { inherit, API } from './core';
import { isValue, isFunction, isString, isEmpty } from './util';
import c3_axis from './c3.axis';
export default function Axis(owner) {
API.call(this, owner);
}
@ -76,17 +81,16 @@ Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, a
}
return tickValues;
};
Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition) {
var axisParams = {
Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
var $$ = this.owner, config = $$.config,
axisParams = {
withOuterTick: withOuterTick,
withoutTransition: withoutTransition,
tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
},
$$ = this.owner,
d3 = $$.d3,
config = $$.config,
axis = c3_axis(d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
if ($$.isTimeSeriesY()) {
axis.ticks(d3.time[config.axis_y_tick_time_value], config.axis_y_tick_time_interval);
axis.ticks($$.d3.time[config.axis_y_tick_time_value], config.axis_y_tick_time_interval);
} else {
axis.tickValues(tickValues);
}
@ -276,10 +280,10 @@ Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute)
targetsToShow = $$.filterTargetsToShow($$.data.targets);
if (id === 'y') {
scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true);
axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true, true);
} else if (id === 'y2') {
scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true);
axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true, true);
} else {
scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);

2
src/c3.axis.js

@ -3,7 +3,7 @@
// 2. ceil values of translate/x/y to int for half pixel antialiasing
// 3. multiline tick text
var tickTextCharSize;
function c3_axis(d3, params) {
export default function c3_axis(d3, params) {
var scale = d3.scale.linear(), orient = "bottom", innerTickSize = 6, outerTickSize, tickPadding = 3, tickValues = null, tickFormat, tickArguments;
var tickOffset = 0, tickCulling = true, tickCentered;

2
src/cache.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.hasCaches = function (ids) {
for (var i = 0; i < ids.length; i++) {
if (! (ids[i] in this.cache)) { return false; }

2
src/category.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.categoryName = function (i) {
var config = this.config;
return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;

101
src/class-utils.js

@ -0,0 +1,101 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.generateClass = function (prefix, targetId) {
return " " + prefix + " " + prefix + this.getTargetSelectorSuffix(targetId);
};
c3_chart_internal_fn.classText = function (d) {
return this.generateClass(CLASS.text, d.index);
};
c3_chart_internal_fn.classTexts = function (d) {
return this.generateClass(CLASS.texts, d.id);
};
c3_chart_internal_fn.classShape = function (d) {
return this.generateClass(CLASS.shape, d.index);
};
c3_chart_internal_fn.classShapes = function (d) {
return this.generateClass(CLASS.shapes, d.id);
};
c3_chart_internal_fn.classLine = function (d) {
return this.classShape(d) + this.generateClass(CLASS.line, d.id);
};
c3_chart_internal_fn.classLines = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
};
c3_chart_internal_fn.classCircle = function (d) {
return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
};
c3_chart_internal_fn.classCircles = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
};
c3_chart_internal_fn.classBar = function (d) {
return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
};
c3_chart_internal_fn.classBars = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
};
c3_chart_internal_fn.classArc = function (d) {
return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
};
c3_chart_internal_fn.classArcs = function (d) {
return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
};
c3_chart_internal_fn.classArea = function (d) {
return this.classShape(d) + this.generateClass(CLASS.area, d.id);
};
c3_chart_internal_fn.classAreas = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
};
c3_chart_internal_fn.classRegion = function (d, i) {
return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
};
c3_chart_internal_fn.classEvent = function (d) {
return this.generateClass(CLASS.eventRect, d.index);
};
c3_chart_internal_fn.classTarget = function (id) {
var $$ = this;
var additionalClassSuffix = $$.config.data_classes[id], additionalClass = '';
if (additionalClassSuffix) {
additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
}
return $$.generateClass(CLASS.target, id) + additionalClass;
};
c3_chart_internal_fn.classFocus = function (d) {
return this.classFocused(d) + this.classDefocused(d);
};
c3_chart_internal_fn.classFocused = function (d) {
return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
};
c3_chart_internal_fn.classDefocused = function (d) {
return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
};
c3_chart_internal_fn.classChartText = function (d) {
return CLASS.chartText + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartLine = function (d) {
return CLASS.chartLine + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartBar = function (d) {
return CLASS.chartBar + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartArc = function (d) {
return CLASS.chartArc + this.classTarget(d.data.id);
};
c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
return targetId || targetId === 0 ? ('-' + targetId).replace(/[\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\]/g, '-') : '';
};
c3_chart_internal_fn.selectorTarget = function (id, prefix) {
return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorTargets = function (ids, prefix) {
var $$ = this;
ids = ids || [];
return ids.length ? ids.map(function (id) { return $$.selectorTarget(id, prefix); }) : null;
};
c3_chart_internal_fn.selectorLegend = function (id) {
return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorLegends = function (ids) {
var $$ = this;
return ids && ids.length ? ids.map(function (id) { return $$.selectorLegend(id); }) : null;
};

100
src/class.js

@ -1,4 +1,4 @@
var CLASS = c3_chart_internal_fn.CLASS = {
export default {
target: 'c3-target',
chart: 'c3-chart',
chartLine: 'c3-chart-line',
@ -76,101 +76,3 @@ var CLASS = c3_chart_internal_fn.CLASS = {
SELECTED: '_selected_',
INCLUDED: '_included_'
};
c3_chart_internal_fn.generateClass = function (prefix, targetId) {
return " " + prefix + " " + prefix + this.getTargetSelectorSuffix(targetId);
};
c3_chart_internal_fn.classText = function (d) {
return this.generateClass(CLASS.text, d.index);
};
c3_chart_internal_fn.classTexts = function (d) {
return this.generateClass(CLASS.texts, d.id);
};
c3_chart_internal_fn.classShape = function (d) {
return this.generateClass(CLASS.shape, d.index);
};
c3_chart_internal_fn.classShapes = function (d) {
return this.generateClass(CLASS.shapes, d.id);
};
c3_chart_internal_fn.classLine = function (d) {
return this.classShape(d) + this.generateClass(CLASS.line, d.id);
};
c3_chart_internal_fn.classLines = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
};
c3_chart_internal_fn.classCircle = function (d) {
return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
};
c3_chart_internal_fn.classCircles = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
};
c3_chart_internal_fn.classBar = function (d) {
return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
};
c3_chart_internal_fn.classBars = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
};
c3_chart_internal_fn.classArc = function (d) {
return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
};
c3_chart_internal_fn.classArcs = function (d) {
return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
};
c3_chart_internal_fn.classArea = function (d) {
return this.classShape(d) + this.generateClass(CLASS.area, d.id);
};
c3_chart_internal_fn.classAreas = function (d) {
return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
};
c3_chart_internal_fn.classRegion = function (d, i) {
return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
};
c3_chart_internal_fn.classEvent = function (d) {
return this.generateClass(CLASS.eventRect, d.index);
};
c3_chart_internal_fn.classTarget = function (id) {
var $$ = this;
var additionalClassSuffix = $$.config.data_classes[id], additionalClass = '';
if (additionalClassSuffix) {
additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
}
return $$.generateClass(CLASS.target, id) + additionalClass;
};
c3_chart_internal_fn.classFocus = function (d) {
return this.classFocused(d) + this.classDefocused(d);
};
c3_chart_internal_fn.classFocused = function (d) {
return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
};
c3_chart_internal_fn.classDefocused = function (d) {
return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
};
c3_chart_internal_fn.classChartText = function (d) {
return CLASS.chartText + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartLine = function (d) {
return CLASS.chartLine + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartBar = function (d) {
return CLASS.chartBar + this.classTarget(d.id);
};
c3_chart_internal_fn.classChartArc = function (d) {
return CLASS.chartArc + this.classTarget(d.data.id);
};
c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
return targetId || targetId === 0 ? ('-' + targetId).replace(/[\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\]/g, '-') : '';
};
c3_chart_internal_fn.selectorTarget = function (id, prefix) {
return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorTargets = function (ids, prefix) {
var $$ = this;
ids = ids || [];
return ids.length ? ids.map(function (id) { return $$.selectorTarget(id, prefix); }) : null;
};
c3_chart_internal_fn.selectorLegend = function (id) {
return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
};
c3_chart_internal_fn.selectorLegends = function (ids) {
var $$ = this;
return ids && ids.length ? ids.map(function (id) { return $$.selectorLegend(id); }) : null;
};

2
src/clip.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.getClipPath = function (id) {
var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0;
return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")";

3
src/color.js

@ -1,3 +1,6 @@
import { c3_chart_internal_fn } from './core';
import { notEmpty } from './util';
c3_chart_internal_fn.generateColor = function () {
var $$ = this, config = $$.config, d3 = $$.d3,
colors = config.data_colors,

14
src/config.js

@ -1,6 +1,10 @@
import { c3_chart_internal_fn } from './core';
import { isDefined } from './util';
c3_chart_internal_fn.getDefaultConfig = function () {
var config = {
bindto: '#chart',
svg_classname: undefined,
size_width: undefined,
size_height: undefined,
padding_left: undefined,
@ -17,6 +21,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
zoom_onzoomend: function () {},
zoom_x_min: undefined,
zoom_x_max: undefined,
interaction_brighten: true,
interaction_enabled: true,
onmouseover: function () {},
onmouseout: function () {},
@ -55,6 +60,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
data_onselected: function () {},
data_onunselected: function () {},
data_url: undefined,
data_headers: undefined,
data_json: undefined,
data_rows: undefined,
data_columns: undefined,
@ -119,6 +125,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
axis_y_tick_format: undefined,
axis_y_tick_outer: true,
axis_y_tick_values: null,
axis_y_tick_rotate: 0,
axis_y_tick_count: undefined,
axis_y_tick_time_value: undefined,
axis_y_tick_time_interval: undefined,
@ -165,17 +172,22 @@ c3_chart_internal_fn.getDefaultConfig = function () {
bar_zerobased: true,
// area
area_zerobased: true,
area_above: false,
// pie
pie_label_show: true,
pie_label_format: undefined,
pie_label_threshold: 0.05,
pie_label_ratio: undefined,
pie_expand: {},
pie_expand_duration: 50,
// gauge
gauge_fullCircle: false,
gauge_label_show: true,
gauge_label_format: undefined,
gauge_min: 0,
gauge_max: 100,
gauge_startingAngle: -1 * Math.PI/2,
gauge_label_extents: undefined,
gauge_units: undefined,
gauge_width: undefined,
gauge_arcs_minWidth: 5,
@ -185,6 +197,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
donut_label_show: true,
donut_label_format: undefined,
donut_label_threshold: 0.05,
donut_label_ratio: undefined,
donut_width: undefined,
donut_title: "",
donut_expand: {},
@ -196,6 +209,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
// tooltip - show when mouseover on each data
tooltip_show: true,
tooltip_grouped: true,
tooltip_order: undefined,
tooltip_format_title: undefined,
tooltip_format_name: undefined,
tooltip_format_value: undefined,

46
src/core.js

@ -1,14 +1,18 @@
var c3 = { version: "0.4.11-rc4" };
import Axis from './axis';
import CLASS from './class';
import { isValue, isFunction, isString, isUndefined, isDefined, ceil10, asHalfPixel, diffDomain, isEmpty, notEmpty, getOption, hasValue, sanitise, getPathBox } from './util';
var c3_chart_fn,
c3_chart_internal_fn,
c3_chart_internal_axis_fn;
export var c3 = { version: "0.4.13" };
function API(owner) {
export var c3_chart_fn;
export var c3_chart_internal_fn;
export var c3_chart_internal_axis_fn;
export function API(owner) {
this.owner = owner;
}
function inherit(base, derived) {
export function inherit(base, derived) {
if (Object.create) {
derived.prototype = Object.create(base.prototype);
@ -81,7 +85,7 @@ c3_chart_internal_fn.init = function () {
$$.initParams();
if (config.data_url) {
$$.convertUrlToData(config.data_url, config.data_mimeType, config.data_keys, $$.initWithData);
$$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
}
else if (config.data_json) {
$$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
@ -253,6 +257,10 @@ c3_chart_internal_fn.initWithData = function (data) {
.on('mouseenter', function () { return config.onmouseover.call($$); })
.on('mouseleave', function () { return config.onmouseout.call($$); });
if ($$.config.svg_classname) {
$$.svg.attr('class', $$.config.svg_classname);
}
// Define defs
defs = $$.svg.append("defs");
$$.clipChart = $$.appendClip(defs, $$.clipId);
@ -416,7 +424,7 @@ c3_chart_internal_fn.updateSizes = function () {
// for arc
$$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
$$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
if ($$.hasType('gauge')) {
if ($$.hasType('gauge') && !config.gauge_fullCircle) {
$$.arcHeight += $$.height - $$.getGaugeLabelHeight();
}
if ($$.updateRadius) { $$.updateRadius(); }
@ -784,7 +792,8 @@ c3_chart_internal_fn.initialOpacityForCircle = function (d) {
return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
};
c3_chart_internal_fn.opacityForCircle = function (d) {
var opacity = this.config.point_show ? 1 : 0;
var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show;
var opacity = isPointShouldBeShown ? 1 : 0;
return isValue(d.value) ? (this.isScatterType(d) ? 0.5 : opacity) : 0;
};
c3_chart_internal_fn.opacityForText = function () {
@ -1033,6 +1042,8 @@ c3_chart_internal_fn.parseDate = function (date) {
parsedDate = date;
} else if (typeof date === 'string') {
parsedDate = $$.dataTimeFormat($$.config.data_xFormat).parse(date);
} else if (typeof date === 'object') {
parsedDate = new Date(+date);
} else if (typeof date === 'number' && !isNaN(date)) {
parsedDate = new Date(+date);
}
@ -1056,3 +1067,20 @@ c3_chart_internal_fn.isTabVisible = function () {
return document[hidden] ? false : true;
};
c3_chart_internal_fn.isValue = isValue;
c3_chart_internal_fn.isFunction = isFunction;
c3_chart_internal_fn.isString = isString;
c3_chart_internal_fn.isUndefined = isUndefined;
c3_chart_internal_fn.isDefined = isDefined;
c3_chart_internal_fn.ceil10 = ceil10;
c3_chart_internal_fn.asHalfPixel = asHalfPixel;
c3_chart_internal_fn.diffDomain = diffDomain;
c3_chart_internal_fn.isEmpty = isEmpty;
c3_chart_internal_fn.notEmpty = notEmpty;
c3_chart_internal_fn.notEmpty = notEmpty;
c3_chart_internal_fn.getOption = getOption;
c3_chart_internal_fn.hasValue = hasValue;
c3_chart_internal_fn.sanitise = sanitise;
c3_chart_internal_fn.getPathBox = getPathBox;
c3_chart_internal_fn.CLASS = CLASS;

55
src/data.convert.js

@ -1,16 +1,26 @@
c3_chart_internal_fn.convertUrlToData = function (url, mimeType, keys, done) {
import { c3_chart_internal_fn } from './core';
import { isValue, isUndefined, isDefined, notEmpty } from './util';
c3_chart_internal_fn.convertUrlToData = function (url, mimeType, headers, keys, done) {
var $$ = this, type = mimeType ? mimeType : 'csv';
$$.d3.xhr(url, function (error, data) {
var req = $$.d3.xhr(url);
if (headers) {
Object.keys(headers).forEach(function (header) {
req.header(header, headers[header]);
});
}
req.get(function (error, data) {
var d;
var dataResponse = data.response || data.responseText; // Fixes IE9 XHR issue; see #1345
if (!data) {
throw new Error(error.responseURL + ' ' + error.status + ' (' + error.statusText + ')');
}
if (type === 'json') {
d = $$.convertJsonToData(JSON.parse(data.response), keys);
d = $$.convertJsonToData(JSON.parse(dataResponse), keys);
} else if (type === 'tsv') {
d = $$.convertTsvToData(data.response);
d = $$.convertTsvToData(dataResponse);
} else {
d = $$.convertCsvToData(data.response);
d = $$.convertCsvToData(dataResponse);
}
done.call($$, d);
});
@ -48,7 +58,10 @@ c3_chart_internal_fn.convertJsonToData = function (json, keys) {
var new_row = [];
targetKeys.forEach(function (key) {
// convert undefined to null because undefined data will be removed in convertDataToTargets()
var v = isUndefined(o[key]) ? null : o[key];
var v = $$.findValueInJson(o, key);
if (isUndefined(v)) {
v = null;
}
new_row.push(v);
});
new_rows.push(new_row);
@ -62,6 +75,20 @@ c3_chart_internal_fn.convertJsonToData = function (json, keys) {
}
return data;
};
c3_chart_internal_fn.findValueInJson = function (object, path) {
path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
path = path.replace(/^\./, ''); // strip a leading dot
var pathArray = path.split('.');
for (var i = 0; i < pathArray.length; ++i) {
var k = pathArray[i];
if (k in object) {
object = object[k];
} else {
return;
}
}
return object;
};
c3_chart_internal_fn.convertRowsToData = function (rows) {
var keys = rows[0], new_row = {}, new_rows = [], i, j;
for (i = 1; i < rows.length; i++) {
@ -140,13 +167,21 @@ c3_chart_internal_fn.convertDataToTargets = function (data, appendXs) {
id: convertedId,
id_org: id,
values: data.map(function (d, i) {
var xKey = $$.getXKey(id), rawX = d[xKey], x = $$.generateTargetX(rawX, id, i),
value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null;
var xKey = $$.getXKey(id), rawX = d[xKey],
value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null, x;
// use x as categories if custom x and categorized
if ($$.isCustomX() && $$.isCategorized() && index === 0 && rawX) {
if (i === 0) { config.axis_x_categories = []; }
if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {
if (index === 0 && i === 0) {
config.axis_x_categories = [];
}
x = config.axis_x_categories.indexOf(rawX);
if (x === -1) {
x = config.axis_x_categories.length;
config.axis_x_categories.push(rawX);
}
} else {
x = $$.generateTargetX(rawX, id, i);
}
// mark as x = undefined if value is undefined and filter to remove after mapped
if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
x = undefined;

26
src/data.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue, isFunction, isArray, notEmpty, hasValue } from './util';
c3_chart_internal_fn.isX = function (key) {
var $$ = this, config = $$.config;
return (config.data_x && key === config.data_x) || (notEmpty(config.data_xs) && hasValue(config.data_xs, key));
@ -175,15 +179,23 @@ c3_chart_internal_fn.mapTargetsToUniqueXs = function (targets) {
return xs.sort(function (a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; });
};
c3_chart_internal_fn.addHiddenTargetIds = function (targetIds) {
this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds);
this.visibleTargetCount -= targetIds.length;
targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds);
for (var i = 0; i < targetIds.length; i++) {
if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {
this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);
}
}
};
c3_chart_internal_fn.removeHiddenTargetIds = function (targetIds) {
this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
this.visibleTargetCount += targetIds.length;
};
c3_chart_internal_fn.addHiddenLegendIds = function (targetIds) {
this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds);
targetIds = (targetIds instanceof Array) ? targetIds : new Array(targetIds);
for (var i = 0; i < targetIds.length; i++) {
if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {
this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);
}
}
};
c3_chart_internal_fn.removeHiddenLegendIds = function (targetIds) {
this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) { return targetIds.indexOf(id) < 0; });
@ -235,7 +247,11 @@ c3_chart_internal_fn.orderTargets = function (targets) {
});
} else if (isFunction(config.data_order)) {
targets.sort(config.data_order);
} // TODO: accept name array for order
} else if (isArray(config.data_order)) {
targets.sort(function (t1, t2) {
return config.data_order.indexOf(t1.id) - config.data_order.indexOf(t2.id);
});
}
return targets;
};
c3_chart_internal_fn.filterByX = function (targets, x) {

5
src/data.load.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.load = function (targets, args) {
var $$ = this;
if (targets) {
@ -39,7 +42,7 @@ c3_chart_internal_fn.loadFromArgs = function (args) {
$$.load($$.convertDataToTargets(args.data), args);
}
else if (args.url) {
$$.convertUrlToData(args.url, args.mimeType, args.keys, function (data) {
$$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
$$.load($$.convertDataToTargets(data), args);
});
}

3
src/domain.js

@ -1,3 +1,6 @@
import { c3_chart_internal_fn } from './core';
import { isValue, isDefined, diffDomain, notEmpty } from './util';
c3_chart_internal_fn.getYDomainMin = function (targets) {
var $$ = this, config = $$.config,
ids = $$.mapToIds(targets), ys = $$.getValuesAsIdKeyed(targets),

4
src/drag.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { getPathBox } from './util';
c3_chart_internal_fn.drag = function (mouse) {
var $$ = this, config = $$.config, main = $$.main, d3 = $$.d3;
var sx, sy, mx, my, minX, maxX, minY, maxY;

3
src/format.js

@ -1,3 +1,6 @@
import { c3_chart_internal_fn } from './core';
import { isValue } from './util';
c3_chart_internal_fn.getYFormat = function (forArc) {
var $$ = this,
formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,

4
src/grid.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue } from './util';
c3_chart_internal_fn.initGrid = function () {
var $$ = this, config = $$.config, d3 = $$.d3;
$$.grid = $$.main.append('g')

4
src/head.js

@ -1,4 +0,0 @@
(function (window) {
'use strict';
/*global define, module, exports, require */

58
src/index.js

@ -0,0 +1,58 @@
import { c3 } from './core';
import './polyfill';
import './api.axis';
import './api.category';
import './api.chart';
import './api.color';
import './api.data';
import './api.flow';
import './api.focus';
import './api.grid';
import './api.group';
import './api.legend';
import './api.load';
import './api.region';
import './api.selection';
import './api.show';
import './api.tooltip';
import './api.transform';
import './api.x';
import './api.zoom';
import './arc';
import './axis';
import './c3.axis';
import './cache';
import './category';
import './class';
import './class-utils';
import './clip';
import './color';
import './config';
import './data.convert';
import './data';
import './data.load';
import './domain';
import './drag';
import './format';
import './grid';
import './interaction';
import './legend';
import './region';
import './scale';
import './selection';
import './shape.bar';
import './shape';
import './shape.line';
import './size';
import './subchart';
import './text';
import './title';
import './tooltip';
import './type';
import './ua';
import './util';
import './zoom';
export default c3;

3
src/interaction.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.initEventRect = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")

4
src/legend.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isDefined, isEmpty, getOption } from './util';
c3_chart_internal_fn.initLegend = function () {
var $$ = this;
$$.legendItemTextBox = {};

849
src/polyfill.js

@ -1,3 +1,5 @@
/* jshint ignore:start */
// PhantomJS doesn't have support for Function.prototype.bind, which has caused confusion. Use
// this polyfill to avoid the confusion.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill
@ -23,3 +25,850 @@ if (!Function.prototype.bind) {
return fBound;
};
}
// SVGPathSeg API polyfill
// https://github.com/progers/pathseg
//
// This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
// SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
// changes which were implemented in Firefox 43 and Chrome 46.
(function() { "use strict";
if (!("SVGPathSeg" in window)) {
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
window.SVGPathSeg = function(type, typeAsLetter, owningPathSegList) {
this.pathSegType = type;
this.pathSegTypeAsLetter = typeAsLetter;
this._owningPathSegList = owningPathSegList;
}
window.SVGPathSeg.prototype.classname = "SVGPathSeg";
window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
window.SVGPathSeg.PATHSEG_ARC_REL = 11;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
// Notify owning PathSegList on any changes so they can be synchronized back to the path element.
window.SVGPathSeg.prototype._segmentChanged = function() {
if (this._owningPathSegList)
this._owningPathSegList.segmentChanged(this);
}
window.SVGPathSegClosePath = function(owningPathSegList) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
}
window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegClosePath.prototype.toString = function() { return "[object SVGPathSegClosePath]"; }
window.SVGPathSegClosePath.prototype._asPathString = function() { return this.pathSegTypeAsLetter; }
window.SVGPathSegClosePath.prototype.clone = function() { return new window.SVGPathSegClosePath(undefined); }
window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegMovetoAbs.prototype.toString = function() { return "[object SVGPathSegMovetoAbs]"; }
window.SVGPathSegMovetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegMovetoAbs.prototype.clone = function() { return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegMovetoRel.prototype.toString = function() { return "[object SVGPathSegMovetoRel]"; }
window.SVGPathSegMovetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegMovetoRel.prototype.clone = function() { return new window.SVGPathSegMovetoRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoAbs.prototype.toString = function() { return "[object SVGPathSegLinetoAbs]"; }
window.SVGPathSegLinetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegLinetoAbs.prototype.clone = function() { return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoRel.prototype.toString = function() { return "[object SVGPathSegLinetoRel]"; }
window.SVGPathSegLinetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegLinetoRel.prototype.clone = function() { return new window.SVGPathSegLinetoRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicAbs = function(owningPathSegList, x, y, x1, y1, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicAbs]"; }
window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicRel = function(owningPathSegList, x, y, x1, y1, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicRel]"; }
window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticAbs = function(owningPathSegList, x, y, x1, y1) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticAbs]"; }
window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticRel = function(owningPathSegList, x, y, x1, y1) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticRel]"; }
window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegArcAbs = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
this._x = x;
this._y = y;
this._r1 = r1;
this._r2 = r2;
this._angle = angle;
this._largeArcFlag = largeArcFlag;
this._sweepFlag = sweepFlag;
}
window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegArcAbs.prototype.toString = function() { return "[object SVGPathSegArcAbs]"; }
window.SVGPathSegArcAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
window.SVGPathSegArcAbs.prototype.clone = function() { return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegArcRel = function(owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
this._x = x;
this._y = y;
this._r1 = r1;
this._r2 = r2;
this._angle = angle;
this._largeArcFlag = largeArcFlag;
this._sweepFlag = sweepFlag;
}
window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegArcRel.prototype.toString = function() { return "[object SVGPathSegArcRel]"; }
window.SVGPathSegArcRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y; }
window.SVGPathSegArcRel.prototype.clone = function() { return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
this._x = x;
}
window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalAbs]"; }
window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x); }
Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
this._x = x;
}
window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoHorizontalRel.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalRel]"; }
window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
window.SVGPathSegLinetoHorizontalRel.prototype.clone = function() { return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x); }
Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
this._y = y;
}
window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoVerticalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalAbs]"; }
window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
window.SVGPathSegLinetoVerticalAbs.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y); }
Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
this._y = y;
}
window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegLinetoVerticalRel.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalRel]"; }
window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
window.SVGPathSegLinetoVerticalRel.prototype.clone = function() { return new window.SVGPathSegLinetoVerticalRel(undefined, this._y); }
Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicSmoothAbs = function(owningPathSegList, x, y, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothAbs]"; }
window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoCubicSmoothRel = function(owningPathSegList, x, y, x2, y2) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothRel]"; }
window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothAbs = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; }
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothRel = function(owningPathSegList, x, y) {
window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
this._x = x;
this._y = y;
}
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; }
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
// Add createSVGPathSeg* functions to window.SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
window.SVGPathElement.prototype.createSVGPathSegClosePath = function() { return new window.SVGPathSegClosePath(undefined); }
window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { return new window.SVGPathSegMovetoAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { return new window.SVGPathSegMovetoRel(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { return new window.SVGPathSegLinetoAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { return new window.SVGPathSegLinetoRel(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(x, y, x1, y1, x2, y2) { return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(x, y, x1, y1) { return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); }
window.SVGPathElement.prototype.createSVGPathSegArcAbs = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
window.SVGPathElement.prototype.createSVGPathSegArcRel = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(x) { return new window.SVGPathSegLinetoHorizontalAbs(undefined, x); }
window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(x) { return new window.SVGPathSegLinetoHorizontalRel(undefined, x); }
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(y) { return new window.SVGPathSegLinetoVerticalAbs(undefined, y); }
window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(y) { return new window.SVGPathSegLinetoVerticalRel(undefined, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(x, y, x2, y2) { return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); }
window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(x, y) { return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }
if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
// Add getPathSegAtLength to SVGPathElement.
// Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
// This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
window.SVGPathElement.prototype.getPathSegAtLength = function(distance) {
if (distance === undefined || !isFinite(distance))
throw "Invalid arguments.";
var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
measurementElement.setAttribute("d", this.getAttribute("d"));
var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
// If the path is empty, return 0.
if (lastPathSegment <= 0)
return 0;
do {
measurementElement.pathSegList.removeItem(lastPathSegment);
if (distance > measurementElement.getTotalLength())
break;
lastPathSegment--;
} while (lastPathSegment > 0);
return lastPathSegment;
}
}
}
if (!("SVGPathSegList" in window)) {
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
window.SVGPathSegList = function(pathElement) {
this._pathElement = pathElement;
this._list = this._parsePath(this._pathElement.getAttribute("d"));
// Use a MutationObserver to catch changes to the path's "d" attribute.
this._mutationObserverConfig = { "attributes": true, "attributeFilter": ["d"] };
this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
}
window.SVGPathSegList.prototype.classname = "SVGPathSegList";
Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
get: function() {
this._checkPathSynchronizedToList();
return this._list.length;
},
enumerable: true
});
// Add the pathSegList accessors to window.SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
get: function() {
if (!this._pathSegList)
this._pathSegList = new window.SVGPathSegList(this);
return this._pathSegList;
},
enumerable: true
});
// FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
// Process any pending mutations to the path element and update the list as needed.
// This should be the first call of all public functions and is needed because
// MutationObservers are not synchronous so we can have pending asynchronous mutations.
window.SVGPathSegList.prototype._checkPathSynchronizedToList = function() {
this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
}
window.SVGPathSegList.prototype._updateListFromPathMutations = function(mutationRecords) {
if (!this._pathElement)
return;
var hasPathMutations = false;
mutationRecords.forEach(function(record) {
if (record.attributeName == "d")
hasPathMutations = true;
});
if (hasPathMutations)
this._list = this._parsePath(this._pathElement.getAttribute("d"));
}
// Serialize the list and update the path's 'd' attribute.
window.SVGPathSegList.prototype._writeListToPath = function() {
this._pathElementMutationObserver.disconnect();
this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
}
// When a path segment changes the list needs to be synchronized back to the path element.
window.SVGPathSegList.prototype.segmentChanged = function(pathSeg) {
this._writeListToPath();
}
window.SVGPathSegList.prototype.clear = function() {
this._checkPathSynchronizedToList();
this._list.forEach(function(pathSeg) {
pathSeg._owningPathSegList = null;
});
this._list = [];
this._writeListToPath();
}
window.SVGPathSegList.prototype.initialize = function(newItem) {
this._checkPathSynchronizedToList();
this._list = [newItem];
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype._checkValidIndex = function(index) {
if (isNaN(index) || index < 0 || index >= this.numberOfItems)
throw "INDEX_SIZE_ERR";
}
window.SVGPathSegList.prototype.getItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
return this._list[index];
}
window.SVGPathSegList.prototype.insertItemBefore = function(newItem, index) {
this._checkPathSynchronizedToList();
// Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
if (index > this.numberOfItems)
index = this.numberOfItems;
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._list.splice(index, 0, newItem);
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype.replaceItem = function(newItem, index) {
this._checkPathSynchronizedToList();
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._checkValidIndex(index);
this._list[index] = newItem;
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
window.SVGPathSegList.prototype.removeItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
var item = this._list[index];
this._list.splice(index, 1);
this._writeListToPath();
return item;
}
window.SVGPathSegList.prototype.appendItem = function(newItem) {
this._checkPathSynchronizedToList();
if (newItem._owningPathSegList) {
// SVG2 spec says to make a copy.
newItem = newItem.clone();
}
this._list.push(newItem);
newItem._owningPathSegList = this;
// TODO: Optimize this to just append to the existing attribute.
this._writeListToPath();
return newItem;
}
window.SVGPathSegList._pathSegArrayAsString = function(pathSegArray) {
var string = "";
var first = true;
pathSegArray.forEach(function(pathSeg) {
if (first) {
first = false;
string += pathSeg._asPathString();
} else {
string += " " + pathSeg._asPathString();
}
});
return string;
}
// This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
window.SVGPathSegList.prototype._parsePath = function(string) {
if (!string || string.length == 0)
return [];
var owningPathSegList = this;
var Builder = function() {
this.pathSegList = [];
}
Builder.prototype.appendSegment = function(pathSeg) {
this.pathSegList.push(pathSeg);
}
var Source = function(string) {
this._string = string;
this._currentIndex = 0;
this._endIndex = this._string.length;
this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
this._skipOptionalSpaces();
}
Source.prototype._isCurrentSpace = function() {
var character = this._string[this._currentIndex];
return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
}
Source.prototype._skipOptionalSpaces = function() {
while (this._currentIndex < this._endIndex && this._isCurrentSpace())
this._currentIndex++;
return this._currentIndex < this._endIndex;
}
Source.prototype._skipOptionalSpacesOrDelimiter = function() {
if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",")
return false;
if (this._skipOptionalSpaces()) {
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
this._currentIndex++;
this._skipOptionalSpaces();
}
}
return this._currentIndex < this._endIndex;
}
Source.prototype.hasMoreData = function() {
return this._currentIndex < this._endIndex;
}
Source.prototype.peekSegmentType = function() {
var lookahead = this._string[this._currentIndex];
return this._pathSegTypeFromChar(lookahead);
}
Source.prototype._pathSegTypeFromChar = function(lookahead) {
switch (lookahead) {
case "Z":
case "z":
return window.SVGPathSeg.PATHSEG_CLOSEPATH;
case "M":
return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
case "m":
return window.SVGPathSeg.PATHSEG_MOVETO_REL;
case "L":
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
case "l":
return window.SVGPathSeg.PATHSEG_LINETO_REL;
case "C":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
case "c":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
case "Q":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
case "q":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
case "A":
return window.SVGPathSeg.PATHSEG_ARC_ABS;
case "a":
return window.SVGPathSeg.PATHSEG_ARC_REL;
case "H":
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
case "h":
return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
case "V":
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
case "v":
return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
case "S":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
case "s":
return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
case "T":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
case "t":
return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
default:
return window.SVGPathSeg.PATHSEG_UNKNOWN;
}
}
Source.prototype._nextCommandHelper = function(lookahead, previousCommand) {
// Check for remaining coordinates in the current command.
if ((lookahead == "+" || lookahead == "-" || lookahead == "." || (lookahead >= "0" && lookahead <= "9")) && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS)
return window.SVGPathSeg.PATHSEG_LINETO_ABS;
if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL)
return window.SVGPathSeg.PATHSEG_LINETO_REL;
return previousCommand;
}
return window.SVGPathSeg.PATHSEG_UNKNOWN;
}
Source.prototype.initialCommandIsMoveTo = function() {
// If the path is empty it is still valid, so return true.
if (!this.hasMoreData())
return true;
var command = this.peekSegmentType();
// Path must start with moveTo.
return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
}
// Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
Source.prototype._parseNumber = function() {
var exponent = 0;
var integer = 0;
var frac = 1;
var decimal = 0;
var sign = 1;
var expsign = 1;
var startIndex = this._currentIndex;
this._skipOptionalSpaces();
// Read the sign.
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+")
this._currentIndex++;
else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
this._currentIndex++;
sign = -1;
}
if (this._currentIndex == this._endIndex || ((this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != "."))
// The first character of a number must be one of [0-9+-.].
return undefined;
// Read the integer part, build right-to-left.
var startIntPartIndex = this._currentIndex;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9")
this._currentIndex++; // Advance to first non-digit.
if (this._currentIndex != startIntPartIndex) {
var scanIntPartIndex = this._currentIndex - 1;
var multiplier = 1;
while (scanIntPartIndex >= startIntPartIndex) {
integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
multiplier *= 10;
}
}
// Read the decimals.
if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
this._currentIndex++;
// There must be a least one digit following the .
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
return undefined;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
frac *= 10;
decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
this._currentIndex += 1;
}
}
// Read the exponent part.
if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && (this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m")) {
this._currentIndex++;
// Read the sign of the exponent.
if (this._string.charAt(this._currentIndex) == "+") {
this._currentIndex++;
} else if (this._string.charAt(this._currentIndex) == "-") {
this._currentIndex++;
expsign = -1;
}
// There must be an exponent.
if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9")
return undefined;
while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
exponent *= 10;
exponent += (this._string.charAt(this._currentIndex) - "0");
this._currentIndex++;
}
}
var number = integer + decimal;
number *= sign;
if (exponent)
number *= Math.pow(10, expsign * exponent);
if (startIndex == this._currentIndex)
return undefined;
this._skipOptionalSpacesOrDelimiter();
return number;
}
Source.prototype._parseArcFlag = function() {
if (this._currentIndex >= this._endIndex)
return undefined;
var flag = false;
var flagChar = this._string.charAt(this._currentIndex++);
if (flagChar == "0")
flag = false;
else if (flagChar == "1")
flag = true;
else
return undefined;
this._skipOptionalSpacesOrDelimiter();
return flag;
}
Source.prototype.parseSegment = function() {
var lookahead = this._string[this._currentIndex];
var command = this._pathSegTypeFromChar(lookahead);
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
// Possibly an implicit command. Not allowed if this is the first command.
if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN)
return null;
command = this._nextCommandHelper(lookahead, this._previousCommand);
if (command == window.SVGPathSeg.PATHSEG_UNKNOWN)
return null;
} else {
this._currentIndex++;
}
this._previousCommand = command;
switch (command) {
case window.SVGPathSeg.PATHSEG_MOVETO_REL:
return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_REL:
return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_ABS:
return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
case window.SVGPathSeg.PATHSEG_CLOSEPATH:
this._skipOptionalSpaces();
return new window.SVGPathSegClosePath(owningPathSegList);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case window.SVGPathSeg.PATHSEG_ARC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
case window.SVGPathSeg.PATHSEG_ARC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber()};
return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
default:
throw "Unknown path seg type."
}
}
var builder = new Builder();
var source = new Source(string);
if (!source.initialCommandIsMoveTo())
return [];
while (source.hasMoreData()) {
var pathSeg = source.parseSegment();
if (!pathSeg)
return [];
builder.appendSegment(pathSeg);
}
return builder.pathSegList;
}
}
}());
/* jshint ignore:end */

15
src/region.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue } from './util';
c3_chart_internal_fn.initRegion = function () {
var $$ = this;
$$.region = $$.main.append('g')
@ -13,16 +17,23 @@ c3_chart_internal_fn.updateRegion = function (duration) {
$$.mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region)
.data(config.regions);
$$.mainRegion.enter().append('g')
.attr('class', $$.classRegion.bind($$))
.append('rect')
.style("fill-opacity", 0);
$$.mainRegion
.attr('class', $$.classRegion.bind($$));
$$.mainRegion.exit().transition().duration(duration)
.style("opacity", 0)
.remove();
};
c3_chart_internal_fn.redrawRegion = function (withTransition) {
var $$ = this,
regions = $$.mainRegion.selectAll('rect'),
regions = $$.mainRegion.selectAll('rect').each(function () {
// data is binded to g and it's not transferred to rect (child node) automatically,
// then data of each rect has to be updated manually.
// TODO: there should be more efficient way to solve this?
var parentData = $$.d3.select(this.parentNode).datum();
$$.d3.select(this).datum(parentData);
}),
x = $$.regionX.bind($$),
y = $$.regionY.bind($$),
w = $$.regionWidth.bind($$),

2
src/scale.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.getScale = function (min, max, forTimeseries) {
return (forTimeseries ? this.d3.time.scale() : this.d3.scale.linear()).range([min, max]);
};

7
src/selection.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.selectPoint = function (target, d, i) {
var $$ = this, config = $$.config,
cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
@ -30,14 +33,18 @@ c3_chart_internal_fn.togglePoint = function (selected, target, d, i) {
c3_chart_internal_fn.selectPath = function (target, d) {
var $$ = this;
$$.config.data_onselected.call($$, d, target.node());
if ($$.config.interaction_brighten) {
target.transition().duration(100)
.style("fill", function () { return $$.d3.rgb($$.color(d)).brighter(0.75); });
}
};
c3_chart_internal_fn.unselectPath = function (target, d) {
var $$ = this;
$$.config.data_onunselected.call($$, d, target.node());
if ($$.config.interaction_brighten) {
target.transition().duration(100)
.style("fill", function () { return $$.color(d); });
}
};
c3_chart_internal_fn.togglePath = function (selected, target, d, i) {
selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);

6
src/shape.bar.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue } from './util';
c3_chart_internal_fn.initBar = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
@ -42,7 +46,7 @@ c3_chart_internal_fn.updateBar = function (durationForExit) {
};
c3_chart_internal_fn.redrawBar = function (drawBar, withTransition) {
return [
(withTransition ? this.mainBar.transition() : this.mainBar)
(withTransition ? this.mainBar.transition(Math.random().toString()) : this.mainBar)
.attr('d', drawBar)
.style("fill", this.color)
.style("opacity", 1)

4
src/shape.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isUndefined } from './util';
c3_chart_internal_fn.getShapeIndices = function (typeFilter) {
var $$ = this, config = $$.config,
indices = {}, i = 0, j, k;

16
src/shape.line.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue, isFunction, isUndefined, isDefined } from './util';
c3_chart_internal_fn.initLine = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")
@ -56,7 +60,7 @@ c3_chart_internal_fn.updateLine = function (durationForExit) {
};
c3_chart_internal_fn.redrawLine = function (drawLine, withTransition) {
return [
(withTransition ? this.mainLine.transition() : this.mainLine)
(withTransition ? this.mainLine.transition(Math.random().toString()) : this.mainLine)
.attr("d", drawLine)
.style("stroke", this.color)
.style("opacity", 1)
@ -232,7 +236,7 @@ c3_chart_internal_fn.updateArea = function (durationForExit) {
};
c3_chart_internal_fn.redrawArea = function (drawArea, withTransition) {
return [
(withTransition ? this.mainArea.transition() : this.mainArea)
(withTransition ? this.mainArea.transition(Math.random().toString()) : this.mainArea)
.attr("d", drawArea)
.style("fill", this.color)
.style("opacity", this.orgAreaOpacity)
@ -250,7 +254,7 @@ c3_chart_internal_fn.generateDrawArea = function (areaIndices, isSub) {
return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
};
area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(value0).y1(value1);
area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
if (!config.line_connectNull) {
area = area.defined(function (d) { return d.value !== null; });
}
@ -315,12 +319,12 @@ c3_chart_internal_fn.updateCircle = function () {
c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition) {
var selectedCircles = this.main.selectAll('.' + CLASS.selectedCircle);
return [
(withTransition ? this.mainCircle.transition() : this.mainCircle)
(withTransition ? this.mainCircle.transition(Math.random().toString()) : this.mainCircle)
.style('opacity', this.opacityForCircle.bind(this))
.style("fill", this.color)
.attr("cx", cx)
.attr("cy", cy),
(withTransition ? selectedCircles.transition() : selectedCircles)
(withTransition ? selectedCircles.transition(Math.random().toString()) : selectedCircles)
.attr("cx", cx)
.attr("cy", cy)
];
@ -372,7 +376,7 @@ c3_chart_internal_fn.pointExpandedR = function (d) {
};
c3_chart_internal_fn.pointSelectR = function (d) {
var $$ = this, config = $$.config;
return config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
return isFunction(config.point_select_r) ? config.point_select_r(d) : ((config.point_select_r) ? config.point_select_r : $$.pointR(d) * 4);
};
c3_chart_internal_fn.isWithinCircle = function (that, r) {
var d3 = this.d3,

14
src/size.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue, ceil10 } from './util';
c3_chart_internal_fn.getCurrentWidth = function () {
var $$ = this, config = $$.config;
return config.size_width ? config.size_width : $$.getParentWidth();
@ -5,7 +9,7 @@ c3_chart_internal_fn.getCurrentWidth = function () {
c3_chart_internal_fn.getCurrentHeight = function () {
var $$ = this, config = $$.config,
h = config.size_height ? config.size_height : $$.getParentHeight();
return h > 0 ? h : 320 / ($$.hasType('gauge') ? 2 : 1);
return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
};
c3_chart_internal_fn.getCurrentPaddingTop = function () {
var $$ = this,
@ -95,12 +99,18 @@ c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
var $$ = this, config = $$.config, h = 30;
if (axisId === 'x' && !config.axis_x_show) { return 8; }
if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; }
if (axisId === 'y' && !config.axis_y_show) { return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1; }
if (axisId === 'y' && !config.axis_y_show) {
return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
}
if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
// Calculate x axis height when tick rotated
if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_x_tick_rotate) / 180);
}
// Calculate y axis height when tick rotated
if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_y_tick_rotate) / 180);
}
return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
};

10
src/subchart.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isFunction } from './util';
c3_chart_internal_fn.initBrush = function () {
var $$ = this, d3 = $$.d3;
$$.brush = d3.svg.brush().on("brush", function () { $$.redrawForBrush(); });
@ -98,7 +102,7 @@ c3_chart_internal_fn.updateBarForSubchart = function (durationForExit) {
.remove();
};
c3_chart_internal_fn.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {
(withTransition ? this.contextBar.transition().duration(duration) : this.contextBar)
(withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar)
.attr('d', drawBarOnSub)
.style('opacity', 1);
};
@ -116,7 +120,7 @@ c3_chart_internal_fn.updateLineForSubchart = function (durationForExit) {
.remove();
};
c3_chart_internal_fn.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {
(withTransition ? this.contextLine.transition().duration(duration) : this.contextLine)
(withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine)
.attr("d", drawLineOnSub)
.style('opacity', 1);
};
@ -135,7 +139,7 @@ c3_chart_internal_fn.updateAreaForSubchart = function (durationForExit) {
.remove();
};
c3_chart_internal_fn.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {
(withTransition ? this.contextArea.transition().duration(duration) : this.contextArea)
(withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea)
.attr("d", drawAreaOnSub)
.style("fill", this.color)
.style("opacity", this.orgAreaOpacity);

9
src/tail.js

@ -1,9 +0,0 @@
if (typeof define === 'function' && define.amd) {
define("c3", ["d3"], function () { return c3; });
} else if ('undefined' !== typeof exports && 'undefined' !== typeof module) {
module.exports = c3;
} else {
window.c3 = c3;
}
})(window);

3
src/text.js

@ -1,3 +1,6 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.initText = function () {
var $$ = this;
$$.main.select('.' + CLASS.chart).append("g")

2
src/title.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.initTitle = function () {
var $$ = this;
$$.title = $$.svg.append("text")

100
src/tooltip.js

@ -1,3 +1,7 @@
import CLASS from './class';
import { c3_chart_internal_fn } from './core';
import { isValue, isFunction, isArray, isString, sanitise } from './util';
c3_chart_internal_fn.initTooltip = function () {
var $$ = this, config = $$.config, i;
$$.tooltip = $$.selectChart
@ -24,44 +28,100 @@ c3_chart_internal_fn.initTooltip = function () {
.style("display", "block");
}
};
c3_chart_internal_fn.getTooltipSortFunction = function() {
var $$ = this, config = $$.config;
if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {
// if data are not grouped or if an order is specified
// for the tooltip values we sort them by their values
var order = config.tooltip_order;
if (order === undefined) {
order = config.data_order;
}
var valueOf = function(obj) {
return obj ? obj.value : null;
};
// if data are not grouped, we sort them by their value
if (isString(order) && order.toLowerCase() === 'asc') {
return function(a, b) {
return valueOf(a) - valueOf(b);
};
} else if (isString(order) && order.toLowerCase() === 'desc') {
return function (a, b) {
return valueOf(b) - valueOf(a);
};
} else if (isFunction(order)) {
// if the function is from data_order we need
// to wrap the returned function in order to format
// the sorted value to the expected format
var sortFunction = order;
if (config.tooltip_order === undefined) {
sortFunction = function (a, b) {
return order(a ? {
id: a.id,
values: [ a ]
} : null, b ? {
id: b.id,
values: [ b ]
} : null);
};
}
return sortFunction;
} else if (isArray(order)) {
return function(a, b) {
return order.indexOf(a.id) - order.indexOf(b.id);
};
}
} else {
// if data are grouped, we follow the order of grouped targets
var ids = $$.orderTargets($$.data.targets).map(function(i) {
return i.id;
});
// if it was either asc or desc we need to invert the order
// returned by orderTargets
if ($$.isOrderAsc() || $$.isOrderDesc()) {
ids = ids.reverse();
}
return function(a, b) {
return ids.indexOf(a.id) - ids.indexOf(b.id);
};
}
};
c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config,
titleFormat = config.tooltip_format_title || defaultTitleFormat,
nameFormat = config.tooltip_format_name || function (name) { return name; },
valueFormat = config.tooltip_format_value || defaultValueFormat,
text, i, title, value, name, bgcolor,
orderAsc = $$.isOrderAsc();
text, i, title, value, name, bgcolor;
if (config.data_groups.length === 0) {
d.sort(function(a,b){
return orderAsc ? a.value - b.value : b.value - a.value;
});
} else {
var ids = $$.orderTargets($$.data.targets).map(function (i) {
return i.id;
});
d.sort(function(a, b) {
if (a.value > 0 && b.value > 0) {
return orderAsc ? ids.indexOf(a.id) - ids.indexOf(b.id) : ids.indexOf(b.id) - ids.indexOf(a.id);
} else {
return orderAsc ? a.value - b.value : b.value - a.value;
}
});
var tooltipSortFunction = this.getTooltipSortFunction();
if(tooltipSortFunction) {
d.sort(tooltipSortFunction);
}
for (i = 0; i < d.length; i++) {
if (! (d[i] && (d[i].value || d[i].value === 0))) { continue; }
if (! text) {
title = titleFormat ? titleFormat(d[i].x) : d[i].x;
title = sanitise(titleFormat ? titleFormat(d[i].x) : d[i].x);
text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
if (value !== undefined) {
// Skip elements when their name is set to null
if (d[i].name === null) { continue; }
name = nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index);
name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
text += "<tr class='" + $$.CLASS.tooltipName + "-" + $$.getTargetSelectorSuffix(d[i].id) + "'>";

3
src/type.js

@ -1,3 +1,6 @@
import { c3_chart_internal_fn } from './core';
import { isString } from './util';
c3_chart_internal_fn.setTargetType = function (targetIds, type) {
var $$ = this, config = $$.config;
$$.mapToTargetIds(targetIds).forEach(function (id) {

2
src/ua.js

@ -1,3 +1,5 @@
import { c3_chart_internal_fn } from './core';
c3_chart_internal_fn.isSafari = function () {
var ua = window.navigator.userAgent;
return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;

62
src/util.js

@ -1,46 +1,54 @@
var isValue = c3_chart_internal_fn.isValue = function (v) {
import { c3_chart_internal_fn } from './core';
export var isValue = function (v) {
return v || v === 0;
},
isFunction = c3_chart_internal_fn.isFunction = function (o) {
};
export var isFunction = function (o) {
return typeof o === 'function';
},
isString = c3_chart_internal_fn.isString = function (o) {
};
export var isArray = function (o) {
return Array.isArray(o);
};
export var isString = function (o) {
return typeof o === 'string';
},
isUndefined = c3_chart_internal_fn.isUndefined = function (v) {
return typeof v === 'undefined';
},
isDefined = c3_chart_internal_fn.isDefined = function (v) {
};
export var isUndefined = function (v) {
return typeof v === 'undefined';
};
export var isDefined = function (v) {
return typeof v !== 'undefined';
},
ceil10 = c3_chart_internal_fn.ceil10 = function (v) {
};
export var ceil10 = function (v) {
return Math.ceil(v / 10) * 10;
},
asHalfPixel = c3_chart_internal_fn.asHalfPixel = function (n) {
};
export var asHalfPixel = function (n) {
return Math.ceil(n) + 0.5;
},
diffDomain = c3_chart_internal_fn.diffDomain = function (d) {
};
export var diffDomain = function (d) {
return d[1] - d[0];
},
isEmpty = c3_chart_internal_fn.isEmpty = function (o) {
};
export var isEmpty = function (o) {
return typeof o === 'undefined' || o === null || (isString(o) && o.length === 0) || (typeof o === 'object' && Object.keys(o).length === 0);
},
notEmpty = c3_chart_internal_fn.notEmpty = function (o) {
};
export var notEmpty = function (o) {
return !c3_chart_internal_fn.isEmpty(o);
},
getOption = c3_chart_internal_fn.getOption = function (options, key, defaultValue) {
};
export var getOption = function (options, key, defaultValue) {
return isDefined(options[key]) ? options[key] : defaultValue;
},
hasValue = c3_chart_internal_fn.hasValue = function (dict, value) {
};
export var hasValue = function (dict, value) {
var found = false;
Object.keys(dict).forEach(function (key) {
if (dict[key] === value) { found = true; }
});
return found;
},
getPathBox = c3_chart_internal_fn.getPathBox = function (path) {
};
export var sanitise = function (str) {
return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
};
export var getPathBox = function (path) {
var box = path.getBoundingClientRect(),
items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
minX = items[0].x, minY = Math.min(items[0].y, items[1].y);
return {x: minX, y: minY, width: box.width, height: box.height};
};
};

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save