Skip to content

Commit 427fd14

Browse files
authored
Merge pull request #3200 from plotly/issue-2872
Implementation of arrayOk textposition for scatter3d traces
2 parents b9d2701 + 555a541 commit 427fd14

File tree

8 files changed

+109
-16
lines changed

8 files changed

+109
-16
lines changed

package-lock.json

+10-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"gl-plot2d": "^1.3.1",
8181
"gl-plot3d": "^1.5.11",
8282
"gl-pointcloud2d": "^1.0.1",
83-
"gl-scatter3d": "^1.0.15",
83+
"gl-scatter3d": "^1.0.16",
8484
"gl-select-box": "^1.0.2",
8585
"gl-spikes2d": "^1.0.1",
8686
"gl-streamtube3d": "^1.1.1",

src/plot_api/helpers.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -439,11 +439,14 @@ function commonPrefix(name1, name2, show1, show2) {
439439
function cleanTextPosition(textposition) {
440440
var posY = 'middle',
441441
posX = 'center';
442-
if(textposition.indexOf('top') !== -1) posY = 'top';
443-
else if(textposition.indexOf('bottom') !== -1) posY = 'bottom';
444442

445-
if(textposition.indexOf('left') !== -1) posX = 'left';
446-
else if(textposition.indexOf('right') !== -1) posX = 'right';
443+
if(typeof textposition === 'string') {
444+
if(textposition.indexOf('top') !== -1) posY = 'top';
445+
else if(textposition.indexOf('bottom') !== -1) posY = 'bottom';
446+
447+
if(textposition.indexOf('left') !== -1) posX = 'left';
448+
else if(textposition.indexOf('right') !== -1) posX = 'right';
449+
}
447450

448451
return posY + ' ' + posX;
449452
}

src/traces/scatter3d/attributes.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ var attrs = module.exports = overrideAll({
160160
colorAttributes('marker')
161161
),
162162

163-
textposition: extendFlat({}, scatterAttrs.textposition, {dflt: 'top center', arrayOk: false}),
163+
textposition: extendFlat({}, scatterAttrs.textposition, {dflt: 'top center'}),
164164
textfont: {
165165
color: scatterAttrs.textfont.color,
166166
size: scatterAttrs.textfont.size,

src/traces/scatter3d/convert.js

+40-7
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,47 @@ function calculateErrorParams(errors) {
133133
return {capSize: capSize, color: color, lineWidth: lineWidth};
134134
}
135135

136+
function parseAlignmentX(a) {
137+
if(a === null || a === undefined) return 0;
138+
139+
return (a.indexOf('left') > -1) ? -1 :
140+
(a.indexOf('right') > -1) ? 1 : 0;
141+
}
142+
143+
function parseAlignmentY(a) {
144+
if(a === null || a === undefined) return 0;
145+
146+
return (a.indexOf('top') > -1) ? -1 :
147+
(a.indexOf('bottom') > -1) ? 1 : 0;
148+
}
149+
136150
function calculateTextOffset(tp) {
137151
// Read out text properties
138-
var textOffset = [0, 0];
139-
if(Array.isArray(tp)) return [0, -1];
140-
if(tp.indexOf('bottom') >= 0) textOffset[1] += 1;
141-
if(tp.indexOf('top') >= 0) textOffset[1] -= 1;
142-
if(tp.indexOf('left') >= 0) textOffset[0] -= 1;
143-
if(tp.indexOf('right') >= 0) textOffset[0] += 1;
152+
153+
var defaultAlignmentX = 0;
154+
var defaultAlignmentY = 0;
155+
156+
var textOffset = [
157+
defaultAlignmentX,
158+
defaultAlignmentY
159+
];
160+
161+
if(Array.isArray(tp)) {
162+
for(var i = 0; i < tp.length; i++) {
163+
textOffset[i] = [
164+
defaultAlignmentX,
165+
defaultAlignmentY
166+
];
167+
if(tp[i]) {
168+
textOffset[i][0] = parseAlignmentX(tp[i]);
169+
textOffset[i][1] = parseAlignmentY(tp[i]);
170+
}
171+
}
172+
} else {
173+
textOffset[0] = parseAlignmentX(tp);
174+
textOffset[1] = parseAlignmentY(tp);
175+
}
176+
144177
return textOffset;
145178
}
146179

@@ -233,7 +266,7 @@ function convertPlotlyOptions(scene, data) {
233266
}
234267

235268
if('textposition' in data) {
236-
params.textOffset = calculateTextOffset(data.textposition); // arrayOk === false
269+
params.textOffset = calculateTextOffset(data.textposition);
237270
params.textColor = formatColor(data.textfont, 1, len);
238271
params.textSize = formatParam(data.textfont.size, len, Lib.identity, 12);
239272
params.textFont = data.textfont.family; // arrayOk === false
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"data": [
3+
{
4+
"x": [0, 1, 2, 3, 4, 5, 6, 7, 8],
5+
"y": [0, 1, 0, 1, 0, 1, 0, 1, 0],
6+
"z": [0, 1, 2, 3, 4, 5, 6, 7, 8],
7+
"type": "scatter3d",
8+
"mode":"lines+markers+text",
9+
"text": ["middle center", "bottom", "right", "bottom right", "bottom left", "left", "top right", "top", "top left"],
10+
"textposition": ["", "bottom", "right", "bottom right", "bottom left", "left", "top right", "top", "top left"]
11+
}
12+
],
13+
"layout": {
14+
"title":"Texts in scatter3d could be aligned differently using arrays",
15+
"width": 800,
16+
"height": 600,
17+
"scene":{
18+
"camera":{
19+
"eye":{ "x":-1.25,"y":1.25,"z":1.25 },
20+
"center":{ "x":0,"y":0,"z":0 },
21+
"up":{ "x":0,"y":0,"z":1 }
22+
}
23+
}
24+
}
25+
}

test/jasmine/tests/gl3d_plot_interact_test.js

+25
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,31 @@ describe('Test gl3d plots', function() {
559559
.then(done);
560560
});
561561

562+
it('@gl should only accept texts for textposition otherwise textposition is set to middle center before passing to webgl', function(done) {
563+
Plotly.plot(gd, [{
564+
type: 'scatter3d',
565+
mode: 'markers+text+lines',
566+
x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
567+
y: [-1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16],
568+
z: [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
569+
text: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'],
570+
textposition: ['left top', 'right top', 'left bottom', 'right bottom', null, undefined, true, false, [], {}, NaN, Infinity, 0, 1.2]
571+
}])
572+
.then(function() {
573+
var AllTextpositions = gd._fullData[0].textposition;
574+
575+
expect(AllTextpositions[0]).toBe('top left', 'is not top left');
576+
expect(AllTextpositions[1]).toBe('top right', 'is not top right');
577+
expect(AllTextpositions[2]).toBe('bottom left', 'is not bottom left');
578+
expect(AllTextpositions[3]).toBe('bottom right', 'is not bottom right');
579+
for(var i = 4; i < AllTextpositions.length; i++) {
580+
expect(AllTextpositions[i]).toBe('middle center', 'is not middle center');
581+
}
582+
})
583+
.catch(failTest)
584+
.then(done);
585+
});
586+
562587
it('@gl axis ticks should not be set when axis _length is NaN', function(done) {
563588
Plotly.plot(gd,
564589
{

0 commit comments

Comments
 (0)