Skip to content

Commit 472225f

Browse files
committed
implement layer: 'below traces' for ternary axes
- to do so, rm <g axlines> and construct plot-layer data based on ax.layer - make sure layer order is updated on ternary.plot using selection.order() - grab layer ref from `this.layers` when possible, to undo useless querySelector calls.
1 parent cb2d3d1 commit 472225f

File tree

3 files changed

+67
-37
lines changed

3 files changed

+67
-37
lines changed

src/plots/ternary/layout/axis_attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ module.exports = {
4747
showgrid: extendFlat({}, axesAttrs.showgrid, {dflt: true}),
4848
gridcolor: axesAttrs.gridcolor,
4949
gridwidth: axesAttrs.gridwidth,
50+
layer: axesAttrs.layer,
5051
// range
5152
min: {
5253
valType: 'number',

src/plots/ternary/layout/axis_defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,6 @@ module.exports = function supplyLayoutDefaults(containerIn, containerOut, option
7979
coerce('gridcolor', colorMix(dfltColor, options.bgColor, 60).toRgbString());
8080
coerce('gridwidth');
8181
}
82+
83+
coerce('layer');
8284
};

src/plots/ternary/ternary.js

+64-37
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function Ternary(options, fullLayout) {
3131
this.id = options.id;
3232
this.graphDiv = options.graphDiv;
3333
this.init(fullLayout);
34-
this.makeFramework();
34+
this.makeFramework(fullLayout);
3535
}
3636

3737
module.exports = Ternary;
@@ -43,6 +43,7 @@ proto.init = function(fullLayout) {
4343
this.defs = fullLayout._defs;
4444
this.layoutId = fullLayout._uid;
4545
this.traceHash = {};
46+
this.layers = {};
4647
};
4748

4849
proto.plot = function(ternaryCalcData, fullLayout) {
@@ -60,15 +61,15 @@ proto.plot = function(ternaryCalcData, fullLayout) {
6061
}
6162
}
6263

64+
_this.updateLayers(ternaryLayout);
6365
_this.adjustLayout(ternaryLayout, graphSize);
64-
6566
Plots.generalUpdatePerTraceModule(_this, ternaryCalcData, ternaryLayout);
66-
6767
_this.layers.plotbg.select('path').call(Color.fill, ternaryLayout.bgcolor);
6868
};
6969

70-
proto.makeFramework = function() {
70+
proto.makeFramework = function(fullLayout) {
7171
var _this = this;
72+
var ternaryLayout = fullLayout[_this.id];
7273

7374
var defGroup = _this.defs.selectAll('g.clips')
7475
.data([0]);
@@ -95,50 +96,75 @@ proto.makeFramework = function() {
9596
_this.plotContainer.enter().append('g')
9697
.classed(_this.id, true);
9798

98-
_this.layers = {};
99+
_this.updateLayers(ternaryLayout);
100+
101+
Drawing.setClipUrl(_this.layers.backplot, clipId);
102+
Drawing.setClipUrl(_this.layers.grids, clipId);
103+
};
104+
105+
proto.updateLayers = function(ternaryLayout) {
106+
var _this = this;
107+
var layers = _this.layers;
99108

100109
// inside that container, we have one container for the data, and
101110
// one each for the three axes around it.
102-
var plotLayers = [
103-
'draglayer',
104-
'plotbg',
105-
'backplot',
106-
'grids',
107-
'frontplot',
108-
'aaxis', 'baxis', 'caxis', 'axlines'
109-
];
111+
112+
var plotLayers = ['draglayer', 'plotbg', 'backplot', 'grids'];
113+
114+
if(ternaryLayout.aaxis.layer === 'below traces') {
115+
plotLayers.push('aaxis', 'aline');
116+
}
117+
if(ternaryLayout.baxis.layer === 'below traces') {
118+
plotLayers.push('baxis', 'bline');
119+
}
120+
if(ternaryLayout.caxis.layer === 'below traces') {
121+
plotLayers.push('caxis', 'cline');
122+
}
123+
124+
plotLayers.push('frontplot');
125+
126+
if(ternaryLayout.aaxis.layer === 'above traces') {
127+
plotLayers.push('aaxis', 'aline');
128+
}
129+
if(ternaryLayout.baxis.layer === 'above traces') {
130+
plotLayers.push('baxis', 'bline');
131+
}
132+
if(ternaryLayout.caxis.layer === 'above traces') {
133+
plotLayers.push('caxis', 'cline');
134+
}
135+
110136
var toplevel = _this.plotContainer.selectAll('g.toplevel')
111-
.data(plotLayers);
137+
.data(plotLayers, String);
138+
139+
var grids = ['agrid', 'bgrid', 'cgrid'];
140+
112141
toplevel.enter().append('g')
113142
.attr('class', function(d) { return 'toplevel ' + d; })
114143
.each(function(d) {
115144
var s = d3.select(this);
116-
_this.layers[d] = s;
145+
layers[d] = s;
117146

118147
// containers for different trace types.
119148
// NOTE - this is different from cartesian, where all traces
120149
// are in front of grids. Here I'm putting maps behind the grids
121150
// so the grids will always be visible if they're requested.
122151
// Perhaps we want that for cartesian too?
123-
if(d === 'frontplot') s.append('g').classed('scatterlayer', true);
124-
else if(d === 'backplot') s.append('g').classed('maplayer', true);
125-
else if(d === 'plotbg') s.append('path').attr('d', 'M0,0Z');
126-
else if(d === 'axlines') {
127-
s.selectAll('path').data(['aline', 'bline', 'cline'])
128-
.enter().append('path').each(function(d) {
129-
d3.select(this).classed(d, true);
130-
});
152+
if(d === 'frontplot') {
153+
s.append('g').classed('scatterlayer', true);
154+
} else if(d === 'backplot') {
155+
s.append('g').classed('maplayer', true);
156+
} else if(d === 'plotbg') {
157+
s.append('path').attr('d', 'M0,0Z');
158+
} else if(d === 'aline' || d === 'bline' || d === 'cline') {
159+
s.append('path');
160+
} else if(d === 'grids') {
161+
grids.forEach(function(d) {
162+
layers[d] = s.append('g').classed('grid ' + d, true);
163+
});
131164
}
132165
});
133166

134-
var grids = _this.plotContainer.select('.grids').selectAll('g.grid')
135-
.data(['agrid', 'bgrid', 'cgrid']);
136-
grids.enter().append('g')
137-
.attr('class', function(d) { return 'grid ' + d; })
138-
.each(function(d) { _this.layers[d] = d3.select(this); });
139-
140-
_this.plotContainer.selectAll('.backplot,.grids')
141-
.call(Drawing.setClipUrl, clipId);
167+
toplevel.order();
142168
};
143169

144170
var w_over_h = Math.sqrt(4 / 3);
@@ -315,18 +341,17 @@ proto.adjustLayout = function(ternaryLayout, graphSize) {
315341
// make these counterproductive.
316342
_this.plotContainer.selectAll('.crisp').classed('crisp', false);
317343

318-
var axlines = _this.layers.axlines;
319-
axlines.select('.aline')
344+
_this.layers.aline.select('path')
320345
.attr('d', aaxis.showline ?
321346
'M' + x0 + ',' + (y0 + h) + 'l' + (w / 2) + ',-' + h : 'M0,0')
322347
.call(Color.stroke, aaxis.linecolor || '#000')
323348
.style('stroke-width', (aaxis.linewidth || 0) + 'px');
324-
axlines.select('.bline')
349+
_this.layers.bline.select('path')
325350
.attr('d', baxis.showline ?
326351
'M' + x0 + ',' + (y0 + h) + 'h' + w : 'M0,0')
327352
.call(Color.stroke, baxis.linecolor || '#000')
328353
.style('stroke-width', (baxis.linewidth || 0) + 'px');
329-
axlines.select('.cline')
354+
_this.layers.cline.select('path')
330355
.attr('d', caxis.showline ?
331356
'M' + (x0 + w / 2) + ',' + y0 + 'l' + (w / 2) + ',' + h : 'M0,0')
332357
.call(Color.stroke, caxis.linecolor || '#000')
@@ -336,8 +361,10 @@ proto.adjustLayout = function(ternaryLayout, graphSize) {
336361
_this.initInteractions();
337362
}
338363

339-
_this.plotContainer.select('.frontplot')
340-
.call(Drawing.setClipUrl, _this._hasClipOnAxisFalse ? null : _this.clipId);
364+
Drawing.setClipUrl(
365+
_this.layers.frontplot,
366+
_this._hasClipOnAxisFalse ? null : _this.clipId
367+
);
341368
};
342369

343370
proto.drawAxes = function(doTitles) {

0 commit comments

Comments
 (0)