Fix pie render issues with overlaps and full circle arcs.
This commit is contained in:
parent
d4fe5100ca
commit
ec00b72603
@ -158,13 +158,17 @@
|
||||
].join(' '));
|
||||
|
||||
var endAngle = startAngle + dataArray[i] / totalDataSum * 360;
|
||||
|
||||
// Use slight offset so there are no transparent hairline issues
|
||||
var overlappigStartAngle = Math.max(0, startAngle - (i === 0 || hasSingleValInSeries ? 0 : 0.2));
|
||||
|
||||
// If we need to draw the arc for all 360 degrees we need to add a hack where we close the circle
|
||||
// with Z and use 359.99 degrees
|
||||
if(endAngle - startAngle === 360) {
|
||||
endAngle -= 0.01;
|
||||
if(endAngle - overlappigStartAngle >= 359.99) {
|
||||
endAngle = overlappigStartAngle + 359.99;
|
||||
}
|
||||
|
||||
var start = Chartist.polarToCartesian(center.x, center.y, radius, startAngle),
|
||||
var start = Chartist.polarToCartesian(center.x, center.y, radius, overlappigStartAngle),
|
||||
end = Chartist.polarToCartesian(center.x, center.y, radius, endAngle);
|
||||
|
||||
// Create a new path element for the pie chart. If this isn't a donut chart we should close the path for a correct stroke
|
||||
@ -239,7 +243,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Set next startAngle to current endAngle. Use slight offset so there are no transparent hairline issues
|
||||
// Set next startAngle to current endAngle.
|
||||
// (except for last slice)
|
||||
startAngle = endAngle;
|
||||
}
|
||||
|
||||
@ -37,12 +37,14 @@ describe('Pie chart tests', function() {
|
||||
describe('Simple Pie Chart', function() {
|
||||
// https://gionkunz.github.io/chartist-js/examples.html#simple-pie-chart
|
||||
|
||||
function onCreated(callback) {
|
||||
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');
|
||||
var data = {
|
||||
var num = '\\d+(\\.\\d*)?';
|
||||
var data, options;
|
||||
|
||||
beforeEach(function() {
|
||||
data = {
|
||||
series: [5, 3, 4]
|
||||
};
|
||||
var options = {
|
||||
options = {
|
||||
width: 100,
|
||||
height: 100,
|
||||
chartPadding: 10,
|
||||
@ -50,9 +52,11 @@ describe('Pie chart tests', function() {
|
||||
return Math.round(value / data.series.reduce(sum) * 100) + '%';
|
||||
}
|
||||
};
|
||||
|
||||
var sum = function(a, b) { return a + b; };
|
||||
|
||||
});
|
||||
|
||||
function onCreated(callback) {
|
||||
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');
|
||||
var chart = new Chartist.Pie('.ct-chart', data, options);
|
||||
chart.on('created', callback);
|
||||
}
|
||||
@ -77,8 +81,6 @@ describe('Pie chart tests', function() {
|
||||
it('should create slice path', function(done) {
|
||||
onCreated(function() {
|
||||
$('.ct-slice-pie').each(function() {
|
||||
|
||||
var num = '\\d+(\\.\\d*)?';
|
||||
var pattern =
|
||||
'^M' + num + ',' + num +
|
||||
'A40,40,0,0,0,' + num + ',' + num +
|
||||
@ -99,36 +101,120 @@ describe('Pie chart tests', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should overlap slices', function(done) {
|
||||
data = {
|
||||
series: [1, 1]
|
||||
};
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
var slice2 = $('.ct-slice-pie').eq(1);
|
||||
|
||||
expect(slice1.attr('d')).toMatch(/^M50,10A40,40,0,0,0,50.\d+,90L50,50Z/);
|
||||
expect(slice2.attr('d')).toMatch(/^M50,90A40,40,0,0,0,50,10L50,50Z/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should set large arc sweep flag', function(done) {
|
||||
data = {
|
||||
series: [1, 2]
|
||||
};
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
expect(slice1.attr('d')).toMatch(/^M50,10A40,40,0,1,0/);
|
||||
done();
|
||||
}, data);
|
||||
});
|
||||
|
||||
it('should draw complete circle with gap', function(done) {
|
||||
data = {
|
||||
series: [1]
|
||||
};
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
expect(slice1.attr('d')).toMatch(/^M49.9\d+,10A40,40,0,1,0,50,10L50,50Z/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should draw complete circle with startAngle', function(done) {
|
||||
data.series = [100];
|
||||
options.startAngle = 90;
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
expect(slice1.attr('d')).toMatch(/^M90,49.9\d+A40,40,0,1,0,90,50L50,50Z/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should draw complete circle if values are 0', function(done) {
|
||||
data = {
|
||||
series: [0, 1, 0]
|
||||
};
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(1);
|
||||
expect(slice1.attr('d')).toMatch(/^M49.9\d+,10A40,40,0,1,0,50,10L50,50Z/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Pie with small ratio', function() {
|
||||
|
||||
function onCreated(callback) {
|
||||
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');
|
||||
var data = {
|
||||
describe('Pie with small slices', function() {
|
||||
var data, options;
|
||||
|
||||
beforeEach(function() {
|
||||
data = {
|
||||
series: [0.001, 2]
|
||||
};
|
||||
var options = {
|
||||
options = {
|
||||
width: 100,
|
||||
height: 100,
|
||||
chartPadding: 0,
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
function onCreated(callback) {
|
||||
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');
|
||||
var chart = new Chartist.Pie('.ct-chart', data, options);
|
||||
chart.on('created', callback);
|
||||
}
|
||||
|
||||
it('should render correctly with very small slices', function(done) {
|
||||
onCreated(function() {
|
||||
|
||||
it('Pie should render correctly with very small slices', function(done) {
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
var slice2 = $('.ct-slice-pie').eq(1);
|
||||
var slice2 = $('.ct-slice-pie').eq(1);
|
||||
|
||||
expect(slice1.attr('d')).toMatch(/^M50,0A50,50,0,1,0,50.1\d+,0/);
|
||||
expect(slice1.attr('d')).toMatch(/^M49.9\d*,0A50,50,0,1,0,50,0/);
|
||||
expect(slice2.attr('d')).toMatch(/^M50.1\d+,0A50,50,0,0,0,50,0/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Pie should render correctly with very small slices on startAngle', function(done) {
|
||||
options.startAngle = 90;
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-pie').eq(0);
|
||||
var slice2 = $('.ct-slice-pie').eq(1);
|
||||
|
||||
expect(slice1.attr('d')).toMatch(/^M100,49.97\d*A50,50,0,1,0,100,49.98\d*/);
|
||||
expect(slice2.attr('d')).toMatch(/^M100,50.1\d*A50,50,0,0,0,100,50/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Donut should render correctly with very small slices', function(done) {
|
||||
options.donut = true;
|
||||
onCreated(function() {
|
||||
var slice1 = $('.ct-slice-donut').eq(0);
|
||||
var slice2 = $('.ct-slice-donut').eq(1);
|
||||
|
||||
expect(slice1.attr('d')).toMatch(/^M49.9\d*,30A20,20,0,1,0,50,30/);
|
||||
expect(slice2.attr('d')).toMatch(/^M50.\d+,30A20,20,0,0,0,50,30/);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user