Permalink
Browse files

added options and test for axis min/max values

  • Loading branch information...
1 parent 1df707b commit 178a1474149adeb8c2d8450b2bbdf5da816edcf7 @paularmstrong paularmstrong committed Dec 14, 2012
Showing with 114 additions and 55 deletions.
  1. +6 −0 lib/chart.js
  2. +48 −37 lib/scales.js
  3. +5 −1 test/chart.test.js
  4. +55 −17 test/scales.test.js
View
@@ -23,6 +23,12 @@ var emptyData = [[]],
tickHintY: 10,
tickFormatY: function (y) { return y; },
+ // Min/Max Axis Values
+ xMin: null,
+ xMax: null,
+ yMin: null,
+ yMax: null,
+
// Pre-format input data
dataFormatX: function (x) { return x; },
dataFormatY: function (y) { return y; },
View
@@ -14,27 +14,6 @@ function _getDomain(data, axis) {
.sort(d3.ascending);
}
-function _extendDomain(domain, axis) {
- var min = domain[0],
- max = domain[1],
- diff,
- e;
-
- if (min === max) {
- e = Math.max(Math.round(min / 10), 4);
- min -= e;
- max += e;
- }
-
- diff = max - min;
- min = (min) ? min - (diff / 10) : min;
- min = (domain[0] > 0) ? Math.max(min, 0) : min;
- max = (max) ? max + (diff / 10) : max;
- max = (domain[1] < 0) ? Math.min(max, 0) : max;
-
- return [min, max];
-}
-
function ordinal(data, axis, bounds, spacing) {
spacing = spacing || defaultSpacing;
var domain = _getDomain(data, axis);
@@ -44,21 +23,13 @@ function ordinal(data, axis, bounds, spacing) {
}
function linear(extents, bounds, axis) {
- if (axis === 'y') {
- extents = _extendDomain(extents, axis);
- }
-
return d3.scale.linear()
.domain(extents)
.nice()
.rangeRound(bounds);
}
function exponential(extents, bounds, axis) {
- if (axis === 'y') {
- extents = _extendDomain(extents, axis);
- }
-
return d3.scale.pow()
.exponent(0.65)
.domain(extents)
@@ -72,22 +43,61 @@ function time(extents, bounds) {
.range(bounds);
}
-function _getExtents(data, key) {
- var nData = _.chain(data)
- .pluck('data')
- .flatten()
- .value();
+function _extendDomain(domain, axis) {
+ var min = domain[0],
+ max = domain[1],
+ diff,
+ e;
+
+ if (min === max) {
+ e = Math.max(Math.round(min / 10), 4);
+ min -= e;
+ max += e;
+ }
- return {
+ diff = max - min;
+ min = (min) ? min - (diff / 10) : min;
+ min = (domain[0] > 0) ? Math.max(min, 0) : min;
+ max = (max) ? max + (diff / 10) : max;
+ max = (domain[1] < 0) ? Math.min(max, 0) : max;
+
+ return [min, max];
+}
+
+function _getExtents(options, data, xType, yType) {
+ var extents,
+ nData = _.chain(data)
+ .pluck('data')
+ .flatten()
+ .value();
+
+ extents = {
x: d3.extent(nData, function (d) { return d.x; }),
y: d3.extent(nData, function (d) { return d.y; })
};
+
+ _.each([xType, yType], function (type, i) {
+ var axis = (i) ? 'y' : 'x',
+ extended;
+ extents[axis] = d3.extent(nData, function (d) { return d[axis]; });
+ extended = _extendDomain(extents[axis]);
+ if (type === 'ordinal') {
+ return;
+ }
+ _.each([axis + 'Min', axis + 'Max'], function (minMax, i) {
+ extents[axis][i] = (options.hasOwnProperty(minMax) &&
+ options[minMax] !== null) ? options[minMax] : extended[i];
+ });
+ });
+
+ return extents;
}
function xy(self, data, xType, yType) {
- var extents = _getExtents(data),
+ var o = self._options,
+ extents = _getExtents(o, data, xType, yType),
+ extendedExtents = _extendDomain(extents),
scales = {},
- o = self._options,
horiz = [o.axisPaddingLeft, self._width],
vert = [self._height, o.axisPaddingTop],
xScale,
@@ -101,6 +111,7 @@ function xy(self, data, xType, yType) {
scales[axis] = ordinal(data, axis, bounds);
break;
case 'linear':
+
scales[axis] = linear(extents[axis], bounds, axis);
break;
case 'exponential':
View
@@ -61,7 +61,11 @@
tickHintX: 10,
tickHintY: 10,
timing: 750,
- interpolation: 'monotone'
+ interpolation: 'monotone',
+ xMin: null,
+ xMax: null,
+ yMin: null,
+ yMax: null
});
});
View
@@ -44,17 +44,10 @@
describe('Linear', function () {
it('returns a linear scale', function () {
- var s = scales.linear([10, 50], [0, 100], 'y');
+ var s = scales.linear([0, 60], [0, 100], 'y');
_testLinear(s);
});
- it('extends the domain if only 1 value', function () {
- var s = scales.linear([10, 10], [0, 100], 'y');
- expect(s.domain()).to.be.eql([5, 15]);
- s = scales.linear([100, 100], [0, 100], 'y');
- expect(s.domain()).to.be.eql([88, 112], 'uses scaled padding');
- });
-
it('does not round values', function () {
var s = scales.linear([1.1, 2.1], [0, 100], 'x');
expect(s(1.4)).to.not.equal(s(1.1));
@@ -65,9 +58,9 @@
describe('Exponential', function () {
it('returns an exponential scale', function () {
var s = scales.exponential([0, 500], [0, 100], 'y');
- expect(s(10)).to.be.eql(7); // would be 2 on linear
- expect(s(100)).to.be.eql(31); // would be 20 on linear
- expect(s(400)).to.be.eql(77); // would be 80 on linear
+ expect(s(10)).to.be.eql(8); // would be 2 on linear
+ expect(s(100)).to.be.eql(35); // would be 20 on linear
+ expect(s(400)).to.be.eql(86); // would be 80 on linear
});
});
@@ -78,17 +71,62 @@
describe('xy', function () {
it('returns multiple types', function () {
var foo = {
- _options: {
- axisPaddingLeft: 0,
- axisPaddingRight: 0
+ _options: {
+ axisPaddingLeft: 0,
+ axisPaddingRight: 0
+ },
+ _width: 100,
+ _height: 100
},
- _width: 100,
- _height: 100
- },
s = scales.xy(foo, data, 'ordinal', 'linear');
+ window.a = s;
_testOrdinal(s.x);
_testLinear(s.y);
});
+
+ it('uses xMin, xMax, yMin, and yMax in options', function () {
+ var foo = {
+ _options: {
+ xMin: -1,
+ xMax: 20,
+ yMin: 10,
+ yMax: 40
+ },
+ _width: 100,
+ _height: 100
+ },
+ data = [
+ { data: [ { x: 1, y: 50 }, { x: 1, y: 20 } ] },
+ { data: [ { x: 2, y: 50 }, { x: 2, y: 10 } ] }
+ ],
+ sOrdinal,
+ sLinear,
+ sTime;
+
+ sOrdinal = scales.xy(foo, data, 'ordinal', 'ordinal');
+ expect(sOrdinal.x.domain()).to.eql([1, 2]);
+ expect(sOrdinal.y.domain()).to.eql([10, 20, 50]);
+
+ sLinear = scales.xy(foo, data, 'linear', 'linear');
+ expect(sLinear.x.domain()).to.eql([foo._options.xMin, foo._options.xMax]);
+ expect(sLinear.y.domain()).to.eql([foo._options.yMin, foo._options.yMax]);
+
+ foo._options = {
+ xMin: new Date(2012, 1, 1),
+ xMax: new Date(2012, 10, 1),
+ yMin: new Date(2012, 2, 1),
+ yMax: new Date(2012, 11, 1)
+ };
+ data = [
+ { data: [ { x: new Date(), y: new Date() },
+ { x: new Date(), y: new Date() } ] },
+ { data: [ { x: new Date(), y: new Date() },
+ { x: new Date(), y: new Date() } ] }
+ ];
+ sTime = scales.xy(foo, data, 'time', 'time');
+ expect(sTime.x.domain()).to.eql([foo._options.xMin, foo._options.xMax]);
+ expect(sTime.y.domain()).to.eql([foo._options.yMin, foo._options.yMax]);
+ });
});
}());

0 comments on commit 178a147

Please sign in to comment.