Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
robustify 'find axis' logic:
- make sure that graphs with only orphan cartesian are
  considered 'cartesian'
- make sure that axes associated with GL2D traces aren't
  considered 'cartesian'
- by making layout with { xaxis: {}, yaxis: {} } a 'hasCartesian'
  plot, deleting the last cartesian trace retains the axes.
  • Loading branch information
etpinard committed Feb 26, 2016
commit ada31b534abbca51f42296f95d4b03fd29d5aefa
83 changes: 58 additions & 25 deletions src/plots/cartesian/layout_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,36 @@ var axisIds = require('./axis_ids');


module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
// get the full list of axes already defined
var layoutKeys = Object.keys(layoutIn),
xaList = [],
yaList = [],
xaListCartesian = [],
yaListCartesian = [],
xaListGl2d = [],
yaListGl2d = [],
outerTicks = {},
noGrids = {},
i;

for(i = 0; i < layoutKeys.length; i++) {
var key = layoutKeys[i];
if(constants.xAxisMatch.test(key)) xaList.push(key);
else if(constants.yAxisMatch.test(key)) yaList.push(key);
}

// look for axes in the data
for(i = 0; i < fullData.length; i++) {
var trace = fullData[i],
xaName = axisIds.id2name(trace.xaxis),
var trace = fullData[i];
var listX, listY;

if(Plots.traceIs(trace, 'cartesian')) {
listX = xaListCartesian;
listY = yaListCartesian;
}
else if(Plots.traceIs(trace, 'gl2d')) {
listX = xaListGl2d;
listY = yaListGl2d;
}
else continue;

var xaName = axisIds.id2name(trace.xaxis),
yaName = axisIds.id2name(trace.yaxis);

// add axes implied by traces
if(xaName && xaList.indexOf(xaName) === -1) xaList.push(xaName);
if(yaName && yaList.indexOf(yaName) === -1) yaList.push(yaName);
if(xaName && listX.indexOf(xaName) === -1) listX.push(xaName);
if(yaName && listY.indexOf(yaName) === -1) listY.push(yaName);

// check for default formatting tweaks
if(Plots.traceIs(trace, '2dMap')) {
Expand All @@ -55,22 +63,47 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
}
}

function axSort(a,b) {
var aNum = Number(a.substr(5)||1),
bNum = Number(b.substr(5)||1);
return aNum - bNum;
// N.B. Ignore orphan axes (i.e. axes that have no data attached to them)
// if gl3d or geo is present on graph. This is retain backward compatible.
//
// TODO drop this in version 2.0
var ignoreOrphan = (layoutOut._hasGL3D || layoutOut._hasGeo);

if(!ignoreOrphan) {
for(i = 0; i < layoutKeys.length; i++) {
var key = layoutKeys[i];

// orphan layout axes are considered cartesian subplots

if(xaListGl2d.indexOf(key) === -1 &&
xaListCartesian.indexOf(key) === -1 &&
constants.xAxisMatch.test(key)) {
xaListCartesian.push(key);
}
else if(yaListGl2d.indexOf(key) === -1 &&
yaListCartesian.indexOf(key) === -1 &&
constants.yAxisMatch.test(key)) {
yaListCartesian.push(key);
}
}
}

if(layoutOut._hasCartesian || layoutOut._hasGL2D || !fullData.length) {
// make sure there's at least one of each and lists are sorted
if(!xaList.length) xaList = ['xaxis'];
else xaList.sort(axSort);
// make sure that plots with orphan cartesian axes
// are considered 'cartesian'
if(xaListCartesian.length && yaListCartesian.length) {
layoutOut._hasCartesian = true;
}

if(!yaList.length) yaList = ['yaxis'];
else yaList.sort(axSort);
function axSort(a, b) {
var aNum = Number(a.substr(5) || 1),
bNum = Number(b.substr(5) || 1);
return aNum - bNum;
}

xaList.concat(yaList).forEach(function(axName){
var xaList = xaListCartesian.concat(xaListGl2d).sort(axSort),
yaList = yaListCartesian.concat(yaListGl2d).sort(axSort);

xaList.concat(yaList).forEach(function(axName) {
var axLetter = axName.charAt(0),
axLayoutIn = layoutIn[axName] || {},
axLayoutOut = {},
Expand Down Expand Up @@ -100,7 +133,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {

// so we don't have to repeat autotype unnecessarily,
// copy an autotype back to layoutIn
if(!layoutIn[axName] && axLayoutIn.type!=='-') {
if(!layoutIn[axName] && axLayoutIn.type !== '-') {
layoutIn[axName] = {type: axLayoutIn.type};
}

Expand Down
74 changes: 70 additions & 4 deletions test/jasmine/tests/axes_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,12 @@ describe('Test axes', function() {
});

describe('supplyLayoutDefaults', function() {
var layoutIn = {},
layoutOut = {},
var layoutIn, layoutOut, fullData;

beforeEach(function() {
layoutOut = {};
fullData = [];
});

var supplyLayoutDefaults = Axes.supplyLayoutDefaults;

Expand All @@ -196,7 +199,7 @@ describe('Test axes', function() {

it('should set linewidth to default if linecolor is supplied and valid', function() {
layoutIn = {
xaxis: {linecolor:'black'}
xaxis: { linecolor: 'black' }
};
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut.xaxis.linecolor).toBe('black');
Expand All @@ -205,7 +208,7 @@ describe('Test axes', function() {

it('should set linecolor to default if linewidth is supplied and valid', function() {
layoutIn = {
yaxis: {linewidth:2}
yaxis: { linewidth: 2 }
};
supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut.yaxis.linewidth).toBe(2);
Expand Down Expand Up @@ -253,6 +256,69 @@ describe('Test axes', function() {
expect(layoutOut.xaxis.zerolinewidth).toBe(undefined);
expect(layoutOut.xaxis.zerolinecolor).toBe(undefined);
});

it('should detect orphan axes (lone axes case)', function() {
layoutIn = {
xaxis: {},
yaxis: {}
};
fullData = [];

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut._hasCartesian).toBe(true);
});

it('should detect orphan axes (gl2d trace conflict case)', function() {
layoutIn = {
xaxis: {},
yaxis: {}
};
fullData = [{
type: 'scattergl',
xaxis: 'x',
yaxis: 'y'
}];

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut._hasCartesian).toBe(undefined);
});

it('should detect orphan axes (gl2d + cartesian case)', function() {
layoutIn = {
xaxis2: {},
yaxis2: {}
};
fullData = [{
type: 'scattergl',
xaxis: 'x',
yaxis: 'y'
}];

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut._hasCartesian).toBe(true);
});

it('should detect orphan axes (gl3d present case)', function() {
layoutIn = {
xaxis: {},
yaxis: {}
};
layoutOut._hasGL3D = true;

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut._hasCartesian).toBe(undefined);
});

it('should detect orphan axes (gl3d present case)', function() {
layoutIn = {
xaxis: {},
yaxis: {}
};
layoutOut._hasGeo = true;

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutOut._hasCartesian).toBe(undefined);
});
});

describe('handleTickDefaults', function() {
Expand Down