Commit bc0b6db9 authored by DungSaga's avatar DungSaga

Merge pull request #1 from masayuki0812/master

Update from base repo
parents f05f765c 90387157
...@@ -29,3 +29,5 @@ Please fork this fiddle: ...@@ -29,3 +29,5 @@ Please fork this fiddle:
## License ## License
MIT 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,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"c3.css", "c3.css",
"c3.js" "c3.js"
], ],
"version": "0.3.0", "version": "0.4.3",
"homepage": "https://github.com/masayuki0812/c3", "homepage": "https://github.com/masayuki0812/c3",
"authors": [ "authors": [
"Masayuki Tanaka <masayuki0812@mac.com>" "Masayuki Tanaka <masayuki0812@mac.com>"
......
...@@ -209,5 +209,5 @@ ...@@ -209,5 +209,5 @@
.c3-chart-arc .c3-gauge-value { .c3-chart-arc .c3-gauge-value {
fill: #000; fill: #000;
font-size: 28px; /* font-size: 28px !important;*/
} }
.c3 svg{font:10px sans-serif}.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-chart-arcs-title{font-size:1.3em}.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-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.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 .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;font-size:28px} .c3 svg{font:10px sans-serif}.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-chart-arcs-title{font-size:1.3em}.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-background{opacity:.75;fill:#fff;stroke:#d3d3d3;stroke-width:1}.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 .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}
\ No newline at end of file \ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "c3", "name": "c3",
"repo": "masayuki0812/c3", "repo": "masayuki0812/c3",
"description": "A D3-based reusable chart library", "description": "A D3-based reusable chart library",
"version": "0.3.0", "version": "0.4.3",
"keywords": [], "keywords": [],
"dependencies": { "dependencies": {
"mbostock/d3": "v3.4.4" "mbostock/d3": "v3.4.4"
......
...@@ -273,6 +273,9 @@ ...@@ -273,6 +273,9 @@
<a href="./samples/regions.html"> <a href="./samples/regions.html">
Show regions Show regions
</a> </a>
<a href="./samples/regions_timeseries.html">
Show regions with timeseries
</a>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<h3>Legend</h3> <h3>Legend</h3>
......
<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.js"></script>
<script>
var chart = c3.generate({
data: {
x: 'date',
columns: [
['date', '2014-01-01', '2014-01-10', '2014-01-20', '2014-01-30', '2014-02-01'],
['sample', 30, 200, 100, 400, 150, 250]
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y%m%d %H:%M:%S'
}
},
},
regions: [
{start: '2014-01-05', end: '2014-01-10'},
// {start: new Date('2014-01-10'), end: new Date('2014-01-15')},
{start: 1390608000000, end: 1391040000000}
]
});
setTimeout(function () {
chart.load({
columns: [
['date', +new Date('2014-01-01'), +new Date('2014-01-10'), +new Date('2014-03-01')],
['sample', 100, 200, 300]
]
});
chart.regions([
{start: +new Date('2014-01-10'), end: +new Date('2014-01-15')}
]);
}, 1000);
</script>
</body>
</html>
{ {
"name": "c3", "name": "c3",
"version": "0.3.0", "version": "0.4.3",
"description": "D3-based reusable chart library", "description": "D3-based reusable chart library",
"main": "c3.js", "main": "c3.js",
"scripts": { "scripts": {
......
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 api grid', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250]
]
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('ygrid.add and ygrid.remove', function () {
it('should update y grids', function (done) {
var main = chart.internal.main,
expectedGrids = [
{
value: 100,
text: 'Pressure Low'
},
{
value: 200,
text: 'Pressure High'
}
],
grids;
// Call ygrids.add
chart.ygrids.add(expectedGrids);
setTimeout(function () {
grids = main.selectAll('.c3-ygrid-line');
expect(grids.size()).toBe(expectedGrids.length);
grids.each(function (d, i) {
var y = +d3.select(this).select('line').attr('y1'),
text = d3.select(this).select('text').text(),
expectedY = Math.round(chart.internal.y(expectedGrids[i].value)),
expectedText = expectedGrids[i].text;
expect(y).toBe(expectedY);
expect(text).toBe(expectedText);
});
// Call ygrids.remove
chart.ygrids.remove(expectedGrids);
setTimeout(function () {
grids = main.selectAll('.c3-ygrid-line');
expect(grids.size()).toBe(0);
}, 500);
}, 500);
setTimeout(function () {
done();
}, 1200);
});
it("should update x ygrids even if it's zoomed", function (done) {
var main = chart.internal.main,
expectedGrids = [
{
value: 0,
text: 'Pressure Low'
},
{
value: 1,
text: 'Pressure High'
}
],
grids, domain;
chart.zoom([0, 2]);
setTimeout(function () {
// Call xgrids
chart.xgrids(expectedGrids);
setTimeout(function () {
grids = main.selectAll('.c3-xgrid-line');
expect(grids.size()).toBe(expectedGrids.length);
grids.each(function (d, i) {
var x = +d3.select(this).select('line').attr('x1'),
text = d3.select(this).select('text').text(),
expectedX = Math.round(chart.internal.x(expectedGrids[i].value)),
expectedText = expectedGrids[i].text;
expect(x).toBe(expectedX);
expect(text).toBe(expectedText);
});
// check if it was not rescaled
domain = chart.internal.y.domain();
expect(domain[0]).toBeLessThan(0);
expect(domain[1]).toBeGreaterThan(400);
// Call xgrids.remove
chart.xgrids.remove(expectedGrids);
setTimeout(function () {
grids = main.selectAll('.c3-xgrid-line');
expect(grids.size()).toBe(0);
}, 500); // for xgrids.remove()
}, 500); // for xgrids()
}, 500); // for zoom
setTimeout(function () {
done();
}, 1700);
});
});
});
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 chart axis', function () {
'use strict';
var chart, d3, args;
beforeEach(function (done) {
if (typeof chart === 'undefined') {
window.initDom();
}
chart = window.c3.generate(args);
d3 = chart.internal.d3;
chart.internal.d3.select('.jasmine_html-reporter')
.style('position', 'absolute')
.style('right', 0);
window.setTimeout(function () {
done();
}, 50);
});
describe('show pie chart', function () {
args = {
data: {
columns: [
['data1', 30],
['data2', 150],
['data3', 120]
],
type: 'pie'
}
};
it('should have correct classes', function () {
var chartArc = d3.select('.c3-chart-arcs'),
arcs = {
data1: chartArc.select('.c3-chart-arc.c3-target.c3-target-data1')
.select('g.c3-shapes.c3-shapes-data1.c3-arcs.c3-arcs-data1')
.select('path.c3-shape.c3-shape.c3-arc.c3-arc-data1'),
data2: chartArc.select('.c3-chart-arc.c3-target.c3-target-data2')
.select('g.c3-shapes.c3-shapes-data2.c3-arcs.c3-arcs-data2')
.select('path.c3-shape.c3-shape.c3-arc.c3-arc-data2'),
data3: chartArc.select('.c3-chart-arc.c3-target.c3-target-data3')
.select('g.c3-shapes.c3-shapes-data3.c3-arcs.c3-arcs-data3')
.select('path.c3-shape.c3-shape.c3-arc.c3-arc-data3')
};
expect(arcs.data1.size()).toBe(1);
expect(arcs.data2.size()).toBe(1);
expect(arcs.data3.size()).toBe(1);
});
it('should have correct d', function () {
expect(d3.select('.c3-arc-data1').attr('d')).toMatch(/M-124\..+,-171\..+A211\..+,211\..+ 0 0,1 -3\..+,-211\..+L0,0Z/);
expect(d3.select('.c3-arc-data2').attr('d')).toMatch(/M1\..+,-211\..+A211\..+,211\..+ 0 0,1 1\..+,211\..+L0,0Z/);
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 () {
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 () {
expect(d3.select('.c3-arc-black').attr('d')).toMatch(/M-124\..+,-171\..+A211\..+,211\..+ 0 0,1 -3\..+,-211\..+L0,0Z/);
});
});
});
...@@ -10,14 +10,34 @@ function initDom() { ...@@ -10,14 +10,34 @@ function initDom() {
} }
typeof initDom !== 'undefined'; typeof initDom !== 'undefined';
function setEvent(chart, x, y) { function setMouseEvent(chart, name, x, y, element) {
'use strict'; 'use strict';
var paddingLeft = chart.internal.main.node().transform.baseVal.getItem(0).matrix.e, var paddingLeft = chart.internal.main.node().transform.baseVal.getItem(0).matrix.e,
evt = document.createEvent("MouseEvents"); event = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, event.initMouseEvent(name, true, true, window,
0, 0, 0, x + paddingLeft, y + 5, 0, 0, 0, x + paddingLeft, y + 5,
false, false, false, false, 0, null); false, false, false, false, 0, null);
chart.internal.d3.event = evt; chart.internal.d3.event = event;
if (element) { element.dispatchEvent(event); }
} }
typeof setEvent !== 'undefined'; typeof setMouseEvent !== 'undefined';
function initChart(chart, args, done) {
'use strict';
if (typeof chart === 'undefined') {
window.initDom();
}
chart = window.c3.generate(args);
chart.internal.d3.select('.jasmine_html-reporter')
.style('position', 'absolute')
.style('right', 0);
window.setTimeout(function () {
done();
}, 10);
return chart;
}
typeof initChart !== 'undefined';
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 chart class', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2 prefix', 50, 20, 10, 40, 15, 25],
['data3 мужчины', 150, 120, 110, 140, 115, 125]
]
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('internal.getTargetSelectorSuffix', function () {
it('should not replace any characters', function () {
var input = 'data1',
expected = '-' + input,
suffix = chart.internal.getTargetSelectorSuffix(input);
expect(suffix).toBe(expected);
});
it('should replace space to "-"', function () {
var input = 'data1 suffix',
expected = '-data1-suffix',
suffix = chart.internal.getTargetSelectorSuffix(input);
expect(suffix).toBe(expected);
});
it('should replace space to "-" with multibyte characters', function () {
var input = 'data1 suffix 日本語',
expected = '-data1-suffix-日本語',
suffix = chart.internal.getTargetSelectorSuffix(input);
expect(suffix).toBe(expected);
});
it('should replace special charactors to "-"', function () {
var input = 'data1 !@#$%^&*()_=+,.<>"\':;[]/|?~`{}\\',
expected = '-data1--------------------------------',
suffix = chart.internal.getTargetSelectorSuffix(input);
expect(suffix).toBe(expected);
});
});
describe('multibyte characters on chart', function () {
it('should replace space to "-" with multibyte characters', function () {
var selector = '.c3-target-data3-мужчины';
expect(chart.internal.main.select(selector).size()).toBe(1);
});
});
});
...@@ -8,10 +8,7 @@ describe('c3 chart', function () { ...@@ -8,10 +8,7 @@ describe('c3 chart', function () {
var chart, d3; var chart, d3;
beforeEach(function () { var args = {
window.initDom();
chart = window.c3.generate({
data: { data: {
columns: [ columns: [
['data1', 30, 200, 100, 400, 150, 250], ['data1', 30, 200, 100, 400, 150, 250],
...@@ -19,16 +16,34 @@ describe('c3 chart', function () { ...@@ -19,16 +16,34 @@ describe('c3 chart', function () {
['data3', 150, 120, 110, 140, 115, 125] ['data3', 150, 120, 110, 140, 115, 125]
] ]
} }
}); };
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3; d3 = chart.internal.d3;
}); });
describe('init', function () {
it('should be created', function () { it('should be created', function () {
var svg = d3.select('#chart svg'); var svg = d3.select('#chart svg');
expect(svg).not.toBeNull(); expect(svg).not.toBeNull();
}); });
it('should set 3rd party property to Function', 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();
});
});
describe('size', function () {
it('should have same width', function () { it('should have same width', function () {
var svg = d3.select('#chart svg'); var svg = d3.select('#chart svg');
expect(+svg.attr('width')).toBe(640); expect(+svg.attr('width')).toBe(640);
...@@ -39,4 +54,20 @@ describe('c3 chart', function () { ...@@ -39,4 +54,20 @@ describe('c3 chart', function () {
expect(+svg.attr('height')).toBe(480); expect(+svg.attr('height')).toBe(480);
}); });
});
describe('bindto', function () {
it('should accept d3.selection object', function () {
args.bindto = d3.select('#chart');
expect(true).toBeTruthy();
});
it('should be created', function () {
var svg = d3.select('#chart svg');
expect(svg).not.toBeNull();
});
});
}); });
...@@ -114,7 +114,8 @@ describe('c3 chart data', function () { ...@@ -114,7 +114,8 @@ describe('c3 chart data', function () {
x: { x: {
type: 'timeseries', type: 'timeseries',
tick: { tick: {
format: '%Y-%m-%d %H:%M:%S.%L' format: '%Y-%m-%d %H:%M:%S.%L',
multiline: false
} }
} }
} }
......
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 chart grid', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250]
]
},
axis: {
y: {
tick: {
}
}
},
grid: {
y: {
show: false
}
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('y grid', function () {
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 () {
args.grid.y.show = true;
expect(true).toBeTruthy();
});
it('should show y grids', function () {
var ygrids = chart.internal.main.select('.c3-ygrids');
expect(ygrids.size()).toBe(1);
expect(ygrids.selectAll('.c3-ygrid').size()).toBe(9);
});
it('should update args to show only 3 y grids', function () {
args.grid.y.ticks = 3;
expect(true).toBeTruthy();
});
it('should show only 3 y grids', function () {
var ygrids = chart.internal.main.select('.c3-ygrids');
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 () {
args.axis.y.tick.count = 5;
expect(true).toBeTruthy();
});
it('should show grids depending on y axis ticks', function () {
var ygrids = chart.internal.main.select('.c3-ygrids'),
expectedYs = [];
ygrids.selectAll('.c3-ygrid').each(function (d, i) {
expectedYs[i] = +d3.select(this).attr('y1');
});
expect(ygrids.size()).toBe(1);
expect(ygrids.selectAll('.c3-ygrid').size()).toBe(5);
chart.internal.main.select('.c3-axis-y').selectAll('.tick').each(function (d, i) {
var t = d3.transform(d3.select(this).attr('transform'));
expect(t.translate[1]).toBe(expectedYs[i]);
});
});
});
});
...@@ -84,6 +84,26 @@ describe('c3 chart legend', function () { ...@@ -84,6 +84,26 @@ describe('c3 chart legend', function () {
expect(box.height).toBe(48); expect(box.height).toBe(48);
}); });
it('should update args to have only one series', function () {
args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
]
},
legend: {
position: 'inset'
}
};
expect(true).toBeTruthy();
});
it('should locate legend properly', function () {
var box = d3.select('.c3-legend-background').node().getBoundingClientRect();
expect(box.height).toBe(28);
expect(box.width).toBeGreaterThan(64);
});
}); });
}); });
...@@ -3,8 +3,7 @@ var describe = window.describe, ...@@ -3,8 +3,7 @@ var describe = window.describe,
it = window.it, it = window.it,
beforeEach = window.beforeEach; beforeEach = window.beforeEach;
var initDom = window.initDom, var setMouseEvent = window.setMouseEvent;
setEvent = window.setEvent;
describe('c3 chart shape bar', function () { describe('c3 chart shape bar', function () {
'use strict'; 'use strict';
...@@ -26,16 +25,8 @@ describe('c3 chart shape bar', function () { ...@@ -26,16 +25,8 @@ describe('c3 chart shape bar', function () {
}; };
beforeEach(function (done) { beforeEach(function (done) {
if (typeof chart === 'undefined') { chart = window.initChart(chart, args, done);
initDom();
}
chart = window.c3.generate(args);
d3 = chart.internal.d3; d3 = chart.internal.d3;
chart.internal.d3.select('.jasmine_html-reporter').style('display', 'none');
window.setTimeout(function () {
done();
}, 10);
}); });
describe('internal.isWithinBar', function () { describe('internal.isWithinBar', function () {
...@@ -44,25 +35,25 @@ describe('c3 chart shape bar', function () { ...@@ -44,25 +35,25 @@ describe('c3 chart shape bar', function () {
it('should not be within bar', function () { it('should not be within bar', function () {
var bar = d3.select('.c3-target-data1 .c3-bar-0').node(); var bar = d3.select('.c3-target-data1 .c3-bar-0').node();
setEvent(chart, 0, 0); setMouseEvent(chart, 'click', 0, 0);
expect(chart.internal.isWithinBar(bar)).toBeFalsy(); expect(chart.internal.isWithinBar(bar)).toBeFalsy();
}); });
it('should be within bar', function () { it('should be within bar', function () {
var bar = d3.select('.c3-target-data1 .c3-bar-0').node(); var bar = d3.select('.c3-target-data1 .c3-bar-0').node();
setEvent(chart, 31, 280); setMouseEvent(chart, 'click', 31, 280);
expect(chart.internal.isWithinBar(bar)).toBeTruthy(); expect(chart.internal.isWithinBar(bar)).toBeTruthy();
}); });
it('should not be within bar of negative value', function () { it('should not be within bar of negative value', function () {
var bar = d3.select('.c3-target-data3 .c3-bar-0').node(); var bar = d3.select('.c3-target-data3 .c3-bar-0').node();
setEvent(chart, 68, 280); setMouseEvent(chart, 'click', 68, 280);
expect(chart.internal.isWithinBar(bar)).toBeFalsy(); expect(chart.internal.isWithinBar(bar)).toBeFalsy();
}); });
it('should be within bar of negative value', function () { it('should be within bar of negative value', function () {
var bar = d3.select('.c3-target-data3 .c3-bar-0').node(); var bar = d3.select('.c3-target-data3 .c3-bar-0').node();
setEvent(chart, 68, 350); setMouseEvent(chart, 'click', 68, 350);
expect(chart.internal.isWithinBar(bar)).toBeTruthy(); expect(chart.internal.isWithinBar(bar)).toBeTruthy();
}); });
...@@ -77,19 +68,19 @@ describe('c3 chart shape bar', function () { ...@@ -77,19 +68,19 @@ describe('c3 chart shape bar', function () {
it('should not be within bar', function () { it('should not be within bar', function () {
var bar = d3.select('.c3-target-data1 .c3-bar-0').node(); var bar = d3.select('.c3-target-data1 .c3-bar-0').node();
setEvent(chart, 0, 0); setMouseEvent(chart, 'click', 0, 0);
expect(chart.internal.isWithinBar(bar)).toBeFalsy(); expect(chart.internal.isWithinBar(bar)).toBeFalsy();
}); });
it('should be within bar', function () { it('should be within bar', function () {
var bar = d3.select('.c3-target-data1 .c3-bar-0').node(); var bar = d3.select('.c3-target-data1 .c3-bar-0').node();
setEvent(chart, 190, 20); setMouseEvent(chart, 'click', 190, 20);
expect(chart.internal.isWithinBar(bar)).toBeTruthy(); expect(chart.internal.isWithinBar(bar)).toBeTruthy();
}); });
it('should be within bar of negative value', function () { it('should be within bar of negative value', function () {
var bar = d3.select('.c3-target-data3 .c3-bar-0').node(); var bar = d3.select('.c3-target-data3 .c3-bar-0').node();
setEvent(chart, 68, 50); setMouseEvent(chart, 'click', 68, 50);
expect(chart.internal.isWithinBar(bar)).toBeTruthy(); expect(chart.internal.isWithinBar(bar)).toBeTruthy();
}); });
......
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 chart tooltip', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', 150, 120, 110, 140, 115, 125]
]
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('tooltip position', function () {
describe('without left margin', function () {
it('should show tooltip on proper position', function () {
var eventRect = d3.select('.c3-event-rect-2').node();
window.setMouseEvent(chart, 'mousemove', 100, 100, eventRect);
var tooltipContainer = d3.select('.c3-tooltip-container'),
top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),
left = Math.floor(+tooltipContainer.style('left').replace(/px/, '')),
topExpected = 115,
leftExpected = 304;
expect(top).toBe(topExpected);
expect(left).toBe(leftExpected);
});
});
describe('with left margin', function () {
it('should set left margin', function () {
d3.select('#chart').style('margin-left', '300px');
expect(true).toBeTruthy();
});
it('should show tooltip on proper position', function () {
var eventRect = d3.select('.c3-event-rect-2').node();
window.setMouseEvent(chart, 'mousemove', 100, 100, eventRect);
var tooltipContainer = d3.select('.c3-tooltip-container'),
top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),
left = Math.floor(+tooltipContainer.style('left').replace(/px/, '')),
topExpected = 115,
leftExpected = 304;
expect(top).toBe(topExpected);
expect(left).toBe(leftExpected);
});
});
});
});
var describe = window.describe,
expect = window.expect,
it = window.it,
beforeEach = window.beforeEach;
describe('c3 chart zoom', function () {
'use strict';
var chart, d3;
var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 3150, 250],
['data2', 50, 20, 10, 40, 15, 6025]
]
},
axis: {
x: {
extent: [1, 2]
}
},
zoom: {
enable: true
},
subchart: {
show: true
}
};
beforeEach(function (done) {
chart = window.initChart(chart, args, done);
d3 = chart.internal.d3;
});
describe('default extent', function () {
describe('main chart domain', function () {
it('should have original y domain', function () {
var yDomain = chart.internal.y.domain(),
expectedYDomain = [-591.5, 6626.5];
expect(yDomain[0]).toBe(expectedYDomain[0]);
expect(yDomain[1]).toBe(expectedYDomain[1]);
});
});
describe('main chart domain', function () {
it('should have original y domain in subchart', function () {
var yDomain = chart.internal.y.domain(),
subYDomain = chart.internal.subY.domain();
expect(subYDomain[0]).toBe(yDomain[0]);
expect(subYDomain[1]).toBe(yDomain[1]);
});
});
describe('main chart domain', function () {
it('should have specified brush extent', function () {
var brushExtent = chart.internal.brush.extent(),
expectedBrushExtent = [1, 2];
expect(brushExtent[0]).toBe(expectedBrushExtent[0]);
expect(brushExtent[1]).toBe(expectedBrushExtent[1]);
});
});
});
});
...@@ -15,5 +15,6 @@ c3_chart_fn.destroy = function () { ...@@ -15,5 +15,6 @@ c3_chart_fn.destroy = function () {
$$.data.targets = undefined; $$.data.targets = undefined;
$$.data.xs = {}; $$.data.xs = {};
$$.selectChart.classed('c3', false).html(""); $$.selectChart.classed('c3', false).html("");
window.clearInterval($$.intervalForObserveInserted);
window.onresize = null; window.onresize = null;
}; };
...@@ -2,7 +2,7 @@ c3_chart_fn.xgrids = function (grids) { ...@@ -2,7 +2,7 @@ c3_chart_fn.xgrids = function (grids) {
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_x_lines; } if (! grids) { return config.grid_x_lines; }
config.grid_x_lines = grids; config.grid_x_lines = grids;
$$.redraw(); $$.redrawWithoutRescale();
return config.grid_x_lines; return config.grid_x_lines;
}; };
c3_chart_fn.xgrids.add = function (grids) { c3_chart_fn.xgrids.add = function (grids) {
...@@ -18,7 +18,7 @@ c3_chart_fn.ygrids = function (grids) { ...@@ -18,7 +18,7 @@ c3_chart_fn.ygrids = function (grids) {
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
if (! grids) { return config.grid_y_lines; } if (! grids) { return config.grid_y_lines; }
config.grid_y_lines = grids; config.grid_y_lines = grids;
$$.redraw(); $$.redrawWithoutRescale();
return config.grid_y_lines; return config.grid_y_lines;
}; };
c3_chart_fn.ygrids.add = function (grids) { c3_chart_fn.ygrids.add = function (grids) {
......
...@@ -2,14 +2,14 @@ c3_chart_fn.regions = function (regions) { ...@@ -2,14 +2,14 @@ c3_chart_fn.regions = function (regions) {
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; } if (!regions) { return config.regions; }
config.regions = regions; config.regions = regions;
$$.redraw(); $$.redrawWithoutRescale();
return config.regions; return config.regions;
}; };
c3_chart_fn.regions.add = function (regions) { c3_chart_fn.regions.add = function (regions) {
var $$ = this.internal, config = $$.config; var $$ = this.internal, config = $$.config;
if (!regions) { return config.regions; } if (!regions) { return config.regions; }
config.regions = config.regions.concat(regions); config.regions = config.regions.concat(regions);
$$.redraw(); $$.redrawWithoutRescale();
return config.regions; return config.regions;
}; };
c3_chart_fn.regions.remove = function (options) { c3_chart_fn.regions.remove = function (options) {
......
...@@ -5,7 +5,8 @@ c3_chart_fn.zoom = function (domain) { ...@@ -5,7 +5,8 @@ c3_chart_fn.zoom = function (domain) {
domain = domain.map(function (x) { return $$.parseDate(x); }); domain = domain.map(function (x) { return $$.parseDate(x); });
} }
$$.brush.extent(domain); $$.brush.extent(domain);
$$.redraw({withUpdateXDomain: true}); $$.redraw({withUpdateXDomain: true, withY: $$.config.zoom_rescale});
$$.config.zoom_onzoom.call(this, $$.x.orgDomain());
} }
return $$.brush.extent(); return $$.brush.extent();
}; };
......
...@@ -127,8 +127,10 @@ c3_chart_internal_fn.expandArc = function (targetIds) { ...@@ -127,8 +127,10 @@ c3_chart_internal_fn.expandArc = function (targetIds) {
interval = window.setInterval(function () { interval = window.setInterval(function () {
if (!$$.transiting) { if (!$$.transiting) {
window.clearInterval(interval); window.clearInterval(interval);
if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {
$$.expandArc(targetIds); $$.expandArc(targetIds);
} }
}
}, 10); }, 10);
return; return;
} }
...@@ -216,7 +218,7 @@ c3_chart_internal_fn.updateTargetsForArc = function (targets) { ...@@ -216,7 +218,7 @@ c3_chart_internal_fn.updateTargetsForArc = function (targets) {
mainPieEnter.append('g') mainPieEnter.append('g')
.attr('class', classArcs); .attr('class', classArcs);
mainPieEnter.append("text") mainPieEnter.append("text")
.attr("dy", $$.hasType('gauge') ? "-0.35em" : ".35em") .attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em")
.style("opacity", 0) .style("opacity", 0)
.style("text-anchor", "middle") .style("text-anchor", "middle")
.style("pointer-events", "none"); .style("pointer-events", "none");
...@@ -311,7 +313,11 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf ...@@ -311,7 +313,11 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
} }
interpolate = d3.interpolate(this._current, updated); interpolate = d3.interpolate(this._current, updated);
this._current = interpolate(0); this._current = interpolate(0);
return function (t) { return $$.getArc(interpolate(t), true); }; return function (t) {
var interpolated = interpolate(t);
interpolated.data = d.data; // data.id will be updated by interporator
return $$.getArc(interpolated, true);
};
}) })
.attr("transform", withTransform ? "scale(1)" : "") .attr("transform", withTransform ? "scale(1)" : "")
.style("fill", function (d) { .style("fill", function (d) {
...@@ -329,6 +335,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf ...@@ -329,6 +335,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
.attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; }) .attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; })
.text($$.textForArcLabel.bind($$)) .text($$.textForArcLabel.bind($$))
.attr("transform", $$.transformForArcLabel.bind($$)) .attr("transform", $$.transformForArcLabel.bind($$))
.style('font-size', function (d) { return $$.isGaugeType(d.data) ? Math.round($$.radius / 5) + 'px' : ''; })
.transition().duration(duration) .transition().duration(duration)
.style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); .style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; });
main.select('.' + CLASS.chartArcsTitle) main.select('.' + CLASS.chartArcsTitle)
......
...@@ -35,7 +35,8 @@ c3_chart_internal_fn.getXAxis = function (scale, orient, tickFormat, tickValues, ...@@ -35,7 +35,8 @@ c3_chart_internal_fn.getXAxis = function (scale, orient, tickFormat, tickValues,
axisParams = { axisParams = {
isCategory: $$.isCategorized(), isCategory: $$.isCategorized(),
withOuterTick: withOuterTick, withOuterTick: withOuterTick,
tickWidth: $$.isCategorized() ? config.axis_x_tick_width : undefined tickMultiline: config.axis_x_tick_multiline,
tickWidth: config.axis_x_tick_width
}, },
axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient); axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient);
...@@ -63,8 +64,14 @@ c3_chart_internal_fn.getXAxis = function (scale, orient, tickFormat, tickValues, ...@@ -63,8 +64,14 @@ c3_chart_internal_fn.getXAxis = function (scale, orient, tickFormat, tickValues,
return axis; return axis;
}; };
c3_chart_internal_fn.getYAxis = function (scale, orient, tickFormat, tickValues, withOuterTick) { c3_chart_internal_fn.getYAxis = function (scale, orient, tickFormat, tickValues, withOuterTick) {
var axisParams = {withOuterTick: withOuterTick}; var axisParams = {withOuterTick: withOuterTick},
return c3_axis(this.d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat).tickValues(tickValues); axis = c3_axis(this.d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
if (this.isTimeSeriesY()) {
axis.ticks(this.d3.time[this.config.axis_y_tick_time_value], this.config.axis_y_tick_time_interval);
} else {
axis.tickValues(tickValues);
}
return axis;
}; };
c3_chart_internal_fn.getAxisId = function (id) { c3_chart_internal_fn.getAxisId = function (id) {
var config = this.config; var config = this.config;
...@@ -242,7 +249,7 @@ c3_chart_internal_fn.textAnchorForY2AxisLabel = function () { ...@@ -242,7 +249,7 @@ c3_chart_internal_fn.textAnchorForY2AxisLabel = function () {
}; };
c3_chart_internal_fn.xForRotatedTickText = function (r) { c3_chart_internal_fn.xForRotatedTickText = function (r) {
return 10 * Math.sin(Math.PI * (r / 180)); return 8 * Math.sin(Math.PI * (r / 180));
}; };
c3_chart_internal_fn.yForRotatedTickText = function (r) { c3_chart_internal_fn.yForRotatedTickText = function (r) {
return 11.5 - 2.5 * (r / 15) * (r > 0 ? 1 : -1); return 11.5 - 2.5 * (r / 15) * (r > 0 ? 1 : -1);
...@@ -252,24 +259,28 @@ c3_chart_internal_fn.rotateTickText = function (axis, transition, rotate) { ...@@ -252,24 +259,28 @@ c3_chart_internal_fn.rotateTickText = function (axis, transition, rotate) {
.style("text-anchor", rotate > 0 ? "start" : "end"); .style("text-anchor", rotate > 0 ? "start" : "end");
transition.selectAll('.tick text') transition.selectAll('.tick text')
.attr("y", this.yForRotatedTickText(rotate)) .attr("y", this.yForRotatedTickText(rotate))
.attr("x", this.xForRotatedTickText(rotate)) .attr("transform", "rotate(" + rotate + ")")
.attr("transform", "rotate(" + rotate + ")"); .selectAll('tspan')
.attr('dx', this.xForRotatedTickText(rotate));
}; };
c3_chart_internal_fn.getMaxTickWidth = function (id) { c3_chart_internal_fn.getMaxTickWidth = function (id, withoutRecompute) {
var $$ = this, config = $$.config, var $$ = this, config = $$.config,
maxWidth = 0, targetsToShow, scale, axis; maxWidth = 0, targetsToShow, scale, axis;
if (withoutRecompute && $$.currentMaxTickWidths[id]) {
return $$.currentMaxTickWidths[id];
}
if ($$.svg) { if ($$.svg) {
targetsToShow = $$.filterTargetsToShow($$.data.targets); targetsToShow = $$.filterTargetsToShow($$.data.targets);
if (id === 'y') { if (id === 'y') {
scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y')); scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
axis = $$.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.getYAxisTickValues()); axis = $$.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues);
} else if (id === 'y2') { } else if (id === 'y2') {
scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2')); scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
axis = $$.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.getY2AxisTickValues()); axis = $$.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues);
} else { } else {
scale = $$.x.copy().domain($$.getXDomain(targetsToShow)); scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
axis = $$.getXAxis(scale, $$.xOrient, $$.getXAxisTickFormat(), $$.getXAxisTickValues()); axis = $$.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues);
} }
$$.d3.select('body').append("g").style('visibility', 'hidden').call(axis).each(function () { $$.d3.select('body').append("g").style('visibility', 'hidden').call(axis).each(function () {
$$.d3.select(this).selectAll('text tspan').each(function () { $$.d3.select(this).selectAll('text tspan').each(function () {
...@@ -278,8 +289,8 @@ c3_chart_internal_fn.getMaxTickWidth = function (id) { ...@@ -278,8 +289,8 @@ c3_chart_internal_fn.getMaxTickWidth = function (id) {
}); });
}).remove(); }).remove();
} }
$$.currentMaxTickWidth = maxWidth <= 0 ? $$.currentMaxTickWidth : maxWidth; $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
return $$.currentMaxTickWidth; return $$.currentMaxTickWidths[id];
}; };
c3_chart_internal_fn.updateAxisLabels = function (withTransition) { c3_chart_internal_fn.updateAxisLabels = function (withTransition) {
...@@ -345,7 +356,7 @@ c3_chart_internal_fn.generateAxisTransitions = function (duration) { ...@@ -345,7 +356,7 @@ c3_chart_internal_fn.generateAxisTransitions = function (duration) {
}; };
}; };
c3_chart_internal_fn.redrawAxis = function (transitions, isHidden) { c3_chart_internal_fn.redrawAxis = function (transitions, isHidden) {
var $$ = this; var $$ = this, config = $$.config;
$$.axes.x.style("opacity", isHidden ? 0 : 1); $$.axes.x.style("opacity", isHidden ? 0 : 1);
$$.axes.y.style("opacity", isHidden ? 0 : 1); $$.axes.y.style("opacity", isHidden ? 0 : 1);
$$.axes.y2.style("opacity", isHidden ? 0 : 1); $$.axes.y2.style("opacity", isHidden ? 0 : 1);
...@@ -354,4 +365,8 @@ c3_chart_internal_fn.redrawAxis = function (transitions, isHidden) { ...@@ -354,4 +365,8 @@ c3_chart_internal_fn.redrawAxis = function (transitions, isHidden) {
transitions.axisY.call($$.yAxis); transitions.axisY.call($$.yAxis);
transitions.axisY2.call($$.y2Axis); transitions.axisY2.call($$.y2Axis);
transitions.axisSubX.call($$.subXAxis); transitions.axisSubX.call($$.subXAxis);
// rotate tick text if needed
if (!config.axis_rotated && config.axis_x_tick_rotate) {
$$.rotateTickText($$.axes.x, transitions.axisX, config.axis_x_tick_rotate);
}
}; };
...@@ -97,19 +97,26 @@ function c3_axis(d3, params) { ...@@ -97,19 +97,26 @@ function c3_axis(d3, params) {
tickOffset = tickX = 0; tickOffset = tickX = 0;
} }
var text, tspan, sizeFor1Char = getSizeFor1Char(tick), counts = []; var text, tspan, sizeFor1Char = getSizeFor1Char(g.select('.tick')), counts = [];
var tickLength = Math.max(innerTickSize, 0) + tickPadding, var tickLength = Math.max(innerTickSize, 0) + tickPadding,
isVertical = orient === 'left' || orient === 'right'; isVertical = orient === 'left' || orient === 'right';
// this should be called only when category axis // this should be called only when category axis
function splitTickText(d) { function splitTickText(d, maxWidth) {
var tickText = textFormatted(d) + "", var tickText = textFormatted(d),
maxWidth = isVertical ? params.tickWidth : tickOffset * 2 - 10,
subtext, spaceIndex, textWidth, splitted = []; subtext, spaceIndex, textWidth, splitted = [];
if (Object.prototype.toString.call(tickText) === "[object Array]") {
return tickText;
}
if (!maxWidth || maxWidth <= 0) {
maxWidth = isVertical ? 95 : params.isCategory ? (Math.ceil(scale1(ticks[1]) - scale1(ticks[0])) - 12) : 110;
}
function split(splitted, text) { function split(splitted, text) {
spaceIndex = undefined; spaceIndex = undefined;
for (var i = 0; i < text.length; i++) { for (var i = 1; i < text.length; i++) {
if (text.charAt(i) === ' ') { if (text.charAt(i) === ' ') {
spaceIndex = i; spaceIndex = i;
} }
...@@ -126,7 +133,7 @@ function c3_axis(d3, params) { ...@@ -126,7 +133,7 @@ function c3_axis(d3, params) {
return splitted.concat(text); return splitted.concat(text);
} }
return split(splitted, tickText); return split(splitted, tickText + "");
} }
function tspanDy(d, i) { function tspanDy(d, i) {
...@@ -135,7 +142,7 @@ function c3_axis(d3, params) { ...@@ -135,7 +142,7 @@ function c3_axis(d3, params) {
if (orient === 'left' || orient === 'right') { if (orient === 'left' || orient === 'right') {
dy = -((counts[d.index] - 1) * (sizeFor1Char.h / 2) - (params.isCategory ? 2 : 3)); dy = -((counts[d.index] - 1) * (sizeFor1Char.h / 2) - (params.isCategory ? 2 : 3));
} else { } else {
dy = params.isCategory ? ".40em" : ".71em"; dy = ".71em";
} }
} }
return dy; return dy;
...@@ -149,7 +156,7 @@ function c3_axis(d3, params) { ...@@ -149,7 +156,7 @@ function c3_axis(d3, params) {
text = tick.select("text"); text = tick.select("text");
tspan = text.selectAll('tspan') tspan = text.selectAll('tspan')
.data(function (d, i) { .data(function (d, i) {
var splitted = params.tickWidth ? splitTickText(d) : [].concat(textFormatted(d)); var splitted = params.tickMultiline ? splitTickText(d, params.tickWidth) : [].concat(textFormatted(d));
counts[i] = splitted.length; counts[i] = splitted.length;
return splitted.map(function (s) { return splitted.map(function (s) {
return { index: i, splitted: s }; return { index: i, splitted: s };
......
...@@ -155,7 +155,7 @@ c3_chart_internal_fn.classChartArc = function (d) { ...@@ -155,7 +155,7 @@ c3_chart_internal_fn.classChartArc = function (d) {
return CLASS.chartArc + this.classTarget(d.data.id); return CLASS.chartArc + this.classTarget(d.data.id);
}; };
c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) { c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
return targetId || targetId === 0 ? '-' + (targetId.replace ? targetId.replace(/([^a-zA-Z0-9-_])/g, '-') : targetId) : ''; return targetId || targetId === 0 ? ('-' + targetId).replace(/[\s?!@#$%^&*()_=+,.<>'":;\[\]/|~`{}\\]/g, '-') : '';
}; };
c3_chart_internal_fn.selectorTarget = function (id, prefix) { c3_chart_internal_fn.selectorTarget = function (id, prefix) {
return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id); return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
......
...@@ -11,7 +11,7 @@ c3_chart_internal_fn.getAxisClipX = function (forHorizontal) { ...@@ -11,7 +11,7 @@ c3_chart_internal_fn.getAxisClipX = function (forHorizontal) {
return forHorizontal ? -(1 + left) : -(left - 1); return forHorizontal ? -(1 + left) : -(left - 1);
}; };
c3_chart_internal_fn.getAxisClipY = function (forHorizontal) { c3_chart_internal_fn.getAxisClipY = function (forHorizontal) {
return forHorizontal ? -20 : -4; return forHorizontal ? -20 : -this.margin.top;
}; };
c3_chart_internal_fn.getXAxisClipX = function () { c3_chart_internal_fn.getXAxisClipX = function () {
var $$ = this; var $$ = this;
...@@ -37,8 +37,7 @@ c3_chart_internal_fn.getAxisClipWidth = function (forHorizontal) { ...@@ -37,8 +37,7 @@ c3_chart_internal_fn.getAxisClipWidth = function (forHorizontal) {
return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20; return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;
}; };
c3_chart_internal_fn.getAxisClipHeight = function (forHorizontal) { c3_chart_internal_fn.getAxisClipHeight = function (forHorizontal) {
var $$ = this, config = $$.config; return (forHorizontal ? this.margin.bottom : (this.margin.top + this.height)) + 8;
return forHorizontal ? (config.axis_x_height ? config.axis_x_height : 0) + 80 : $$.height + 8;
}; };
c3_chart_internal_fn.getXAxisClipWidth = function () { c3_chart_internal_fn.getXAxisClipWidth = function () {
var $$ = this; var $$ = this;
......
...@@ -90,9 +90,10 @@ c3_chart_internal_fn.getDefaultConfig = function () { ...@@ -90,9 +90,10 @@ c3_chart_internal_fn.getDefaultConfig = function () {
axis_x_tick_count: undefined, axis_x_tick_count: undefined,
axis_x_tick_fit: true, axis_x_tick_fit: true,
axis_x_tick_values: null, axis_x_tick_values: null,
axis_x_tick_rotate: undefined, axis_x_tick_rotate: 0,
axis_x_tick_outer: true, axis_x_tick_outer: true,
axis_x_tick_width: 80, axis_x_tick_multiline: true,
axis_x_tick_width: null,
axis_x_max: undefined, axis_x_max: undefined,
axis_x_min: undefined, axis_x_min: undefined,
axis_x_padding: {}, axis_x_padding: {},
...@@ -100,6 +101,7 @@ c3_chart_internal_fn.getDefaultConfig = function () { ...@@ -100,6 +101,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
axis_x_extent: undefined, axis_x_extent: undefined,
axis_x_label: {}, axis_x_label: {},
axis_y_show: true, axis_y_show: true,
axis_y_type: undefined,
axis_y_max: undefined, axis_y_max: undefined,
axis_y_min: undefined, axis_y_min: undefined,
axis_y_center: undefined, axis_y_center: undefined,
...@@ -108,6 +110,8 @@ c3_chart_internal_fn.getDefaultConfig = function () { ...@@ -108,6 +110,8 @@ c3_chart_internal_fn.getDefaultConfig = function () {
axis_y_tick_outer: true, axis_y_tick_outer: true,
axis_y_tick_values: null, axis_y_tick_values: null,
axis_y_tick_count: undefined, axis_y_tick_count: undefined,
axis_y_tick_time_value: undefined,
axis_y_tick_time_interval: undefined,
axis_y_padding: {}, axis_y_padding: {},
axis_y_default: undefined, axis_y_default: undefined,
axis_y2_show: false, axis_y2_show: false,
......
...@@ -100,13 +100,20 @@ c3_chart_internal_fn.cloneTarget = function (target) { ...@@ -100,13 +100,20 @@ c3_chart_internal_fn.cloneTarget = function (target) {
}) })
}; };
}; };
c3_chart_internal_fn.updateXs = function () {
var $$ = this;
$$.xs = [];
$$.data.targets[0].values.forEach(function (v) {
$$.xs[v.index] = v.x;
});
};
c3_chart_internal_fn.getPrevX = function (i) { c3_chart_internal_fn.getPrevX = function (i) {
var $$ = this, value = $$.getValueOnIndex($$.data.targets[0].values, i - 1); var x = this.xs[i - 1];
return value ? value.x : null; return typeof x !== 'undefined' ? x : null;
}; };
c3_chart_internal_fn.getNextX = function (i) { c3_chart_internal_fn.getNextX = function (i) {
var $$ = this, value = $$.getValueOnIndex($$.data.targets[0].values, i + 1); var x = this.xs[i + 1];
return value ? value.x : null; return typeof x !== 'undefined' ? x : null;
}; };
c3_chart_internal_fn.getMaxDataCount = function () { c3_chart_internal_fn.getMaxDataCount = function () {
var $$ = this; var $$ = this;
...@@ -296,22 +303,34 @@ c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) { ...@@ -296,22 +303,34 @@ c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) {
return $$.findClosest(candidates, pos); return $$.findClosest(candidates, pos);
}; };
c3_chart_internal_fn.findClosest = function (values, pos) { c3_chart_internal_fn.findClosest = function (values, pos) {
var $$ = this, minDist, closest; var $$ = this, minDist = 100, closest;
values.forEach(function (v) {
// find mouseovering bar
values.filter(function (v) { return v && $$.isBarType(v.id); }).forEach(function (v) {
var shape = $$.d3.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
if ($$.isWithinBar(shape)) {
closest = v;
}
});
// find closest point from non-bar
values.filter(function (v) { return v && !$$.isBarType(v.id); }).forEach(function (v) {
var d = $$.dist(v, pos); var d = $$.dist(v, pos);
if (d < minDist || ! minDist) { if (d < minDist) {
minDist = d; minDist = d;
closest = v; closest = v;
} }
}); });
return closest; return closest;
}; };
c3_chart_internal_fn.dist = function (data, pos) { c3_chart_internal_fn.dist = function (data, pos) {
var $$ = this, config = $$.config, var $$ = this, config = $$.config,
yScale = $$.getAxisId(data.id) === 'y' ? $$.y : $$.y2,
xIndex = config.axis_rotated ? 1 : 0, xIndex = config.axis_rotated ? 1 : 0,
yIndex = config.axis_rotated ? 0 : 1; yIndex = config.axis_rotated ? 0 : 1,
return Math.pow($$.x(data.x) - pos[xIndex], 2) + Math.pow(yScale(data.value) - pos[yIndex], 2); y = $$.circleY(data, data.index),
x = $$.x(data.x);
return Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2);
}; };
c3_chart_internal_fn.convertValuesToStep = function (values) { c3_chart_internal_fn.convertValuesToStep = function (values) {
var converted = [].concat(values), i; var converted = [].concat(values), i;
......
...@@ -55,9 +55,10 @@ c3_chart_internal_fn.updateXGrid = function (withoutUpdate) { ...@@ -55,9 +55,10 @@ c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
}; };
c3_chart_internal_fn.updateYGrid = function () { c3_chart_internal_fn.updateYGrid = function () {
var $$ = this, config = $$.config; var $$ = this, config = $$.config,
gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
$$.ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid) $$.ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid)
.data($$.y.ticks(config.grid_y_ticks)); .data(gridValues);
$$.ygrid.enter().append('line') $$.ygrid.enter().append('line')
.attr('class', CLASS.ygrid); .attr('class', CLASS.ygrid);
$$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0) $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0)
...@@ -69,7 +70,7 @@ c3_chart_internal_fn.updateYGrid = function () { ...@@ -69,7 +70,7 @@ c3_chart_internal_fn.updateYGrid = function () {
}; };
c3_chart_internal_fn.redrawGrid = function (duration, withY) { c3_chart_internal_fn.redrawGrid = function (duration) {
var $$ = this, main = $$.main, config = $$.config, var $$ = this, main = $$.main, config = $$.config,
xgridLine, ygridLine, yv; xgridLine, ygridLine, yv;
...@@ -101,10 +102,9 @@ c3_chart_internal_fn.redrawGrid = function (duration, withY) { ...@@ -101,10 +102,9 @@ c3_chart_internal_fn.redrawGrid = function (duration, withY) {
.remove(); .remove();
// Y-Grid // Y-Grid
if (withY && config.grid_y_show) { if (config.grid_y_show) {
$$.updateYGrid(); $$.updateYGrid();
} }
if (withY) {
$$.ygridLines = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine) $$.ygridLines = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine)
.data(config.grid_y_lines); .data(config.grid_y_lines);
// enter // enter
...@@ -137,7 +137,6 @@ c3_chart_internal_fn.redrawGrid = function (duration, withY) { ...@@ -137,7 +137,6 @@ c3_chart_internal_fn.redrawGrid = function (duration, withY) {
$$.ygridLines.exit().transition().duration(duration) $$.ygridLines.exit().transition().duration(duration)
.style("opacity", 0) .style("opacity", 0)
.remove(); .remove();
}
}; };
c3_chart_internal_fn.addTransitionForGrid = function (transitions) { c3_chart_internal_fn.addTransitionForGrid = function (transitions) {
var $$ = this, config = $$.config, xv = $$.xv.bind($$); var $$ = this, config = $$.config, xv = $$.xv.bind($$);
...@@ -202,7 +201,7 @@ c3_chart_internal_fn.getGridFilterToRemove = function (params) { ...@@ -202,7 +201,7 @@ c3_chart_internal_fn.getGridFilterToRemove = function (params) {
return params ? function (line) { return params ? function (line) {
var found = false; var found = false;
[].concat(params).forEach(function (param) { [].concat(params).forEach(function (param) {
if ((('value' in param && line.value === params.value) || ('class' in param && line['class'] === params['class']))) { if ((('value' in param && line.value === param.value) || ('class' in param && line['class'] === param['class']))) {
found = true; found = true;
} }
}); });
......
...@@ -59,6 +59,10 @@ c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) { ...@@ -59,6 +59,10 @@ c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) {
} }
else { else {
if (($$.isCustomX() || $$.isTimeSeries()) && !$$.isCategorized()) { if (($$.isCustomX() || $$.isTimeSeries()) && !$$.isCategorized()) {
// update index for x that is used by prevX and nextX
$$.updateXs();
rectW = function (d) { rectW = function (d) {
var prevX = $$.getPrevX(d.index), nextX = $$.getNextX(d.index); var prevX = $$.getPrevX(d.index), nextX = $$.getNextX(d.index);
...@@ -231,12 +235,20 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) { ...@@ -231,12 +235,20 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
.on('drag', function () { $$.drag(d3.mouse(this)); }) .on('drag', function () { $$.drag(d3.mouse(this)); })
.on('dragstart', function () { $$.dragstart(d3.mouse(this)); }) .on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
.on('dragend', function () { $$.dragend(); }) .on('dragend', function () { $$.dragend(); })
) );
.on("dblclick.zoom", null);
}; };
c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) { c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config; var $$ = this, d3 = $$.d3, config = $$.config;
function mouseout() {
$$.svg.select('.' + CLASS.eventRect).style('cursor', null);
$$.hideXGridFocus();
$$.hideTooltip();
$$.unexpandCircles();
$$.unexpandBars();
}
eventRectEnter.append('rect') eventRectEnter.append('rect')
.attr('x', 0) .attr('x', 0)
.attr('y', 0) .attr('y', 0)
...@@ -245,9 +257,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) ...@@ -245,9 +257,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
.attr('class', CLASS.eventRect) .attr('class', CLASS.eventRect)
.on('mouseout', function () { .on('mouseout', function () {
if ($$.hasArcType()) { return; } if ($$.hasArcType()) { return; }
$$.hideXGridFocus(); mouseout();
$$.hideTooltip();
$$.unexpandCircles();
}) })
.on('mousemove', function () { .on('mousemove', function () {
var targetsToShow = $$.filterTargetsToShow($$.data.targets); var targetsToShow = $$.filterTargetsToShow($$.data.targets);
...@@ -259,7 +269,15 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) ...@@ -259,7 +269,15 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
mouse = d3.mouse(this); mouse = d3.mouse(this);
closest = $$.findClosestFromTargets(targetsToShow, mouse); closest = $$.findClosestFromTargets(targetsToShow, mouse);
if (! closest) { return; } if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) {
config.data_onmouseout.call($$, $$.mouseover);
$$.mouseover = undefined;
}
if (! closest) {
mouseout();
return;
}
if ($$.isScatterType(closest) || !config.tooltip_grouped) { if ($$.isScatterType(closest) || !config.tooltip_grouped) {
sameXData = [closest]; sameXData = [closest];
...@@ -277,21 +295,18 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) ...@@ -277,21 +295,18 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
if (config.point_focus_expand_enabled) { if (config.point_focus_expand_enabled) {
$$.expandCircles(closest.index, closest.id, true); $$.expandCircles(closest.index, closest.id, true);
} }
$$.expandBars(closest.index, closest.id, true);
// Show xgrid focus line // Show xgrid focus line
$$.showXGridFocus(selectedData); $$.showXGridFocus(selectedData);
// Show cursor as pointer if point is close to mouse position // Show cursor as pointer if point is close to mouse position
if ($$.dist(closest, mouse) < 100) { if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < 100) {
$$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer'); $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
if (!$$.mouseover) { if (!$$.mouseover) {
config.data_onmouseover.call($$, closest); config.data_onmouseover.call($$, closest);
$$.mouseover = true; $$.mouseover = closest;
} }
} else if ($$.mouseover) {
$$.svg.select('.' + CLASS.eventRect).style('cursor', null);
config.data_onmouseout.call($$, closest);
$$.mouseover = false;
} }
}) })
.on('click', function () { .on('click', function () {
...@@ -306,8 +321,8 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) ...@@ -306,8 +321,8 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
if (! closest) { return; } if (! closest) { return; }
// select if selection enabled // select if selection enabled
if ($$.dist(closest, mouse) < 100 && $$.toggleShape) { if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < 100) {
$$.main.select('.' + CLASS.circles + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.circle + '-' + closest.index).each(function () { $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.shape + '-' + closest.index).each(function () {
if (config.data_selection_grouped || $$.isWithinShape(this, closest)) { if (config.data_selection_grouped || $$.isWithinShape(this, closest)) {
$$.toggleShape(this, closest, closest.index); $$.toggleShape(this, closest, closest.index);
$$.config.data_onclick.call($$.api, closest, this); $$.config.data_onclick.call($$.api, closest, this);
...@@ -320,8 +335,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) ...@@ -320,8 +335,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
.on('drag', function () { $$.drag(d3.mouse(this)); }) .on('drag', function () { $$.drag(d3.mouse(this)); })
.on('dragstart', function () { $$.dragstart(d3.mouse(this)); }) .on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
.on('dragend', function () { $$.dragend(); }) .on('dragend', function () { $$.dragend(); })
) );
.on("dblclick.zoom", null);
}; };
c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) { c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
var $$ = this, var $$ = this,
......
...@@ -74,6 +74,7 @@ c3_chart_internal_fn.toggleFocusLegend = function (targetIds, focus) { ...@@ -74,6 +74,7 @@ c3_chart_internal_fn.toggleFocusLegend = function (targetIds, focus) {
c3_chart_internal_fn.revertLegend = function () { c3_chart_internal_fn.revertLegend = function () {
var $$ = this, d3 = $$.d3; var $$ = this, d3 = $$.d3;
$$.legend.selectAll('.' + CLASS.legendItem) $$.legend.selectAll('.' + CLASS.legendItem)
.classed(CLASS.legendItemFocused, false)
.transition().duration(100) .transition().duration(100)
.style('opacity', function () { return $$.opacityForLegend(d3.select(this)); }); .style('opacity', function () { return $$.opacityForLegend(d3.select(this)); });
}; };
...@@ -107,7 +108,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) { ...@@ -107,7 +108,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0; var l, totalLength = 0, offsets = {}, widths = {}, heights = {}, margins = [0], steps = {}, step = 0;
var withTransition, withTransitionForTransform; var withTransition, withTransitionForTransform;
var hasFocused = $$.legend.selectAll('.' + CLASS.legendItemFocused).size(); var hasFocused = $$.legend.selectAll('.' + CLASS.legendItemFocused).size();
var texts, rects, tiles; var texts, rects, tiles, background;
options = options || {}; options = options || {};
withTransition = getOption(options, "withTransition", true); withTransition = getOption(options, "withTransition", true);
...@@ -116,7 +117,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) { ...@@ -116,7 +117,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
function updatePositions(textElement, id, index) { function updatePositions(textElement, id, index) {
var reset = index === 0, isLast = index === targetIds.length - 1, var reset = index === 0, isLast = index === targetIds.length - 1,
box = $$.getTextRect(textElement.textContent, CLASS.legendItem), box = $$.getTextRect(textElement.textContent, CLASS.legendItem),
itemWidth = box.width + tileWidth + (isLast && !$$.isLegendRight ? 0 : paddingRight), itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight),
itemHeight = box.height + paddingTop, itemHeight = box.height + paddingTop,
itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth, itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(), areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
...@@ -225,9 +226,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) { ...@@ -225,9 +226,7 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
}) })
.on('mouseout', function (id) { .on('mouseout', function (id) {
$$.d3.select(this).classed(CLASS.legendItemFocused, false); $$.d3.select(this).classed(CLASS.legendItemFocused, false);
if (!$$.transiting) {
$$.api.revert(); $$.api.revert();
}
if (config.legend_item_onmouseout) { if (config.legend_item_onmouseout) {
config.legend_item_onmouseout.call($$, id); config.legend_item_onmouseout.call($$, id);
} }
...@@ -251,13 +250,13 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) { ...@@ -251,13 +250,13 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
.attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegend) .attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegend)
.attr('width', 10) .attr('width', 10)
.attr('height', 10); .attr('height', 10);
// Set background for inset legend // Set background for inset legend
if ($$.isLegendInset && maxWidth !== 0) { background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
$$.legend.insert('g', '.' + CLASS.legendItem) if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
background = $$.legend.insert('g', '.' + CLASS.legendItem)
.attr("class", CLASS.legendBackground) .attr("class", CLASS.legendBackground)
.append('rect') .append('rect');
.attr('height', $$.getLegendHeight() - 12)
.attr('width', maxWidth * (step + 1) + 10);
} }
texts = $$.legend.selectAll('text') texts = $$.legend.selectAll('text')
...@@ -283,6 +282,12 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) { ...@@ -283,6 +282,12 @@ c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
.attr('x', xForLegend) .attr('x', xForLegend)
.attr('y', yForLegend); .attr('y', yForLegend);
if (background) {
(withTransition ? background.transition() : background)
.attr('height', $$.getLegendHeight() - 12)
.attr('width', maxWidth * (step + 1) + 10);
}
// toggle legend state // toggle legend state
$$.legend.selectAll('.' + CLASS.legendItem) $$.legend.selectAll('.' + CLASS.legendItem)
.classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); }) .classed(CLASS.legendItemHidden, function (id) { return !$$.isTargetToShow(id); })
......
...@@ -39,7 +39,7 @@ c3_chart_internal_fn.getX = function (min, max, domain, offset) { ...@@ -39,7 +39,7 @@ c3_chart_internal_fn.getX = function (min, max, domain, offset) {
return scale; return scale;
}; };
c3_chart_internal_fn.getY = function (min, max, domain) { c3_chart_internal_fn.getY = function (min, max, domain) {
var scale = this.getScale(min, max); var scale = this.getScale(min, max, this.isTimeSeriesY());
if (domain) { scale.domain(domain); } if (domain) { scale.domain(domain); }
return scale; return scale;
}; };
......
...@@ -52,14 +52,14 @@ c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) { ...@@ -52,14 +52,14 @@ c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) {
w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickOffset() * 2 * config.bar_width_ratio) / barTargetsNum : 0; w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? (axis.tickOffset() * 2 * config.bar_width_ratio) / barTargetsNum : 0;
return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w; return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
}; };
c3_chart_internal_fn.getBars = function (i) { c3_chart_internal_fn.getBars = function (i, id) {
var $$ = this; var $$ = this;
return $$.main.selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : '')); return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
}; };
c3_chart_internal_fn.expandBars = function (i, id, reset) { c3_chart_internal_fn.expandBars = function (i, id, reset) {
var $$ = this; var $$ = this;
if (reset) { $$.unexpandBars(); } if (reset) { $$.unexpandBars(); }
$$.getBars(i).classed(CLASS.EXPANDED, true); $$.getBars(i, id).classed(CLASS.EXPANDED, true);
}; };
c3_chart_internal_fn.unexpandBars = function (i) { c3_chart_internal_fn.unexpandBars = function (i) {
var $$ = this; var $$ = this;
...@@ -112,8 +112,7 @@ c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) { ...@@ -112,8 +112,7 @@ c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) {
}; };
}; };
c3_chart_internal_fn.isWithinBar = function (that) { c3_chart_internal_fn.isWithinBar = function (that) {
var d3 = this.d3, var mouse = this.d3.mouse(that), box = that.getBoundingClientRect(),
mouse = d3.mouse(that), box = that.getBoundingClientRect(),
seg0 = that.pathSegList.getItem(0), seg1 = that.pathSegList.getItem(1), seg0 = that.pathSegList.getItem(0), seg1 = that.pathSegList.getItem(1),
x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y), x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y),
w = box.width, h = box.height, offset = 2, w = box.width, h = box.height, offset = 2,
......
...@@ -289,7 +289,7 @@ c3_chart_internal_fn.redrawCircle = function () { ...@@ -289,7 +289,7 @@ c3_chart_internal_fn.redrawCircle = function () {
.attr("r", $$.pointR.bind($$)) .attr("r", $$.pointR.bind($$))
.style("fill", $$.color); .style("fill", $$.color);
$$.mainCircle $$.mainCircle
.style("opacity", $$.initialOpacity.bind($$)); .style("opacity", $$.initialOpacityForCircle.bind($$));
$$.mainCircle.exit().remove(); $$.mainCircle.exit().remove();
}; };
c3_chart_internal_fn.addTransitionForCircle = function (transitions, cx, cy) { c3_chart_internal_fn.addTransitionForCircle = function (transitions, cx, cy) {
...@@ -306,10 +306,19 @@ c3_chart_internal_fn.addTransitionForCircle = function (transitions, cx, cy) { ...@@ -306,10 +306,19 @@ c3_chart_internal_fn.addTransitionForCircle = function (transitions, cx, cy) {
c3_chart_internal_fn.circleX = function (d) { c3_chart_internal_fn.circleX = function (d) {
return d.x || d.x === 0 ? this.x(d.x) : null; return d.x || d.x === 0 ? this.x(d.x) : null;
}; };
c3_chart_internal_fn.circleY = function (d, i) { c3_chart_internal_fn.updateCircleY = function () {
var $$ = this, var $$ = this, lineIndices, getPoints;
lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices); if ($$.config.data_groups.length > 0) {
return $$.config.data_groups.length > 0 ? getPoints(d, i)[0][1] : $$.getYScale(d.id)(d.value); lineIndices = $$.getShapeIndices($$.isLineType),
getPoints = $$.generateGetLinePoints(lineIndices);
$$.circleY = function (d, i) {
return getPoints(d, i)[0][1];
};
} else {
$$.circleY = function (d) {
return $$.getYScale(d.id)(d.value);
};
}
}; };
c3_chart_internal_fn.getCircles = function (i, id) { c3_chart_internal_fn.getCircles = function (i, id) {
var $$ = this; var $$ = this;
......
...@@ -15,14 +15,14 @@ c3_chart_internal_fn.getCurrentPaddingBottom = function () { ...@@ -15,14 +15,14 @@ c3_chart_internal_fn.getCurrentPaddingBottom = function () {
var config = this.config; var config = this.config;
return isValue(config.padding_bottom) ? config.padding_bottom : 0; return isValue(config.padding_bottom) ? config.padding_bottom : 0;
}; };
c3_chart_internal_fn.getCurrentPaddingLeft = function () { c3_chart_internal_fn.getCurrentPaddingLeft = function (withoutRecompute) {
var $$ = this, config = $$.config; var $$ = this, config = $$.config;
if (isValue(config.padding_left)) { if (isValue(config.padding_left)) {
return config.padding_left; return config.padding_left;
} else if (config.axis_rotated) { } else if (config.axis_rotated) {
return !config.axis_x_show ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x')), 40); return !config.axis_x_show ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
} else { } else {
return !config.axis_y_show ? 1 : ceil10($$.getAxisWidthByAxisId('y')); return !config.axis_y_show ? 1 : ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
} }
}; };
c3_chart_internal_fn.getCurrentPaddingRight = function () { c3_chart_internal_fn.getCurrentPaddingRight = function () {
...@@ -57,29 +57,33 @@ c3_chart_internal_fn.getParentHeight = function () { ...@@ -57,29 +57,33 @@ c3_chart_internal_fn.getParentHeight = function () {
}; };
c3_chart_internal_fn.getSvgLeft = function () { c3_chart_internal_fn.getSvgLeft = function (withoutRecompute) {
var $$ = this, config = $$.config, var $$ = this, config = $$.config,
leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY, leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
leftAxis = $$.main.select('.' + leftAxisClass).node(), leftAxis = $$.main.select('.' + leftAxisClass).node(),
svgRect = leftAxis ? leftAxis.getBoundingClientRect() : {right: 0}, svgRect = leftAxis ? leftAxis.getBoundingClientRect() : {right: 0},
chartRect = $$.selectChart.node().getBoundingClientRect(), chartRect = $$.selectChart.node().getBoundingClientRect(),
hasArc = $$.hasArcType(), hasArc = $$.hasArcType(),
svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft()); svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
return svgLeft > 0 ? svgLeft : 0; return svgLeft > 0 ? svgLeft : 0;
}; };
c3_chart_internal_fn.getAxisWidthByAxisId = function (id) { c3_chart_internal_fn.getAxisWidthByAxisId = function (id, withoutRecompute) {
var $$ = this, position = $$.getAxisLabelPositionById(id); var $$ = this, position = $$.getAxisLabelPositionById(id);
return position.isInner ? 20 + $$.getMaxTickWidth(id) : 40 + $$.getMaxTickWidth(id); return $$.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
}; };
c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) { c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
var $$ = this, config = $$.config; var $$ = this, config = $$.config, h = 30;
if (axisId === 'x' && !config.axis_x_show) { return 8; } if (axisId === 'x' && !config.axis_x_show) { return 8; }
if (axisId === 'x' && config.axis_x_height) { return config.axis_x_height; } 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; } if (axisId === 'y2' && !config.axis_y2_show) { return $$.rotated_padding_top; }
return ($$.getAxisLabelPositionById(axisId).isInner ? 30 : 40) + (axisId === 'y2' ? -10 : 0); // Calculate x axis height when tick rotated
if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
h = $$.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_x_tick_rotate) / 180);
}
return h + ($$.getAxisLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
}; };
c3_chart_internal_fn.getEventRectWidth = function () { c3_chart_internal_fn.getEventRectWidth = function () {
......
...@@ -19,7 +19,7 @@ c3_chart_internal_fn.initSubchart = function () { ...@@ -19,7 +19,7 @@ c3_chart_internal_fn.initSubchart = function () {
// Define g for chart area // Define g for chart area
context.append('g') context.append('g')
.attr("clip-path", $$.clipPath) .attr("clip-path", $$.clipPathForSubchart)
.attr('class', CLASS.chart); .attr('class', CLASS.chart);
// Define g for bar chart area // Define g for bar chart area
......
...@@ -32,7 +32,7 @@ c3_chart_internal_fn.redrawText = function (durationForExit) { ...@@ -32,7 +32,7 @@ c3_chart_internal_fn.redrawText = function (durationForExit) {
.style("fill", function (d) { return $$.color(d); }) .style("fill", function (d) { return $$.color(d); })
.style("fill-opacity", 0); .style("fill-opacity", 0);
$$.mainText $$.mainText
.text(function (d) { return $$.formatByAxisId($$.getAxisId(d.id))(d.value, d.id); }); .text(function (d, i, j) { return $$.formatByAxisId($$.getAxisId(d.id))(d.value, d.id, i, j); });
$$.mainText.exit() $$.mainText.exit()
.transition().duration(durationForExit) .transition().duration(durationForExit)
.style('fill-opacity', 0) .style('fill-opacity', 0)
......
...@@ -67,27 +67,29 @@ c3_chart_internal_fn.showTooltip = function (selectedData, mouse) { ...@@ -67,27 +67,29 @@ c3_chart_internal_fn.showTooltip = function (selectedData, mouse) {
tooltipLeft = ($$.width / 2) + mouse[0]; tooltipLeft = ($$.width / 2) + mouse[0];
tooltipTop = ($$.height / 2) + mouse[1] + 20; tooltipTop = ($$.height / 2) + mouse[1] + 20;
} else { } else {
svgLeft = $$.getSvgLeft(true);
if (config.axis_rotated) { if (config.axis_rotated) {
svgLeft = $$.getSvgLeft();
tooltipLeft = svgLeft + mouse[0] + 100; tooltipLeft = svgLeft + mouse[0] + 100;
tooltipRight = tooltipLeft + tWidth; tooltipRight = tooltipLeft + tWidth;
chartRight = $$.getCurrentWidth() - $$.getCurrentPaddingRight(); chartRight = $$.currentWidth - $$.getCurrentPaddingRight();
tooltipTop = $$.x(dataToShow[0].x) + 20; tooltipTop = $$.x(dataToShow[0].x) + 20;
} else { } else {
svgLeft = $$.getSvgLeft(); tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;
tooltipLeft = svgLeft + $$.getCurrentPaddingLeft() + $$.x(dataToShow[0].x) + 20;
tooltipRight = tooltipLeft + tWidth; tooltipRight = tooltipLeft + tWidth;
chartRight = svgLeft + $$.getCurrentWidth() - $$.getCurrentPaddingRight(); chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();
tooltipTop = mouse[1] + 15; tooltipTop = mouse[1] + 15;
} }
if (tooltipRight > chartRight) { if (tooltipRight > chartRight) {
tooltipLeft -= tooltipRight - chartRight; tooltipLeft -= tooltipRight - chartRight;
} }
if (tooltipTop + tHeight > $$.getCurrentHeight() && tooltipTop > tHeight + 30) { if (tooltipTop + tHeight > $$.currentHeight) {
tooltipTop -= tHeight + 30; tooltipTop -= tHeight + 30;
} }
} }
if (tooltipTop < 0) {
tooltipTop = 0;
}
// Set tooltip // Set tooltip
$$.tooltip $$.tooltip
.style("top", tooltipTop + "px") .style("top", tooltipTop + "px")
......
c3_chart_internal_fn.initZoom = function () { c3_chart_internal_fn.initZoom = function () {
var $$ = this, d3 = $$.d3, config = $$.config; var $$ = this, d3 = $$.d3, config = $$.config, startEvent;
$$.zoom = d3.behavior.zoom() $$.zoom = d3.behavior.zoom()
.on("zoomstart", function () { .on("zoomstart", function () {
startEvent = d3.event.sourceEvent;
$$.zoom.altDomain = d3.event.sourceEvent.altKey ? $$.x.orgDomain() : null; $$.zoom.altDomain = d3.event.sourceEvent.altKey ? $$.x.orgDomain() : null;
config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent); config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);
}) })
...@@ -10,6 +11,11 @@ c3_chart_internal_fn.initZoom = function () { ...@@ -10,6 +11,11 @@ c3_chart_internal_fn.initZoom = function () {
$$.redrawForZoom.call($$); $$.redrawForZoom.call($$);
}) })
.on('zoomend', function () { .on('zoomend', function () {
var event = d3.event.sourceEvent;
// if click, do nothing. otherwise, click interaction will be canceled.
if (event && startEvent.x === event.x && startEvent.y === event.y) {
return;
}
$$.redrawEventRect(); $$.redrawEventRect();
$$.updateZoom(); $$.updateZoom();
config.zoom_onzoomend.call($$.api, $$.x.orgDomain()); config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
...@@ -30,8 +36,8 @@ c3_chart_internal_fn.initZoom = function () { ...@@ -30,8 +36,8 @@ c3_chart_internal_fn.initZoom = function () {
}; };
c3_chart_internal_fn.updateZoom = function () { c3_chart_internal_fn.updateZoom = function () {
var $$ = this, z = $$.config.zoom_enabled ? $$.zoom : function () {}; var $$ = this, z = $$.config.zoom_enabled ? $$.zoom : function () {};
$$.main.select('.' + CLASS.zoomRect).call(z); $$.main.select('.' + CLASS.zoomRect).call(z).on("dblclick.zoom", null);
$$.main.selectAll('.' + CLASS.eventRect).call(z); $$.main.selectAll('.' + CLASS.eventRect).call(z).on("dblclick.zoom", null);
}; };
c3_chart_internal_fn.redrawForZoom = function () { c3_chart_internal_fn.redrawForZoom = function () {
var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x; var $$ = this, d3 = $$.d3, config = $$.config, zoom = $$.zoom, x = $$.x;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment