Skip to content

Commit

Permalink
BUG#130702 Avoid base axis overflow by adding compensating min / max …
Browse files Browse the repository at this point in the history
…paddings in runtime
  • Loading branch information
vladminsky committed Oct 4, 2016
1 parent 62ad4cd commit d82bf32
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/elements/element.interval.js
Expand Up @@ -76,7 +76,11 @@ export class Interval extends Element {
CartesianGrammar.decorator_dynamic_size,
CartesianGrammar.decorator_color,
CartesianGrammar.decorator_label,
config.adjustPhase && enableDistributeEvenly && CartesianGrammar.decorator_size_distribute_evenly,
(config.adjustPhase && enableDistributeEvenly && CartesianGrammar.decorator_size_distribute_evenly),
(config.adjustPhase
&& enableDistributeEvenly
&& this.config.guide.prettify
&& CartesianGrammar.avoidBaseScaleOverflow),
config.adjustPhase && enableStack && CartesianGrammar.adjustYScale
].concat(config.transformModel || []);

Expand Down
57 changes: 57 additions & 0 deletions src/models/cartesian-grammar.js
Expand Up @@ -452,4 +452,61 @@ export class CartesianGrammar {
},
[]));
}

static avoidBaseScaleOverflow(model, {dataSource}) {
if (model.scaleX.discrete) {
return {};
}

var plannedMaxSize;
model.scaleSize.fixup((prev) => {
plannedMaxSize = prev.maxSize;
return prev;
});

if (plannedMaxSize <= 10) {
return {};
}

var xs = dataSource
.map((row) => model.xi(row))
.sort(((a, b) => (a - b)));

var domain = model.scaleX.domain();
var length = Math.abs(model.scaleX.value(domain[1]) - model.scaleX.value(domain[0]));
var koeff = ((domain[1] - domain[0]) / length);

var lPad = Math.abs(Math.min(0, (xs[0] - plannedMaxSize / 2)));
var rPad = Math.abs(Math.min(0, (length - (xs[xs.length - 1] + plannedMaxSize / 2))));

var lxPad = model.flip ? rPad : lPad;
var rxPad = model.flip ? lPad : rPad;

var lVal = domain[0] - (lxPad * koeff);
var rVal = domain[1] - (-1 * rxPad * koeff);

model.scaleX.fixup((prev) => {
var next = {};
if (!prev.fixed) {
next.fixed = true;
next.min = lVal;
next.max = rVal;
} else {
if (prev.min > lVal) {
next.min = lVal;
}

if (prev.max < rVal) {
next.max = rVal;
}
}

return next;
});

var linearlyScaledMaxSize = plannedMaxSize * (1 - ((lPad + rPad) / length)) - 1;
model.scaleSize.fixup(() => ({maxSize: linearlyScaledMaxSize}));

return {};
}
}
86 changes: 86 additions & 0 deletions test/grammar-rules.test.js
@@ -0,0 +1,86 @@
define(function (require) {

var expect = require('chai').expect;
var CartesianGrammar = require('src/models/cartesian-grammar').CartesianGrammar;
var SizeScale = require('src/scales/size').SizeScale;
var LinearScale = require('src/scales/linear').LinearScale;
var OrdinalScale = require('src/scales/ordinal').OrdinalScale;

describe('Grammar', function () {

var data = [
{x: 0.0, y: 0, s: 1, x_ordinal: 'A'},
{x: 0.5, y: 50, s: 0, x_ordinal: 'B'},
{x: 1.0, y: 100, s: 1, x_ordinal: 'C'}
];

var xSrc = {
part: function () {
return data;
},
full: function () {
return data;
}
};

it('should support avoidBaseScaleOverflow rule (continues scale)', function () {
var xConfig = {dim: 'x'};
var sConfig = {dim: 's', minSize: 1, maxSize: 40};
var model = {
scaleX: new LinearScale(xSrc, xConfig).create([0, 100]),
scaleSize: new SizeScale(xSrc, sConfig).create(),
xi: (row) => model.scaleX.value(row[model.scaleX.dim])
};

CartesianGrammar.avoidBaseScaleOverflow(model, {dataSource: data});

model.scaleX.commit();
model.scaleSize.commit();

expect(xConfig.min).to.equal(-0.2);
expect(xConfig.max).to.equal(1.2);
expect(sConfig.minSize).to.equal(1);
expect(sConfig.maxSize).to.equal(23);
});

it('should ignore avoidBaseScaleOverflow rule for ordinal scale', function () {
var xConfig = {dim: 'x_ordinal'};
var xConfigOriginal = JSON.stringify(xConfig);
var sConfig = {dim: 's', minSize: 1, maxSize: 40};
var sConfigOriginal = JSON.stringify(sConfig);
var model = {
scaleX: new OrdinalScale(xSrc, xConfig).create([0, 100]),
scaleSize: new SizeScale(xSrc, sConfig).create(),
xi: (row) => model.scaleX.value(row[model.scaleX.dim])
};

CartesianGrammar.avoidBaseScaleOverflow(model, {dataSource: data});

model.scaleX.commit();
model.scaleSize.commit();

expect(JSON.stringify(xConfig)).to.equal(xConfigOriginal);
expect(JSON.stringify(sConfig)).to.equal(sConfigOriginal);
});

it('should ignore avoidBaseScaleOverflow rule when max size is less than 10', function () {
var xConfig = {dim: 'x'};
var xConfigOriginal = JSON.stringify(xConfig);
var sConfig = {dim: 's', minSize: 1, maxSize: 10};
var sConfigOriginal = JSON.stringify(sConfig);
var model = {
scaleX: new LinearScale(xSrc, xConfig).create([0, 100]),
scaleSize: new SizeScale(xSrc, sConfig).create(),
xi: (row) => model.scaleX.value(row[model.scaleX.dim])
};

CartesianGrammar.avoidBaseScaleOverflow(model, {dataSource: data});

model.scaleX.commit();
model.scaleSize.commit();

expect(JSON.stringify(xConfig)).to.equal(xConfigOriginal);
expect(JSON.stringify(sConfig)).to.equal(sConfigOriginal);
});
});
});

0 comments on commit d82bf32

Please sign in to comment.