Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix axis line width, length, and positioning for coupled subplots #1854

Merged
merged 13 commits into from
Jul 14, 2017
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
107 changes: 52 additions & 55 deletions src/plot_api/subroutines.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ function overlappingDomain(xDomain, yDomain, domains) {
}

exports.lsInner = function(gd) {
var fullLayout = gd._fullLayout,
gs = fullLayout._size,
axList = Plotly.Axes.list(gd),
i;
var fullLayout = gd._fullLayout;
var gs = fullLayout._size;
var axList = Plotly.Axes.list(gd);
var i;

// clear axis line positions, to be set in the subplot loop below
for(i = 0; i < axList.length; i++) axList[i]._linepositions = {};
Expand Down Expand Up @@ -79,11 +79,9 @@ exports.lsInner = function(gd) {
return;
}

var xa = Plotly.Axes.getFromId(gd, subplot, 'x'),
ya = Plotly.Axes.getFromId(gd, subplot, 'y'),
xDomain = xa.domain,
yDomain = ya.domain,
plotgroupBgData = [];
var xDomain = plotinfo.xaxis.domain;
Copy link
Contributor

@etpinard etpinard Jul 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing. Note that references in plotinfo in are updated linkSubplots called during supplyDefaults.

var yDomain = plotinfo.yaxis.domain;
var plotgroupBgData = [];

if(overlappingDomain(xDomain, yDomain, lowerDomains)) {
plotgroupBgData = [0];
Expand Down Expand Up @@ -127,9 +125,8 @@ exports.lsInner = function(gd) {
var freefinished = [];
subplotSelection.each(function(subplot) {
var plotinfo = fullLayout._plots[subplot];

var xa = Plotly.Axes.getFromId(gd, subplot, 'x'),
ya = Plotly.Axes.getFromId(gd, subplot, 'y');
var xa = plotinfo.xaxis;
var ya = plotinfo.yaxis;

// reset scale in case the margins have changed
xa.setScale();
Expand Down Expand Up @@ -168,46 +165,46 @@ exports.lsInner = function(gd) {
plotinfo.plot.call(Drawing.setTranslate, xa._offset, ya._offset);
plotinfo.plot.call(Drawing.setClipUrl, plotinfo.clipId);

var xlw = Drawing.crispRound(gd, xa.linewidth, 1),
ylw = Drawing.crispRound(gd, ya.linewidth, 1),
xp = gs.p + ylw,
xpathPrefix = 'M' + (-xp) + ',',
xpathSuffix = 'h' + (xa._length + 2 * xp),
showfreex = xa.anchor === 'free' &&
freefinished.indexOf(xa._id) === -1,
freeposx = gs.h * (1 - (xa.position||0)) + ((xlw / 2) % 1),
showbottom =
(xa.anchor === ya._id && (xa.mirror || xa.side !== 'top')) ||
xa.mirror === 'all' || xa.mirror === 'allticks' ||
(xa.mirrors && xa.mirrors[ya._id + 'bottom']),
bottompos = ya._length + gs.p + xlw / 2,
showtop =
(xa.anchor === ya._id && (xa.mirror || xa.side === 'top')) ||
xa.mirror === 'all' || xa.mirror === 'allticks' ||
(xa.mirrors && xa.mirrors[ya._id + 'top']),
toppos = -gs.p - xlw / 2,

// shorten y axis lines so they don't overlap x axis lines
yp = gs.p,
// except where there's no x line
// TODO: this gets more complicated with multiple x and y axes
ypbottom = showbottom ? 0 : xlw,
yptop = showtop ? 0 : xlw,
ypathSuffix = ',' + (-yp - yptop) +
'v' + (ya._length + 2 * yp + yptop + ypbottom),
showfreey = ya.anchor === 'free' &&
freefinished.indexOf(ya._id) === -1,
freeposy = gs.w * (ya.position||0) + ((ylw / 2) % 1),
showleft =
(ya.anchor === xa._id && (ya.mirror || ya.side !== 'right')) ||
ya.mirror === 'all' || ya.mirror === 'allticks' ||
(ya.mirrors && ya.mirrors[xa._id + 'left']),
leftpos = -gs.p - ylw / 2,
showright =
(ya.anchor === xa._id && (ya.mirror || ya.side === 'right')) ||
ya.mirror === 'all' || ya.mirror === 'allticks' ||
(ya.mirrors && ya.mirrors[xa._id + 'right']),
rightpos = xa._length + gs.p + ylw / 2;
var xlw = Drawing.crispRound(gd, xa.linewidth, 1);
var ylw = Drawing.crispRound(gd, ya.linewidth, 1);
var xp = gs.p + ylw;
var xpathPrefix = 'M' + (-xp) + ',';
var xpathSuffix = 'h' + (xa._length + 2 * xp);
var showfreex = xa.anchor === 'free' &&
freefinished.indexOf(xa._id) === -1;
var freeposx = gs.h * (1 - (xa.position||0)) + ((xlw / 2) % 1);
var showbottom =
(xa.anchor === ya._id && (xa.mirror || xa.side !== 'top')) ||
xa.mirror === 'all' || xa.mirror === 'allticks' ||
(xa.mirrors && xa.mirrors[ya._id + 'bottom']);
var bottompos = ya._length + gs.p + xlw / 2;
var showtop =
(xa.anchor === ya._id && (xa.mirror || xa.side === 'top')) ||
xa.mirror === 'all' || xa.mirror === 'allticks' ||
(xa.mirrors && xa.mirrors[ya._id + 'top']);
var toppos = -gs.p - xlw / 2;

// shorten y axis lines so they don't overlap x axis lines
var yp = gs.p;
// except where there's no x line
// TODO: this gets more complicated with multiple x and y axes
var ypbottom = showbottom ? 0 : xlw;
var yptop = showtop ? 0 : xlw;
var ypathSuffix = ',' + (-yp - yptop) +
'v' + (ya._length + 2 * yp + yptop + ypbottom);
var showfreey = ya.anchor === 'free' &&
freefinished.indexOf(ya._id) === -1;
var freeposy = gs.w * (ya.position||0) + ((ylw / 2) % 1);
var showleft =
(ya.anchor === xa._id && (ya.mirror || ya.side !== 'right')) ||
ya.mirror === 'all' || ya.mirror === 'allticks' ||
(ya.mirrors && ya.mirrors[xa._id + 'left']);
var leftpos = -gs.p - ylw / 2;
var showright =
(ya.anchor === xa._id && (ya.mirror || ya.side === 'right')) ||
ya.mirror === 'all' || ya.mirror === 'allticks' ||
(ya.mirrors && ya.mirrors[xa._id + 'right']);
var rightpos = xa._length + gs.p + ylw / 2;

// save axis line positions for ticks, draggers, etc to reference
// each subplot gets an entry:
Expand Down Expand Up @@ -241,9 +238,9 @@ exports.lsInner = function(gd) {

// translate all the extra stuff to have the
// same origin as the plot area or axes
var origin = 'translate(' + xa._offset + ',' + ya._offset + ')',
originx = origin,
originy = origin;
var origin = 'translate(' + xa._offset + ',' + ya._offset + ')';
var originx = origin;
var originy = origin;
if(showfreex) {
originx = 'translate(' + xa._offset + ',' + gs.t + ')';
toppos += ya._offset - gs.t;
Expand Down
25 changes: 17 additions & 8 deletions test/image/mocks/20.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@
],
"showline": true,
"ticks": "outside",
"mirror": true
"mirror": true,
"linecolor": "rgba(0,0,0,0.5)",
"linewidth": 10
},
"yaxis": {
"title": "yaxis title",
Expand All @@ -112,7 +114,8 @@
"tickfont": {
"color": "#1f77b4"
},
"linecolor": "#1f77b4"
"linecolor": "rgba(31,119,180,0.5)",
"linewidth": 20
},
"legend": {
"x": 1.1,
Expand All @@ -131,7 +134,8 @@
"tickfont": {
"color": "#ff7f0e"
},
"linecolor": "#ff7f0e",
"linecolor": "rgba(255,127,14,0.4)",
"linewidth": 6,
"anchor": "free",
"position": 0.15,
"overlaying": "y"
Expand All @@ -147,7 +151,7 @@
"tickfont": {
"color": "#2ca02c"
},
"linecolor": "#2ca02c",
"linecolor": "rgba(44,160,44,0.5)",
"anchor": "free",
"position": 0,
"overlaying": "y"
Expand All @@ -164,7 +168,8 @@
"color": "#d62728"
},
"showexponent": "last",
"linecolor": "#d62728",
"linecolor": "rgba(214,39,40,0.5)",
"linewidth": 15,
"side": "right",
"overlaying": "y"
},
Expand All @@ -181,7 +186,8 @@
},
"exponentformat": "power",
"showexponent": "first",
"linecolor": "#9467bd",
"linecolor": "rgba(148,103,189,0.5)",
"linewidth": 5,
"anchor": "free",
"side": "right",
"position": 0.85,
Expand All @@ -199,11 +205,14 @@
"color": "#8c564b"
},
"exponentformat": "SI",
"linecolor": "#8c564b",
"linecolor": "rgba(140,86,75,0.5)",
"anchor": "free",
"side": "right",
"position": 1,
"overlaying": "y"
}
},
"width": 750,
"height": 400,
"margin": {"r": 200, "l": 50, "t": 50, "b": 50}
}
}