Browse Source

Merged in upstream changes

pull/1834/head
Brandon Noad 9 years ago
parent
commit
1adf937650
  1. 11
      .travis.yml
  2. 1
      Gruntfile.coffee
  3. 10
      README.md
  4. 997
      c3.js
  5. 11
      c3.min.js
  6. 2
      component.json
  7. 5
      package.json
  8. 53
      spec/api.data-spec.js
  9. 250
      spec/api.region-spec.js
  10. 59
      spec/arc-spec.js
  11. 45
      spec/axis-spec.js
  12. 104
      spec/data-spec.js
  13. 64
      spec/shape.line-spec.js
  14. 50
      spec/svg-helper.js
  15. 2
      src/api.flow.js
  16. 4
      src/api.load.js
  17. 28
      src/arc.js
  18. 23
      src/axis.js
  19. 8
      src/config.js
  20. 6
      src/core.js
  21. 47
      src/data.convert.js
  22. 2
      src/data.load.js
  23. 817
      src/polyfill.js
  24. 11
      src/region.js
  25. 12
      src/selection.js
  26. 4
      src/shape.line.js
  27. 10
      src/size.js
  28. 20
      src/tooltip.js
  29. 3
      src/util.js

11
.travis.yml

@ -5,8 +5,15 @@ before_script:
- gem install sass
script:
- npm run lint
- npm test
- grunt
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

1
Gruntfile.coffee

@ -83,6 +83,7 @@ module.exports = (grunt) ->
c3: 'c3.js'
spec: 'spec/*.js'
options:
reporter: require('jshint-stylish')
jshintrc: '.jshintrc'
karma:

10
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) [![codecov.io](https://codecov.io/github/masayuki0812/c3/coverage.svg?branch=master)](https://codecov.io/github/masayuki0812/c3?branch=master)
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,7 +11,7 @@ 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:
```
@ -23,14 +23,14 @@ $ python -m SimpleHTTPServer 8080
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.

997
c3.js

File diff suppressed because it is too large Load Diff

11
c3.min.js vendored

File diff suppressed because one or more lines are too long

2
component.json

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

5
package.json

@ -1,6 +1,6 @@
{
"name": "c3",
"version": "0.4.11-rc4",
"version": "0.4.11",
"description": "D3-based reusable chart library",
"main": "c3.js",
"scripts": {
@ -29,12 +29,13 @@
"grunt": "^0.4.5",
"grunt-contrib-concat": "~0.5.0",
"grunt-contrib-cssmin": "^0.10.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-uglify": "~0.4.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-karma": "^0.12.1",
"grunt-sass": "^1.0.0",
"jasmine-core": "^2.3.4",
"jshint-stylish": "^2.1.0",
"karma": "^0.13.10",
"karma-coverage": "^0.5.2",
"karma-jasmine": "^0.3.6",

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;
}
};
}
};

250
spec/api.region-spec.js

@ -0,0 +1,250 @@
describe('c3 api region', function () {
'use strict';
var chart, args;
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
});
describe('api.region', function () {
it('should update args', 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',
}
]
};
expect(true).toBeTruthy();
});
it('should update 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 () {
it('should update args', 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',
}
]
};
expect(true).toBeTruthy();
});
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 () {
it('should update args', 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'
},
]
};
expect(true).toBeTruthy();
});
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);
});
});
});

59
spec/arc-spec.js

@ -97,4 +97,63 @@ describe('c3 chart arc', function () {
});
describe('show gauge', function () {
it('should update args to have a 180 degree gauge', function () {
args = {
gauge: {
width: 10,
max: 10,
expand: true
},
data: {
columns: [
['data', 8]
],
type: 'gauge'
}
};
expect(true).toBeTruthy();
});
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/);
});
it('should update args to have a 2 Pi radian gauge that starts at Pi/2', function() {
args = {
gauge: {
width: 10,
max: 10,
expand: true,
fullCircle: true
},
data: {
columns: [
['data', 8]
],
type: 'gauge',
fullCircle: true,
startingAngle: Math.PI/2
}
};
expect(true).toBeTruthy();
});
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/);
});
});
});

45
spec/axis-spec.js

@ -153,7 +153,7 @@ 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);
@ -599,6 +599,49 @@ describe('c3 chart axis', function () {
});
});
describe('axis.y.tick.rotate', function () {
describe('not rotated', function () {
it('should update args successfully', 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
}
}
}
};
expect(true).toBeTruthy();
});
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);
});
});
});
describe('axis.x.tick.fit', function () {
describe('axis.x.tick.fit = true', function () {

104
spec/data-spec.js

@ -23,11 +23,11 @@ describe('c3 chart data', function () {
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);
});
});
@ -62,16 +62,104 @@ describe('c3 chart data', function () {
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);
});
});
it('should update nested JSON args', 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"
}
}
};
expect(true).toBeTruthy();
});
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);
});
});

64
spec/shape.line-spec.js

@ -7,6 +7,8 @@ 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 () {
@ -21,6 +23,16 @@ describe('c3 chart shape line', function () {
}
};
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 () {
@ -37,7 +49,7 @@ describe('c3 chart shape line', function () {
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');
});
});
@ -79,30 +91,43 @@ describe('c3 chart shape line', function () {
}, 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) {
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');
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);
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('spline.interpolation option', function () {
@ -123,6 +148,7 @@ describe('c3 chart shape line', function () {
}
}
};
expect(true).toBeTruthy();
});

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;
}

2
src/api.flow.js

@ -202,7 +202,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()) {

4
src/api.load.js

@ -4,6 +4,10 @@ c3_chart_fn.load = function (args) {
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) {

28
src/arc.js

@ -50,9 +50,9 @@ c3_chart_internal_fn.updateAngle = function (d) {
if ($$.isGaugeType(d.data)) {
gMin = config.gauge_min;
gMax = config.gauge_max;
gTic = (Math.PI) / (gMax - gMin);
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;
@ -87,15 +87,20 @@ c3_chart_internal_fn.getArc = function (d, withoutUpdate, force) {
c3_chart_internal_fn.transformForArcLabel = function (d) {
var $$ = this,
var $$ = this, config = $$.config,
updated = $$.updateAngle(d), c, x, y, h, ratio, translate = "";
if (updated && !$$.hasType('gauge')) {
c = this.svgArc.centroid(updated);
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?
ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
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) + ")";
}
return translate;
@ -103,7 +108,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;
};
@ -278,7 +284,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;
});
@ -388,8 +394,8 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
.attr("d", function () {
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
};
return $$.getArc(d, true, true);
});
@ -397,11 +403,11 @@ 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 : '');
$$.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 : '');
}

23
src/axis.js

@ -76,17 +76,16 @@ Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, a
}
return tickValues;
};
Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition) {
var axisParams = {
withOuterTick: withOuterTick,
withoutTransition: withoutTransition,
},
$$ = this.owner,
d3 = $$.d3,
config = $$.config,
axis = c3_axis(d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
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
},
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 +275,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);

8
src/config.js

@ -18,6 +18,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 () {},
@ -56,6 +57,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,
@ -120,6 +122,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,
@ -166,17 +169,21 @@ 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_units: undefined,
gauge_width: undefined,
gauge_expand: {},
@ -185,6 +192,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: {},

6
src/core.js

@ -1,4 +1,4 @@
var c3 = { version: "0.4.11-rc4" };
var c3 = { version: "0.4.11" };
var c3_chart_fn,
c3_chart_internal_fn,
@ -81,7 +81,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));
@ -419,7 +419,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(); }

47
src/data.convert.js

@ -1,6 +1,12 @@
c3_chart_internal_fn.convertUrlToData = function (url, mimeType, keys, done) {
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;
if (!data) {
throw new Error(error.responseURL + ' ' + error.status + ' (' + error.statusText + ')');
@ -48,7 +54,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 +71,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,12 +163,20 @@ 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 = []; }
config.axis_x_categories.push(rawX);
if ($$.isCustomX() && $$.isCategorized() && index === 0 && !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) {

2
src/data.load.js

@ -39,7 +39,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);
});
}

817
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,818 @@ 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.
//Chrome 48 removes these APIs, so this polyfill is required.
(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;
}
SVGPathSeg.PATHSEG_UNKNOWN = 0;
SVGPathSeg.PATHSEG_CLOSEPATH = 1;
SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
SVGPathSeg.PATHSEG_MOVETO_REL = 3;
SVGPathSeg.PATHSEG_LINETO_ABS = 4;
SVGPathSeg.PATHSEG_LINETO_REL = 5;
SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
SVGPathSeg.PATHSEG_ARC_ABS = 10;
SVGPathSeg.PATHSEG_ARC_REL = 11;
SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
// Notify owning PathSegList on any changes so they can be synchronized back to the path element.
SVGPathSeg.prototype._segmentChanged = function() {
if (this._owningPathSegList)
this._owningPathSegList.segmentChanged(this);
}
window.SVGPathSegClosePath = function(owningPathSegList) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
}
SVGPathSegClosePath.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegClosePath.prototype.toString = function() { return "[object SVGPathSegClosePath]"; }
SVGPathSegClosePath.prototype._asPathString = function() { return this.pathSegTypeAsLetter; }
SVGPathSegClosePath.prototype.clone = function() { return new SVGPathSegClosePath(undefined); }
window.SVGPathSegMovetoAbs = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegMovetoAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegMovetoAbs.prototype.toString = function() { return "[object SVGPathSegMovetoAbs]"; }
SVGPathSegMovetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegMovetoAbs.prototype.clone = function() { return new SVGPathSegMovetoAbs(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegMovetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegMovetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegMovetoRel = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegMovetoRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegMovetoRel.prototype.toString = function() { return "[object SVGPathSegMovetoRel]"; }
SVGPathSegMovetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegMovetoRel.prototype.clone = function() { return new SVGPathSegMovetoRel(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegMovetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegMovetoRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoAbs = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegLinetoAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoAbs.prototype.toString = function() { return "[object SVGPathSegLinetoAbs]"; }
SVGPathSegLinetoAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegLinetoAbs.prototype.clone = function() { return new SVGPathSegLinetoAbs(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegLinetoAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegLinetoAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoRel = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegLinetoRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoRel.prototype.toString = function() { return "[object SVGPathSegLinetoRel]"; }
SVGPathSegLinetoRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegLinetoRel.prototype.clone = function() { return new SVGPathSegLinetoRel(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegLinetoRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, 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;
}
SVGPathSegCurvetoCubicAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoCubicAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicAbs]"; }
SVGPathSegCurvetoCubicAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoCubicAbs.prototype.clone = function() { return new SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, 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;
}
SVGPathSegCurvetoCubicRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoCubicRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicRel]"; }
SVGPathSegCurvetoCubicRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoCubicRel.prototype.clone = function() { return new SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2); }
Object.defineProperty(SVGPathSegCurvetoCubicRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function() { return this._y1; }, set: function(y1) { this._y1 = y1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoQuadraticAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticAbs]"; }
SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoQuadraticAbs.prototype.clone = function() { return new SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
this._x = x;
this._y = y;
this._x1 = x1;
this._y1 = y1;
}
SVGPathSegCurvetoQuadraticRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoQuadraticRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticRel]"; }
SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoQuadraticRel.prototype.clone = function() { return new SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1); }
Object.defineProperty(SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function() { return this._x1; }, set: function(x1) { this._x1 = x1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, 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;
}
SVGPathSegArcAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegArcAbs.prototype.toString = function() { return "[object SVGPathSegArcAbs]"; }
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; }
SVGPathSegArcAbs.prototype.clone = function() { return new SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(SVGPathSegArcAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcAbs.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcAbs.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcAbs.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, 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;
}
SVGPathSegArcRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegArcRel.prototype.toString = function() { return "[object SVGPathSegArcRel]"; }
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; }
SVGPathSegArcRel.prototype.clone = function() { return new SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag); }
Object.defineProperty(SVGPathSegArcRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "r1", { get: function() { return this._r1; }, set: function(r1) { this._r1 = r1; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "r2", { get: function() { return this._r2; }, set: function(r2) { this._r2 = r2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "angle", { get: function() { return this._angle; }, set: function(angle) { this._angle = angle; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "largeArcFlag", { get: function() { return this._largeArcFlag; }, set: function(largeArcFlag) { this._largeArcFlag = largeArcFlag; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegArcRel.prototype, "sweepFlag", { get: function() { return this._sweepFlag; }, set: function(sweepFlag) { this._sweepFlag = sweepFlag; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalAbs = function(owningPathSegList, x) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
this._x = x;
}
SVGPathSegLinetoHorizontalAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoHorizontalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalAbs]"; }
SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
SVGPathSegLinetoHorizontalAbs.prototype.clone = function() { return new SVGPathSegLinetoHorizontalAbs(undefined, this._x); }
Object.defineProperty(SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoHorizontalRel = function(owningPathSegList, x) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
this._x = x;
}
SVGPathSegLinetoHorizontalRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoHorizontalRel.prototype.toString = function() { return "[object SVGPathSegLinetoHorizontalRel]"; }
SVGPathSegLinetoHorizontalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x; }
SVGPathSegLinetoHorizontalRel.prototype.clone = function() { return new SVGPathSegLinetoHorizontalRel(undefined, this._x); }
Object.defineProperty(SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalAbs = function(owningPathSegList, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
this._y = y;
}
SVGPathSegLinetoVerticalAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoVerticalAbs.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalAbs]"; }
SVGPathSegLinetoVerticalAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
SVGPathSegLinetoVerticalAbs.prototype.clone = function() { return new SVGPathSegLinetoVerticalAbs(undefined, this._y); }
Object.defineProperty(SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegLinetoVerticalRel = function(owningPathSegList, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
this._y = y;
}
SVGPathSegLinetoVerticalRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegLinetoVerticalRel.prototype.toString = function() { return "[object SVGPathSegLinetoVerticalRel]"; }
SVGPathSegLinetoVerticalRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._y; }
SVGPathSegLinetoVerticalRel.prototype.clone = function() { return new SVGPathSegLinetoVerticalRel(undefined, this._y); }
Object.defineProperty(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) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothAbs]"; }
SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function() { return new SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(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) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
this._x = x;
this._y = y;
this._x2 = x2;
this._y2 = y2;
}
SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoCubicSmoothRel]"; }
SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y; }
SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function() { return new SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2); }
Object.defineProperty(SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function() { return this._x2; }, set: function(x2) { this._x2 = x2; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function() { return this._y2; }, set: function(y2) { this._y2 = y2; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothAbs = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothAbs]"; }
SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function() { return new SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
window.SVGPathSegCurvetoQuadraticSmoothRel = function(owningPathSegList, x, y) {
SVGPathSeg.call(this, SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
this._x = x;
this._y = y;
}
SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(SVGPathSeg.prototype);
SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function() { return "[object SVGPathSegCurvetoQuadraticSmoothRel]"; }
SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function() { return this.pathSegTypeAsLetter + " " + this._x + " " + this._y; }
SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function() { return new SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y); }
Object.defineProperty(SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function() { return this._x; }, set: function(x) { this._x = x; this._segmentChanged(); }, enumerable: true });
Object.defineProperty(SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function() { return this._y; }, set: function(y) { this._y = y; this._segmentChanged(); }, enumerable: true });
// Add createSVGPathSeg* functions to SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathElement.
SVGPathElement.prototype.createSVGPathSegClosePath = function() { return new SVGPathSegClosePath(undefined); }
SVGPathElement.prototype.createSVGPathSegMovetoAbs = function(x, y) { return new SVGPathSegMovetoAbs(undefined, x, y); }
SVGPathElement.prototype.createSVGPathSegMovetoRel = function(x, y) { return new SVGPathSegMovetoRel(undefined, x, y); }
SVGPathElement.prototype.createSVGPathSegLinetoAbs = function(x, y) { return new SVGPathSegLinetoAbs(undefined, x, y); }
SVGPathElement.prototype.createSVGPathSegLinetoRel = function(x, y) { return new SVGPathSegLinetoRel(undefined, x, y); }
SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function(x, y, x1, y1, x2, y2) { return new SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2); }
SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function(x, y, x1, y1, x2, y2) { return new SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2); }
SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function(x, y, x1, y1) { return new SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1); }
SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function(x, y, x1, y1) { return new SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1); }
SVGPathElement.prototype.createSVGPathSegArcAbs = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
SVGPathElement.prototype.createSVGPathSegArcRel = function(x, y, r1, r2, angle, largeArcFlag, sweepFlag) { return new SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag); }
SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function(x) { return new SVGPathSegLinetoHorizontalAbs(undefined, x); }
SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function(x) { return new SVGPathSegLinetoHorizontalRel(undefined, x); }
SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function(y) { return new SVGPathSegLinetoVerticalAbs(undefined, y); }
SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function(y) { return new SVGPathSegLinetoVerticalRel(undefined, y); }
SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function(x, y, x2, y2) { return new SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2); }
SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function(x, y, x2, y2) { return new SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2); }
SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function(x, y) { return new SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y); }
SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function(x, y) { return new SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y); }
}
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);
}
Object.defineProperty(SVGPathSegList.prototype, "numberOfItems", {
get: function() {
this._checkPathSynchronizedToList();
return this._list.length;
},
enumerable: true
});
// Add the pathSegList accessors to SVGPathElement.
// Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
Object.defineProperty(SVGPathElement.prototype, "pathSegList", {
get: function() {
if (!this._pathSegList)
this._pathSegList = new SVGPathSegList(this);
return this._pathSegList;
},
enumerable: true
});
// FIXME: The following are not implemented and simply return SVGPathElement.pathSegList.
Object.defineProperty(SVGPathElement.prototype, "normalizedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(SVGPathElement.prototype, "animatedPathSegList", { get: function() { return this.pathSegList; }, enumerable: true });
Object.defineProperty(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.
SVGPathSegList.prototype._checkPathSynchronizedToList = function() {
this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
}
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.
SVGPathSegList.prototype._writeListToPath = function() {
this._pathElementMutationObserver.disconnect();
this._pathElement.setAttribute("d", 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.
SVGPathSegList.prototype.segmentChanged = function(pathSeg) {
this._writeListToPath();
}
SVGPathSegList.prototype.clear = function() {
this._checkPathSynchronizedToList();
this._list.forEach(function(pathSeg) {
pathSeg._owningPathSegList = null;
});
this._list = [];
this._writeListToPath();
}
SVGPathSegList.prototype.initialize = function(newItem) {
this._checkPathSynchronizedToList();
this._list = [newItem];
newItem._owningPathSegList = this;
this._writeListToPath();
return newItem;
}
SVGPathSegList.prototype._checkValidIndex = function(index) {
if (isNaN(index) || index < 0 || index >= this.numberOfItems)
throw "INDEX_SIZE_ERR";
}
SVGPathSegList.prototype.getItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
return this._list[index];
}
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;
}
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;
}
SVGPathSegList.prototype.removeItem = function(index) {
this._checkPathSynchronizedToList();
this._checkValidIndex(index);
var item = this._list[index];
this._list.splice(index, 1);
this._writeListToPath();
return item;
}
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;
}
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.
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 = 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 SVGPathSeg.PATHSEG_CLOSEPATH;
case "M":
return SVGPathSeg.PATHSEG_MOVETO_ABS;
case "m":
return SVGPathSeg.PATHSEG_MOVETO_REL;
case "L":
return SVGPathSeg.PATHSEG_LINETO_ABS;
case "l":
return SVGPathSeg.PATHSEG_LINETO_REL;
case "C":
return SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
case "c":
return SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
case "Q":
return SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
case "q":
return SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
case "A":
return SVGPathSeg.PATHSEG_ARC_ABS;
case "a":
return SVGPathSeg.PATHSEG_ARC_REL;
case "H":
return SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
case "h":
return SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
case "V":
return SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
case "v":
return SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
case "S":
return SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
case "s":
return SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
case "T":
return SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
case "t":
return SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
default:
return 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 != SVGPathSeg.PATHSEG_CLOSEPATH) {
if (previousCommand == SVGPathSeg.PATHSEG_MOVETO_ABS)
return SVGPathSeg.PATHSEG_LINETO_ABS;
if (previousCommand == SVGPathSeg.PATHSEG_MOVETO_REL)
return SVGPathSeg.PATHSEG_LINETO_REL;
return previousCommand;
}
return 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 == SVGPathSeg.PATHSEG_MOVETO_ABS || command == 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")
decimal += (this._string.charAt(this._currentIndex++) - "0") * (frac *= 0.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 == SVGPathSeg.PATHSEG_UNKNOWN) {
// Possibly an implicit command. Not allowed if this is the first command.
if (this._previousCommand == SVGPathSeg.PATHSEG_UNKNOWN)
return null;
command = this._nextCommandHelper(lookahead, this._previousCommand);
if (command == SVGPathSeg.PATHSEG_UNKNOWN)
return null;
} else {
this._currentIndex++;
}
this._previousCommand = command;
switch (command) {
case SVGPathSeg.PATHSEG_MOVETO_REL:
return new SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case SVGPathSeg.PATHSEG_MOVETO_ABS:
return new SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_REL:
return new SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_ABS:
return new SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
return new SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
return new SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
return new SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
return new SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
case SVGPathSeg.PATHSEG_CLOSEPATH:
this._skipOptionalSpaces();
return new SVGPathSegClosePath(owningPathSegList);
case 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 SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case 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 SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
var points = {x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
var points = {x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber()};
return new SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
return new SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
return new SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
case 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 SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
case 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 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 */

11
src/region.js

@ -13,16 +13,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($$),

12
src/selection.js

@ -30,14 +30,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());
target.transition().duration(100)
.style("fill", function () { return $$.d3.rgb($$.color(d)).brighter(0.75); });
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());
target.transition().duration(100)
.style("fill", function () { return $$.color(d); });
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);

4
src/shape.line.js

@ -250,7 +250,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; });
}
@ -372,7 +372,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,

10
src/size.js

@ -5,7 +5,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 +95,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);
};

20
src/tooltip.js

@ -35,19 +35,21 @@ c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaul
orderAsc = $$.isOrderAsc();
if (config.data_groups.length === 0) {
d.sort(function(a,b){
return orderAsc ? a.value - b.value : b.value - a.value;
d.sort(function(a, b){
var v1 = a ? a.value : null, v2 = b ? b.value : null;
return orderAsc ? v1 - v2 : v2 - v1;
});
} 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 v1 = a ? a.value : null, v2 = b ? b.value : null;
if (v1 > 0 && v2 > 0) {
v1 = a ? ids.indexOf(a.id) : null;
v2 = b ? ids.indexOf(b.id) : null;
}
return orderAsc ? v1 - v2 : v2 - v1;
});
}
@ -55,15 +57,15 @@ c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaul
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/util.js

@ -38,6 +38,9 @@ var isValue = c3_chart_internal_fn.isValue = function (v) {
});
return found;
},
sanitise = c3_chart_internal_fn.sanitise = function (str) {
return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
},
getPathBox = c3_chart_internal_fn.getPathBox = function (path) {
var box = path.getBoundingClientRect(),
items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],

Loading…
Cancel
Save