Skip to content

Commit 6a6f7da

Browse files
committed
fix the title side for odd cheaterslope situations
1 parent 2db8707 commit 6a6f7da

File tree

3 files changed

+264
-12
lines changed

3 files changed

+264
-12
lines changed

src/traces/carpet/plot.js

+33-12
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var map1dArray = require('./map_1d_array');
1515
var makepath = require('./makepath');
1616
var orientText = require('./orient_text');
1717
var svgTextUtils = require('../../lib/svg_text_utils');
18+
var alignmentConstants = require('../../constants/alignment');
1819

1920
module.exports = function plot(gd, plotinfo, cdcarpet) {
2021
for(var i = 0; i < cdcarpet.length; i++) {
@@ -58,10 +59,10 @@ function plotOne(gd, plotinfo, cd) {
5859
drawGridLines(xa, ya, boundaryLayer, aax, 'a-boundary', aax._boundarylines);
5960
drawGridLines(xa, ya, boundaryLayer, bax, 'b-boundary', bax._boundarylines);
6061

61-
var maxAExtent = drawAxisLabels(gd, xa, ya, trace, t, labelLayer, aax._labels, 'a-label');
62-
var maxBExtent = drawAxisLabels(gd, xa, ya, trace, t, labelLayer, bax._labels, 'b-label');
62+
var labelOrientationA = drawAxisLabels(gd, xa, ya, trace, t, labelLayer, aax._labels, 'a-label');
63+
var labelOrientationB = drawAxisLabels(gd, xa, ya, trace, t, labelLayer, bax._labels, 'b-label');
6364

64-
drawAxisTitles(gd, labelLayer, trace, t, xa, ya, maxAExtent, maxBExtent);
65+
drawAxisTitles(gd, labelLayer, trace, t, xa, ya, labelOrientationA, labelOrientationB);
6566

6667
drawClipPath(trace, t, clipLayer, xa, ya);
6768
}
@@ -131,8 +132,9 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
131132
.classed(labelClass, true);
132133

133134
var maxExtent = 0;
135+
var labelOrientation;
134136

135-
labelJoin.each(function(label) {
137+
labelJoin.each(function(label, i) {
136138
// Most of the positioning is done in calc_labels. Only the parts that depend upon
137139
// the screen space representation of the x and y axes are here:
138140
var orientation;
@@ -142,6 +144,11 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
142144
var angle = (label.axis.tickangle + 180.0) * Math.PI / 180.0;
143145
orientation = orientText(trace, xaxis, yaxis, label.xy, [Math.cos(angle), Math.sin(angle)]);
144146
}
147+
148+
if(!i) {
149+
// TODO: offsetMultiplier? Not currently used anywhere...
150+
labelOrientation = {angle: orientation.angle, flip: orientation.flip};
151+
}
145152
var direction = (label.endAnchor ? -1 : 1) * orientation.flip;
146153

147154
var labelEl = d3.select(this)
@@ -169,29 +176,34 @@ function drawAxisLabels(gd, xaxis, yaxis, trace, t, layer, labels, labelClass) {
169176

170177
labelJoin.exit().remove();
171178

172-
return maxExtent;
179+
labelOrientation.maxExtent = maxExtent;
180+
return labelOrientation;
173181
}
174182

175-
function drawAxisTitles(gd, layer, trace, t, xa, ya, maxAExtent, maxBExtent) {
183+
function drawAxisTitles(gd, layer, trace, t, xa, ya, labelOrientationA, labelOrientationB) {
176184
var a, b, xy, dxy;
177185

178186
a = 0.5 * (trace.a[0] + trace.a[trace.a.length - 1]);
179187
b = trace.b[0];
180188
xy = trace.ab2xy(a, b, true);
181189
dxy = trace.dxyda_rough(a, b);
182-
drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.aaxis, xa, ya, maxAExtent, 'a-title');
190+
drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.aaxis, xa, ya, labelOrientationA, 'a-title');
183191

184192
a = trace.a[0];
185193
b = 0.5 * (trace.b[0] + trace.b[trace.b.length - 1]);
186194
xy = trace.ab2xy(a, b, true);
187195
dxy = trace.dxydb_rough(a, b);
188-
drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.baxis, xa, ya, maxBExtent, 'b-title');
196+
drawAxisTitle(gd, layer, trace, t, xy, dxy, trace.baxis, xa, ya, labelOrientationB, 'b-title');
189197
}
190198

191-
function drawAxisTitle(gd, layer, trace, t, xy, dxy, axis, xa, ya, offset, labelClass) {
199+
var lineSpacing = alignmentConstants.LINE_SPACING;
200+
var midShift = ((1 - alignmentConstants.MID_SHIFT) / lineSpacing) + 1;
201+
202+
function drawAxisTitle(gd, layer, trace, t, xy, dxy, axis, xa, ya, labelOrientation, labelClass) {
192203
var data = [];
193204
if(axis.title) data.push(axis.title);
194205
var titleJoin = layer.selectAll('text.' + labelClass).data(data);
206+
var offset = labelOrientation.maxExtent;
195207

196208
titleJoin.enter().append('text')
197209
.classed(labelClass, true);
@@ -205,14 +217,23 @@ function drawAxisTitle(gd, layer, trace, t, xy, dxy, axis, xa, ya, offset, label
205217
}
206218

207219
// In addition to the size of the labels, add on some extra padding:
208-
offset += axis.titlefont.size + axis.titleoffset;
220+
var titleSize = axis.titlefont.size;
221+
offset += titleSize + axis.titleoffset;
209222

223+
var labelNorm = labelOrientation.angle + (labelOrientation.flip < 0 ? 180 : 0);
224+
var angleDiff = (labelNorm - orientation.angle + 450) % 360;
225+
var reverseTitle = angleDiff > 90 && angleDiff < 270;
210226

211227
var el = d3.select(this);
212228

213229
el.text(axis.title || '')
214-
.call(svgTextUtils.convertToTspans, gd)
215-
.attr('transform',
230+
.call(svgTextUtils.convertToTspans, gd);
231+
232+
if(reverseTitle) {
233+
offset = (-svgTextUtils.lineCount(el) + midShift) * lineSpacing * titleSize - offset;
234+
}
235+
236+
el.attr('transform',
216237
'translate(' + orientation.p[0] + ',' + orientation.p[1] + ') ' +
217238
'rotate(' + orientation.angle + ') ' +
218239
'translate(0,' + offset + ')'

test/image/baselines/cheaterslope.png

87.2 KB
Loading

test/image/mocks/cheaterslope.json

+231
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
{
2+
"data": [
3+
{
4+
"type": "carpet",
5+
"carpet": "c1",
6+
"a": [1, 2, 3],
7+
"b": [1, 2, 3],
8+
"y": [[0, 0.8, 2], [1.2, 2, 3.2], [2, 2.8, 4]],
9+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
10+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
11+
"xaxis": "x",
12+
"yaxis": "y",
13+
"cheaterslope": -10
14+
},
15+
{
16+
"type": "carpet",
17+
"carpet": "c2",
18+
"a": [1, 2, 3],
19+
"b": [1, 2, 3],
20+
"y": [[0.8, 0, 2], [2, 1.2, 3.2], [2.8, 2, 4]],
21+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
22+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
23+
"xaxis": "x2",
24+
"yaxis": "y",
25+
"cheaterslope": -10
26+
},
27+
{
28+
"type": "carpet",
29+
"carpet": "c3",
30+
"a": [1, 2, 3],
31+
"b": [1, 2, 3],
32+
"y": [[0, 0.8, 2], [1.2, 2, 3.2], [2, 2.8, 4]],
33+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
34+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
35+
"xaxis": "x",
36+
"yaxis": "y2",
37+
"cheaterslope": -0.3
38+
},
39+
{
40+
"type": "carpet",
41+
"carpet": "c4",
42+
"a": [1, 2, 3],
43+
"b": [1, 2, 3],
44+
"y": [[0.8, 0, 2], [2, 1.2, 3.2], [2.8, 2, 4]],
45+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
46+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
47+
"xaxis": "x2",
48+
"yaxis": "y2",
49+
"cheaterslope": -0.3
50+
},
51+
{
52+
"type": "carpet",
53+
"carpet": "c5",
54+
"a": [1, 2, 3],
55+
"b": [1, 2, 3],
56+
"y": [[0, 0.8, 2], [1.2, 2, 3.2], [2, 2.8, 4]],
57+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
58+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
59+
"xaxis": "x",
60+
"yaxis": "y3",
61+
"cheaterslope": 0
62+
},
63+
{
64+
"type": "carpet",
65+
"carpet": "c6",
66+
"a": [1, 2, 3],
67+
"b": [1, 2, 3],
68+
"y": [[0.8, 0, 2], [2, 1.2, 3.2], [2.8, 2, 4]],
69+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
70+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
71+
"xaxis": "x2",
72+
"yaxis": "y3",
73+
"cheaterslope": 0
74+
},
75+
{
76+
"type": "carpet",
77+
"carpet": "c7",
78+
"a": [1, 2, 3],
79+
"b": [1, 2, 3],
80+
"y": [[0, 0.8, 2], [1.2, 2, 3.2], [2, 2.8, 4]],
81+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
82+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
83+
"xaxis": "x",
84+
"yaxis": "y4",
85+
"cheaterslope": 0.3
86+
},
87+
{
88+
"type": "carpet",
89+
"carpet": "c8",
90+
"a": [1, 2, 3],
91+
"b": [1, 2, 3],
92+
"y": [[0.8, 0, 2], [2, 1.2, 3.2], [2.8, 2, 4]],
93+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
94+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
95+
"xaxis": "x2",
96+
"yaxis": "y4",
97+
"cheaterslope": 0.3
98+
},
99+
{
100+
"type": "carpet",
101+
"carpet": "c9",
102+
"a": [1, 2, 3],
103+
"b": [1, 2, 3],
104+
"y": [[0, 0.8, 2], [1.2, 2, 3.2], [2, 2.8, 4]],
105+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
106+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
107+
"xaxis": "x",
108+
"yaxis": "y5",
109+
"cheaterslope": 10
110+
},
111+
{
112+
"type": "carpet",
113+
"carpet": "c10",
114+
"a": [1, 2, 3],
115+
"b": [1, 2, 3],
116+
"y": [[0.8, 0, 2], [2, 1.2, 3.2], [2.8, 2, 4]],
117+
"aaxis": {"smoothing": 1, "title": "A axis<br>title", "color": "red"},
118+
"baxis": {"smoothing": 1, "title": "B axis<br>title"},
119+
"xaxis": "x2",
120+
"yaxis": "y5",
121+
"cheaterslope": 10
122+
}
123+
],
124+
"layout": {
125+
"title": "Cheaterslope with titles",
126+
"width": 600,
127+
"height": 800,
128+
"dragmode": "pan",
129+
"margin": {
130+
"t": 60,
131+
"r": 30,
132+
"b": 30,
133+
"l": 30
134+
},
135+
"yaxis": {
136+
"domain": [0, 0.19],
137+
"zeroline": false,
138+
"range": [-2, 5]
139+
},
140+
"yaxis2": {
141+
"domain": [0.21, 0.39],
142+
"zeroline": false,
143+
"range": [-2, 5]
144+
},
145+
"yaxis3": {
146+
"domain": [0.41, 0.59],
147+
"zeroline": false,
148+
"range": [-2, 5]
149+
},
150+
"yaxis4": {
151+
"domain": [0.61, 0.79],
152+
"zeroline": false,
153+
"range": [-2, 5]
154+
},
155+
"yaxis5": {
156+
"domain": [0.81, 1],
157+
"zeroline": false,
158+
"range": [-2, 5]
159+
},
160+
"xaxis": {
161+
"domain": [0, 0.49],
162+
"range": [-0.5, 1.2]
163+
},
164+
"xaxis2": {
165+
"domain": [0.51, 1.0],
166+
"range": [-0.5, 1.2]
167+
},
168+
"annotations": [
169+
{
170+
"x": 0,
171+
"y": 4.5,
172+
"text": "slope: -10",
173+
"align": "left",
174+
"xref": "x",
175+
"yref": "y",
176+
"showarrow": false,
177+
"font": {
178+
"size": 14
179+
}
180+
},
181+
{
182+
"x": 0,
183+
"align": "left",
184+
"y": 4.5,
185+
"xref": "x",
186+
"yref": "y2",
187+
"text": "slope: -0.3",
188+
"showarrow": false,
189+
"font": {
190+
"size": 14
191+
}
192+
},
193+
{
194+
"x": 0,
195+
"y": 4.5,
196+
"align": "left",
197+
"xref": "x",
198+
"yref": "y3",
199+
"text": "slope: 0",
200+
"showarrow": false,
201+
"font": {
202+
"size": 14
203+
}
204+
},
205+
{
206+
"x": 0,
207+
"y": 4.5,
208+
"align": "left",
209+
"xref": "x",
210+
"yref": "y4",
211+
"text": "slope: 0.3",
212+
"showarrow": false,
213+
"font": {
214+
"size": 14
215+
}
216+
},
217+
{
218+
"x": 0,
219+
"y": 4.5,
220+
"align": "left",
221+
"xref": "x",
222+
"yref": "y5",
223+
"text": "slope: 10",
224+
"showarrow": false,
225+
"font": {
226+
"size": 14
227+
}
228+
}
229+
]
230+
}
231+
}

0 commit comments

Comments
 (0)