Skip to content

Commit

Permalink
Allow charts to be created without data and labels, fixes chartist-js…
Browse files Browse the repository at this point in the history
  • Loading branch information
gionkunz committed Feb 21, 2016
1 parent a4d7ff7 commit 38ab68f
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/scripts/axes/axis.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
}

// Skip grid lines and labels where interpolated label values are falsey (execpt for 0)
if(!labelValues[index] && labelValues[index] !== 0) {
if(!Chartist.isFalseyButZero(labelValues[index]) && !labelValues[index] === '') {
return;
}

Expand Down
3 changes: 2 additions & 1 deletion src/scripts/charts/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
*
*/
function createChart(options) {
this.data = Chartist.normalizeData(this.data);
var data = {
raw: this.data,
normalized: options.distributeSeries ? Chartist.getDataArray(this.data, options.reverseData, options.horizontalBars ? 'x' : 'y').map(function(value) {
Expand All @@ -129,7 +130,7 @@
var seriesGroup = this.svg.elem('g');
var labelGroup = this.svg.elem('g').addClass(options.classNames.labelGroup);

if(options.stackBars) {
if(options.stackBars && data.normalized.length !== 0) {
// If stacked bars we need to calculate the high low from stacked values from each series
var serialSums = Chartist.serialMap(data.normalized, function serialSums() {
return Array.prototype.slice.call(arguments).map(function(value) {
Expand Down
1 change: 1 addition & 0 deletions src/scripts/charts/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
*
*/
function createChart(options) {
this.data = Chartist.normalizeData(this.data);
var data = {
raw: this.data,
normalized: Chartist.getDataArray(this.data, options.reverseData, true)
Expand Down
5 changes: 3 additions & 2 deletions src/scripts/charts/pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
* @param options
*/
function createChart(options) {
this.data = Chartist.normalizeData(this.data);
var seriesGroups = [],
labelsGroup,
chartRect,
Expand Down Expand Up @@ -166,7 +167,7 @@

// 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 - overlappigStartAngle >= 359.99) {
Expand Down Expand Up @@ -226,7 +227,7 @@
if(options.showLabel) {
// Position at the labelRadius distance from center and between start and end angle
var labelPosition = Chartist.polarToCartesian(center.x, center.y, labelRadius, startAngle + (endAngle - startAngle) / 2),
interpolatedValue = options.labelInterpolationFnc(this.data.labels ? this.data.labels[i] : dataArray[i], i);
interpolatedValue = options.labelInterpolationFnc(this.data.labels && !Chartist.isFalseyButZero(this.data.labels[i]) ? this.data.labels[i] : dataArray[i], i);

if(interpolatedValue || interpolatedValue === 0) {
var labelElement = labelsGroup.elem('text', {
Expand Down
41 changes: 40 additions & 1 deletion src/scripts/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,44 @@ var Chartist = {
return svg;
};

/**
* Ensures that the data object passed as second argument to the charts is present and correctly initialized.
*
* @param {Object} data The data object that is passed as second argument to the charts
* @return {Object} The normalized data object
*/
Chartist.normalizeData = function(data) {
// Ensure data is present otherwise enforce
data = data || {series: [], labels: []};
data.series = data.series || [];
data.labels = data.labels || [];

// Check if we should generate some labels based on existing series data
if (data.series.length > 0 && data.labels.length === 0) {
var normalized = Chartist.getDataArray(data),
labelCount;

// If all elements of the normalized data array are arrays we're dealing with
// data from Bar or Line charts and we need to find the largest series if they are un-even
if (normalized.every(function(value) {
return value instanceof Array;
})) {
// Getting the series with the the most elements
labelCount = Math.max.apply(null, normalized.map(function(series) {
return series.length;
}));
} else {
// We're dealing with Pie data so we just take the normalized array length
labelCount = normalized.length;
}

// Setting labels to an array with emptry strings using our labelCount estimated above
data.labels = Chartist.times(labelCount).map(function() {
return '';
});
}
return data;
};

/**
* Reverses the series, labels and series data arrays.
Expand Down Expand Up @@ -516,7 +554,8 @@ var Chartist = {
highLow.low = 0;
} else {
// If data array was empty, values are Number.MAX_VALUE and -Number.MAX_VALUE. Set bounds to prevent errors
highLow.high = highLow.low = 0;
highLow.high = 1;
highLow.low = 0;
}
}

Expand Down
133 changes: 133 additions & 0 deletions test/spec/spec-bar-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,137 @@ describe('Bar chart tests', function() {
});
});
});

describe('Empty data tests', function () {
it('should render empty grid with no data', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart');

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});

it('should render empty grid with only labels', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var data = {
labels: [1, 2, 3, 4]
};
var chart = new Chartist.Bar('.ct-chart', data);

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
// Find exactly as many horizontal grid lines as labels were specified (Step Axis)
expect(document.querySelectorAll('.ct-grids .ct-grid.ct-horizontal').length).toBe(data.labels.length);
done();
});
});

it('should generate labels and render empty grid with only series in data', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var data = {
series: [
[1, 2, 3, 4],
[2, 3, 4],
[3, 4]
]
};
var chart = new Chartist.Bar('.ct-chart', data);

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
// Should generate the labels using the largest series count
expect(document.querySelectorAll('.ct-grids .ct-grid.ct-horizontal').length).toBe(Math.max.apply(null, data.series.map(function(series) {
return series.length;
})));
done();
});
});

it('should render empty grid with no data and specified high low', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart', null, {
width: 400,
height: 300,
high: 100,
low: -100
});

chart.on('created', function () {
// Find first and last label
var labels = document.querySelectorAll('.ct-labels .ct-label.ct-vertical');
var firstLabel = labels[0];
var lastLabel = labels[labels.length - 1];

expect(firstLabel.textContent).toBe('-100');
expect(lastLabel.textContent).toBe('100');
done();
});
});

it('should render empty grid with no data and reverseData option', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart', null, {
reverseData: true
});

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});

it('should render empty grid with no data and stackBars option', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart', null, {
stackBars: true
});

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});

it('should render empty grid with no data and horizontalBars option', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart', null, {
horizontalBars: true
});

chart.on('created', function () {
// Find at least one vertical grid line
// TODO: In theory the axis should be created with ct-horizontal class
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});

it('should render empty grid with no data and distributeSeries option', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Bar('.ct-chart', null, {
distributeSeries: true
});

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});
});
});
90 changes: 90 additions & 0 deletions test/spec/spec-line-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,4 +313,94 @@ describe('Line chart tests', function () {
});
});
});

describe('Empty data tests', function () {
it('should render empty grid with no data', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Line('.ct-chart');

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});

it('should render empty grid with only labels', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var data = {
labels: [1, 2, 3, 4]
};
var chart = new Chartist.Line('.ct-chart', data);

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
// Find exactly as many horizontal grid lines as labels were specified (Step Axis)
expect(document.querySelectorAll('.ct-grids .ct-grid.ct-horizontal').length).toBe(data.labels.length);
done();
});
});

it('should generate labels and render empty grid with only series in data', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var data = {
series: [
[1, 2, 3, 4],
[2, 3, 4],
[3, 4]
]
};
var chart = new Chartist.Line('.ct-chart', data);

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
// Should generate the labels using the largest series count
expect(document.querySelectorAll('.ct-grids .ct-grid.ct-horizontal').length).toBe(Math.max.apply(null, data.series.map(function(series) {
return series.length;
})));
done();
});
});

it('should render empty grid with no data and specified high low', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Line('.ct-chart', null, {
width: 400,
height: 300,
high: 100,
low: -100
});

chart.on('created', function () {
// Find first and last label
var labels = document.querySelectorAll('.ct-labels .ct-label.ct-vertical');
var firstLabel = labels[0];
var lastLabel = labels[labels.length - 1];

expect(firstLabel.textContent).toBe('-100');
expect(lastLabel.textContent).toBe('100');
done();
});
});

it('should render empty grid with no data and reverseData option', function (done) {
jasmine.getFixtures().set('<div class="ct-chart ct-golden-section"></div>');

var chart = new Chartist.Line('.ct-chart', null, {
reverseData: true
});

chart.on('created', function () {
// Find at least one vertical grid line
expect(document.querySelector('.ct-grids .ct-grid.ct-vertical')).toBeDefined();
done();
});
});
});
});

0 comments on commit 38ab68f

Please sign in to comment.