Skip to content

Commit b760fe8

Browse files
committed
Merge branch 'master' into hovertext-on-hover
2 parents 4148cd4 + 0ec992e commit b760fe8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2589
-1112
lines changed

Diff for: src/components/annotations/annotation_defaults.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ module.exports = function handleAnnotationDefaults(annIn, annOut, fullLayout, op
3030
if(!(visible || clickToShow)) return annOut;
3131

3232
coerce('opacity');
33-
coerce('align');
3433
coerce('bgcolor');
3534

3635
var borderColor = coerce('bordercolor'),
@@ -45,6 +44,12 @@ module.exports = function handleAnnotationDefaults(annIn, annOut, fullLayout, op
4544
coerce('textangle');
4645
Lib.coerceFont(coerce, 'font', fullLayout.font);
4746

47+
coerce('width');
48+
coerce('align');
49+
50+
var h = coerce('height');
51+
if(h) coerce('valign');
52+
4853
// positioning
4954
var axLetters = ['x', 'y'],
5055
arrowPosDflt = [-10, -30],

Diff for: src/components/annotations/attributes.js

+36-4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@ module.exports = {
4949
font: extendFlat({}, fontAttrs, {
5050
description: 'Sets the annotation text font.'
5151
}),
52+
width: {
53+
valType: 'number',
54+
min: 1,
55+
dflt: null,
56+
role: 'style',
57+
description: [
58+
'Sets an explicit width for the text box. null (default) lets the',
59+
'text set the box width. Wider text will be clipped.',
60+
'There is no automatic wrapping; use <br> to start a new line.'
61+
].join(' ')
62+
},
63+
height: {
64+
valType: 'number',
65+
min: 1,
66+
dflt: null,
67+
role: 'style',
68+
description: [
69+
'Sets an explicit height for the text box. null (default) lets the',
70+
'text set the box height. Taller text will be clipped.'
71+
].join(' ')
72+
},
5273
opacity: {
5374
valType: 'number',
5475
min: 0,
@@ -63,10 +84,21 @@ module.exports = {
6384
dflt: 'center',
6485
role: 'style',
6586
description: [
66-
'Sets the vertical alignment of the `text` with',
67-
'respect to the set `x` and `y` position.',
68-
'Has only an effect if `text` spans more two or more lines',
69-
'(i.e. `text` contains one or more <br> HTML tags).'
87+
'Sets the horizontal alignment of the `text` within the box.',
88+
'Has an effect only if `text` spans more two or more lines',
89+
'(i.e. `text` contains one or more <br> HTML tags) or if an',
90+
'explicit width is set to override the text width.'
91+
].join(' ')
92+
},
93+
valign: {
94+
valType: 'enumerated',
95+
values: ['top', 'middle', 'bottom'],
96+
dflt: 'middle',
97+
role: 'style',
98+
description: [
99+
'Sets the vertical alignment of the `text` within the box.',
100+
'Has an effect only if an explicit height is set to override',
101+
'the text height.'
70102
].join(' ')
71103
},
72104
bgcolor: {

Diff for: src/components/annotations/draw.js

+60-20
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,14 @@ function drawOne(gd, index) {
7272
var optionsIn = (layout.annotations || [])[index],
7373
options = fullLayout.annotations[index];
7474

75+
var annClipID = 'clip' + fullLayout._uid + '_ann' + index;
76+
7577
// this annotation is gone - quit now after deleting it
7678
// TODO: use d3 idioms instead of deleting and redrawing every time
77-
if(!optionsIn || options.visible === false) return;
79+
if(!optionsIn || options.visible === false) {
80+
d3.selectAll('#' + annClipID).remove();
81+
return;
82+
}
7883

7984
var xa = Axes.getFromId(gd, options.xref),
8085
ya = Axes.getFromId(gd, options.yref),
@@ -118,6 +123,18 @@ function drawOne(gd, index) {
118123
.call(Color.stroke, options.bordercolor)
119124
.call(Color.fill, options.bgcolor);
120125

126+
var isSizeConstrained = options.width || options.height;
127+
128+
var annTextClip = fullLayout._defs.select('.clips')
129+
.selectAll('#' + annClipID)
130+
.data(isSizeConstrained ? [0] : []);
131+
132+
annTextClip.enter().append('clipPath')
133+
.classed('annclip', true)
134+
.attr('id', annClipID)
135+
.append('rect');
136+
annTextClip.exit().remove();
137+
121138
var font = options.font;
122139

123140
var annText = annTextGroupInner.append('text')
@@ -144,19 +161,21 @@ function drawOne(gd, index) {
144161
// at the end, even if their position changes
145162
annText.selectAll('tspan.line').attr({y: 0, x: 0});
146163

147-
var mathjaxGroup = annTextGroupInner.select('.annotation-math-group'),
148-
hasMathjax = !mathjaxGroup.empty(),
149-
anntextBB = Drawing.bBox(
150-
(hasMathjax ? mathjaxGroup : annText).node()),
151-
annwidth = anntextBB.width,
152-
annheight = anntextBB.height,
153-
outerwidth = Math.round(annwidth + 2 * borderfull),
154-
outerheight = Math.round(annheight + 2 * borderfull);
164+
var mathjaxGroup = annTextGroupInner.select('.annotation-math-group');
165+
var hasMathjax = !mathjaxGroup.empty();
166+
var anntextBB = Drawing.bBox(
167+
(hasMathjax ? mathjaxGroup : annText).node());
168+
var textWidth = anntextBB.width;
169+
var textHeight = anntextBB.height;
170+
var annWidth = options.width || textWidth;
171+
var annHeight = options.height || textHeight;
172+
var outerWidth = Math.round(annWidth + 2 * borderfull);
173+
var outerHeight = Math.round(annHeight + 2 * borderfull);
155174

156175

157176
// save size in the annotation object for use by autoscale
158-
options._w = annwidth;
159-
options._h = annheight;
177+
options._w = annWidth;
178+
options._h = annHeight;
160179

161180
function shiftFraction(v, anchor) {
162181
if(anchor === 'auto') {
@@ -181,8 +200,8 @@ function drawOne(gd, index) {
181200
ax = Axes.getFromId(gd, axRef),
182201
dimAngle = (textangle + (axLetter === 'x' ? 0 : -90)) * Math.PI / 180,
183202
// note that these two can be either positive or negative
184-
annSizeFromWidth = outerwidth * Math.cos(dimAngle),
185-
annSizeFromHeight = outerheight * Math.sin(dimAngle),
203+
annSizeFromWidth = outerWidth * Math.cos(dimAngle),
204+
annSizeFromHeight = outerHeight * Math.sin(dimAngle),
186205
// but this one is the positive total size
187206
annSize = Math.abs(annSizeFromWidth) + Math.abs(annSizeFromHeight),
188207
anchor = options[axLetter + 'anchor'],
@@ -299,22 +318,43 @@ function drawOne(gd, index) {
299318
return;
300319
}
301320

321+
var xShift = 0;
322+
var yShift = 0;
323+
324+
if(options.align !== 'left') {
325+
xShift = (annWidth - textWidth) * (options.align === 'center' ? 0.5 : 1);
326+
}
327+
if(options.valign !== 'top') {
328+
yShift = (annHeight - textHeight) * (options.valign === 'middle' ? 0.5 : 1);
329+
}
330+
302331
if(hasMathjax) {
303-
mathjaxGroup.select('svg').attr({x: borderfull - 1, y: borderfull});
332+
mathjaxGroup.select('svg').attr({
333+
x: borderfull + xShift - 1,
334+
y: borderfull + yShift
335+
})
336+
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null);
304337
}
305338
else {
306-
var texty = borderfull - anntextBB.top,
307-
textx = borderfull - anntextBB.left;
308-
annText.attr({x: textx, y: texty});
339+
var texty = borderfull + yShift - anntextBB.top,
340+
textx = borderfull + xShift - anntextBB.left;
341+
annText.attr({
342+
x: textx,
343+
y: texty
344+
})
345+
.call(Drawing.setClipUrl, isSizeConstrained ? annClipID : null);
309346
annText.selectAll('tspan.line').attr({y: texty, x: textx});
310347
}
311348

349+
annTextClip.select('rect').call(Drawing.setRect, borderfull, borderfull,
350+
annWidth, annHeight);
351+
312352
annTextBG.call(Drawing.setRect, borderwidth / 2, borderwidth / 2,
313-
outerwidth - borderwidth, outerheight - borderwidth);
353+
outerWidth - borderwidth, outerHeight - borderwidth);
314354

315355
annTextGroupInner.call(Drawing.setTranslate,
316-
Math.round(annPosPx.x.text - outerwidth / 2),
317-
Math.round(annPosPx.y.text - outerheight / 2));
356+
Math.round(annPosPx.x.text - outerWidth / 2),
357+
Math.round(annPosPx.y.text - outerHeight / 2));
318358

319359
/*
320360
* rotate text and background

Diff for: src/components/colorbar/draw.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,10 @@ module.exports = function draw(gd, id) {
170170
anchor: 'free',
171171
position: 1
172172
},
173-
cbAxisOut = {},
173+
cbAxisOut = {
174+
type: 'linear',
175+
_id: 'y' + id
176+
},
174177
axisOptions = {
175178
letter: 'y',
176179
font: fullLayout.font,
@@ -188,8 +191,6 @@ module.exports = function draw(gd, id) {
188191
handleAxisDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions, fullLayout);
189192
handleAxisPositionDefaults(cbAxisIn, cbAxisOut, coerce, axisOptions);
190193

191-
cbAxisOut._id = 'y' + id;
192-
193194
// position can't go in through supplyDefaults
194195
// because that restricts it to [0,1]
195196
cbAxisOut.position = opts.x + xpadFrac + thickFrac;

Diff for: src/constants/numerical.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,10 @@ module.exports = {
4242
* For fast conversion btwn world calendars and epoch ms, the Julian Day Number
4343
* of the unix epoch. From calendars.instance().newDate(1970, 1, 1).toJD()
4444
*/
45-
EPOCHJD: 2440587.5
45+
EPOCHJD: 2440587.5,
46+
47+
/*
48+
* Are two values nearly equal? Compare to 1PPM
49+
*/
50+
ALMOST_EQUAL: 1 - 1e-6
4651
};

Diff for: src/lib/geojson_utils.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
'use strict';
1111

12+
var BADNUM = require('../constants/numerical').BADNUM;
13+
1214
/**
1315
* Convert calcTrace to GeoJSON 'MultiLineString' coordinate arrays
1416
*
@@ -21,18 +23,19 @@
2123
*
2224
*/
2325
exports.calcTraceToLineCoords = function(calcTrace) {
24-
var trace = calcTrace[0].trace,
25-
connectgaps = trace.connectgaps;
26+
var trace = calcTrace[0].trace;
27+
var connectgaps = trace.connectgaps;
2628

27-
var coords = [],
28-
lineString = [];
29+
var coords = [];
30+
var lineString = [];
2931

3032
for(var i = 0; i < calcTrace.length; i++) {
3133
var calcPt = calcTrace[i];
34+
var lonlat = calcPt.lonlat;
3235

33-
lineString.push(calcPt.lonlat);
34-
35-
if(!connectgaps && calcPt.gapAfter && lineString.length > 0) {
36+
if(lonlat[0] !== BADNUM) {
37+
lineString.push(lonlat);
38+
} else if(!connectgaps && lineString.length > 0) {
3639
coords.push(lineString);
3740
lineString = [];
3841
}

0 commit comments

Comments
 (0)