plotly.js 2.6.1 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +3 -3
- package/dist/README.md +26 -26
- package/dist/plot-schema.json +117 -0
- package/dist/plotly-basic.js +129 -90
- package/dist/plotly-basic.min.js +2 -2
- package/dist/plotly-cartesian.js +187 -97
- package/dist/plotly-cartesian.min.js +2 -2
- package/dist/plotly-finance.js +179 -92
- package/dist/plotly-finance.min.js +2 -2
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +128 -89
- package/dist/plotly-geo.min.js +4 -4
- package/dist/plotly-gl2d.js +134 -110
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +128 -89
- package/dist/plotly-gl3d.min.js +2 -2
- package/dist/plotly-mapbox.js +134 -92
- package/dist/plotly-mapbox.min.js +2 -2
- package/dist/plotly-strict.js +199 -121
- package/dist/plotly-strict.min.js +2 -2
- package/dist/plotly-with-meta.js +202 -121
- package/dist/plotly.js +199 -121
- package/dist/plotly.min.js +2 -2
- package/package.json +10 -9
- package/src/components/colorbar/draw.js +72 -61
- package/src/components/drawing/index.js +6 -3
- package/src/components/fx/hover.js +11 -15
- package/src/plot_api/plot_api.js +37 -8
- package/src/plots/mapbox/mapbox.js +6 -3
- package/src/traces/bar/plot.js +1 -1
- package/src/traces/histogram/attributes.js +40 -0
- package/src/traces/histogram/defaults.js +11 -0
- package/src/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plotly.js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "The open source javascript graphing library that powers plotly",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"native-promise-only": "^0.8.1",
|
|
104
104
|
"parse-svg-path": "^0.1.2",
|
|
105
105
|
"polybooljs": "^1.2.0",
|
|
106
|
-
"probe-image-size": "^7.2.
|
|
106
|
+
"probe-image-size": "^7.2.2",
|
|
107
107
|
"regl": "^2.1.0",
|
|
108
108
|
"regl-error2d": "^2.0.12",
|
|
109
109
|
"regl-line2d": "^3.1.2",
|
|
@@ -113,6 +113,7 @@
|
|
|
113
113
|
"superscript-text": "^1.0.0",
|
|
114
114
|
"svg-path-sdf": "^1.1.3",
|
|
115
115
|
"tinycolor2": "^1.4.2",
|
|
116
|
+
"to-px": "1.0.1",
|
|
116
117
|
"topojson-client": "^3.1.0",
|
|
117
118
|
"webgl-context": "^2.2.0",
|
|
118
119
|
"world-calendars": "^1.0.3"
|
|
@@ -124,12 +125,12 @@
|
|
|
124
125
|
"browserify-transform-tools": "^1.7.0",
|
|
125
126
|
"bubleify": "^2.0.0",
|
|
126
127
|
"canvas": "^2.8.0",
|
|
127
|
-
"check-node-version": "^4.1
|
|
128
|
+
"check-node-version": "^4.2.1",
|
|
128
129
|
"chttps": "^1.0.6",
|
|
129
130
|
"deep-equal": "^2.0.5",
|
|
130
131
|
"derequire": "^2.1.1",
|
|
131
132
|
"ecstatic": "^4.1.4",
|
|
132
|
-
"eslint": "^8.
|
|
133
|
+
"eslint": "^8.3.0",
|
|
133
134
|
"extra-iterable": "^2.5.22",
|
|
134
135
|
"falafel": "^2.2.4",
|
|
135
136
|
"fs-extra": "^10.0.0",
|
|
@@ -138,11 +139,11 @@
|
|
|
138
139
|
"gzip-size": "^6.0.0",
|
|
139
140
|
"into-stream": "^6.0.0",
|
|
140
141
|
"jasmine-core": "^3.5.0",
|
|
141
|
-
"jsdom": "^18.
|
|
142
|
-
"karma": "^6.3.
|
|
142
|
+
"jsdom": "^18.1.1",
|
|
143
|
+
"karma": "^6.3.9",
|
|
143
144
|
"karma-browserify": "^8.1.0",
|
|
144
145
|
"karma-chrome-launcher": "^3.1.0",
|
|
145
|
-
"karma-firefox-launcher": "^2.1.
|
|
146
|
+
"karma-firefox-launcher": "^2.1.2",
|
|
146
147
|
"karma-ie-launcher": "^1.0.0",
|
|
147
148
|
"karma-jasmine": "^3.3.1",
|
|
148
149
|
"karma-jasmine-spec-tags": "^1.3.0",
|
|
@@ -154,14 +155,14 @@
|
|
|
154
155
|
"mathjax": "2.7.5",
|
|
155
156
|
"minify-stream": "^2.1.0",
|
|
156
157
|
"npm-link-check": "^4.0.0",
|
|
157
|
-
"open": "^8.
|
|
158
|
+
"open": "^8.4.0",
|
|
158
159
|
"pixelmatch": "^5.2.1",
|
|
159
160
|
"prepend-file": "^2.0.0",
|
|
160
161
|
"prettysize": "^2.0.0",
|
|
161
162
|
"read-last-lines": "^1.8.0",
|
|
162
163
|
"run-series": "^1.1.9",
|
|
163
164
|
"sane-topojson": "^4.0.0",
|
|
164
|
-
"sass": "^1.
|
|
165
|
+
"sass": "^1.43.4",
|
|
165
166
|
"through2": "^4.0.2",
|
|
166
167
|
"true-case-path": "^2.2.1",
|
|
167
168
|
"watchify": "^4.0.0"
|
|
@@ -167,6 +167,19 @@ function makeColorBarData(gd) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
function drawColorBar(g, opts, gd) {
|
|
170
|
+
var len = opts.len;
|
|
171
|
+
var lenmode = opts.lenmode;
|
|
172
|
+
var thickness = opts.thickness;
|
|
173
|
+
var thicknessmode = opts.thicknessmode;
|
|
174
|
+
var outlinewidth = opts.outlinewidth;
|
|
175
|
+
var borderwidth = opts.borderwidth;
|
|
176
|
+
var xanchor = opts.xanchor;
|
|
177
|
+
var yanchor = opts.yanchor;
|
|
178
|
+
var xpad = opts.xpad;
|
|
179
|
+
var ypad = opts.ypad;
|
|
180
|
+
var optsX = opts.x;
|
|
181
|
+
var optsY = opts.y;
|
|
182
|
+
|
|
170
183
|
var fullLayout = gd._fullLayout;
|
|
171
184
|
var gs = fullLayout._size;
|
|
172
185
|
|
|
@@ -196,42 +209,41 @@ function drawColorBar(g, opts, gd) {
|
|
|
196
209
|
// when the colorbar itself is pushing the margins.
|
|
197
210
|
// but then the fractional size is calculated based on the
|
|
198
211
|
// actual graph size, so that the axes will size correctly.
|
|
199
|
-
var thickPx = Math.round(
|
|
212
|
+
var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? gs.w : 1));
|
|
200
213
|
var thickFrac = thickPx / gs.w;
|
|
201
|
-
var lenPx = Math.round(
|
|
214
|
+
var lenPx = Math.round(len * (lenmode === 'fraction' ? gs.h : 1));
|
|
202
215
|
var lenFrac = lenPx / gs.h;
|
|
203
|
-
var xpadFrac =
|
|
204
|
-
var yExtraPx = (
|
|
205
|
-
var ypadFrac =
|
|
216
|
+
var xpadFrac = xpad / gs.w;
|
|
217
|
+
var yExtraPx = (borderwidth + outlinewidth) / 2;
|
|
218
|
+
var ypadFrac = ypad / gs.h;
|
|
206
219
|
|
|
207
220
|
// x positioning: do it initially just for left anchor,
|
|
208
221
|
// then fix at the end (since we don't know the width yet)
|
|
209
|
-
var
|
|
222
|
+
var uPx = Math.round(optsX * gs.w + xpad);
|
|
210
223
|
// for dragging... this is getting a little muddled...
|
|
211
|
-
var
|
|
224
|
+
var uFrac = optsX - thickFrac * ({center: 0.5, right: 1}[xanchor] || 0);
|
|
212
225
|
|
|
213
226
|
// y positioning we can do correctly from the start
|
|
214
|
-
var
|
|
215
|
-
var
|
|
216
|
-
var yTopPx = yBottomPx - lenPx;
|
|
227
|
+
var vFrac = optsY + lenFrac * (({top: -0.5, bottom: 0.5}[yanchor] || 0) - 0.5);
|
|
228
|
+
var vPx = Math.round(gs.h * (1 - vFrac));
|
|
217
229
|
|
|
218
230
|
// stash a few things for makeEditable
|
|
219
231
|
opts._lenFrac = lenFrac;
|
|
220
232
|
opts._thickFrac = thickFrac;
|
|
221
|
-
opts.
|
|
222
|
-
opts.
|
|
233
|
+
opts._uFrac = uFrac;
|
|
234
|
+
opts._vFrac = vFrac;
|
|
223
235
|
|
|
224
236
|
// stash mocked axis for contour label formatting
|
|
225
237
|
var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
|
|
226
238
|
|
|
227
239
|
// position can't go in through supplyDefaults
|
|
228
240
|
// because that restricts it to [0,1]
|
|
229
|
-
ax.position =
|
|
241
|
+
ax.position = optsX + xpadFrac + thickFrac;
|
|
230
242
|
|
|
231
243
|
if(['top', 'bottom'].indexOf(titleSide) !== -1) {
|
|
232
244
|
ax.title.side = titleSide;
|
|
233
|
-
ax.titlex =
|
|
234
|
-
ax.titley =
|
|
245
|
+
ax.titlex = optsX + xpadFrac;
|
|
246
|
+
ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypadFrac : ypadFrac);
|
|
235
247
|
}
|
|
236
248
|
|
|
237
249
|
if(line.color && opts.tickmode === 'auto') {
|
|
@@ -239,7 +251,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
239
251
|
ax.tick0 = levelsIn.start;
|
|
240
252
|
var dtick = levelsIn.size;
|
|
241
253
|
// expand if too many contours, so we don't get too many ticks
|
|
242
|
-
var autoNtick = Lib.constrain(
|
|
254
|
+
var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
|
|
243
255
|
var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
|
|
244
256
|
if(dtFactor > 1) {
|
|
245
257
|
var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
|
|
@@ -257,8 +269,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
257
269
|
// set domain after init, because we may want to
|
|
258
270
|
// allow it outside [0,1]
|
|
259
271
|
ax.domain = [
|
|
260
|
-
|
|
261
|
-
|
|
272
|
+
vFrac + ypadFrac,
|
|
273
|
+
vFrac + lenFrac - ypadFrac
|
|
262
274
|
];
|
|
263
275
|
|
|
264
276
|
ax.setScale();
|
|
@@ -299,15 +311,15 @@ function drawColorBar(g, opts, gd) {
|
|
|
299
311
|
// draw the title so we know how much room it needs
|
|
300
312
|
// when we squish the axis. This one only applies to
|
|
301
313
|
// top or bottom titles, not right side.
|
|
302
|
-
var x = gs.l + (
|
|
314
|
+
var x = gs.l + (optsX + xpadFrac) * gs.w;
|
|
303
315
|
var fontSize = ax.title.font.size;
|
|
304
316
|
var y;
|
|
305
317
|
|
|
306
318
|
if(titleSide === 'top') {
|
|
307
|
-
y = (1 - (
|
|
319
|
+
y = (1 - (vFrac + lenFrac - ypadFrac)) * gs.h +
|
|
308
320
|
gs.t + 3 + fontSize * 0.75;
|
|
309
321
|
} else {
|
|
310
|
-
y = (1 - (
|
|
322
|
+
y = (1 - (vFrac + ypadFrac)) * gs.h +
|
|
311
323
|
gs.t - 3 - fontSize * 0.25;
|
|
312
324
|
}
|
|
313
325
|
drawTitle(ax._id + 'title', {
|
|
@@ -346,7 +358,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
346
358
|
// squish the axis top to make room for the title
|
|
347
359
|
var titleGroup = g.select('.' + cn.cbtitle);
|
|
348
360
|
var titleText = titleGroup.select('text');
|
|
349
|
-
var titleTrans = [-
|
|
361
|
+
var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
|
|
350
362
|
var mathJaxNode = titleGroup
|
|
351
363
|
.select('.h' + ax._id + 'title-math-group')
|
|
352
364
|
.node();
|
|
@@ -418,7 +430,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
418
430
|
// Colorbar cannot currently support opacities so we
|
|
419
431
|
// use an opaque fill even when alpha channels present
|
|
420
432
|
var fillEl = d3.select(this).attr({
|
|
421
|
-
x:
|
|
433
|
+
x: uPx,
|
|
422
434
|
width: Math.max(thickPx, 2),
|
|
423
435
|
y: d3.min(z),
|
|
424
436
|
height: Math.max(d3.max(z) - d3.min(z), 2),
|
|
@@ -442,7 +454,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
442
454
|
lines.exit().remove();
|
|
443
455
|
lines.each(function(d) {
|
|
444
456
|
d3.select(this)
|
|
445
|
-
.attr('d', 'M' +
|
|
457
|
+
.attr('d', 'M' + uPx + ',' +
|
|
446
458
|
(Math.round(ax.c2p(d)) + (line.width / 2) % 1) + 'h' + thickPx)
|
|
447
459
|
.call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
|
|
448
460
|
});
|
|
@@ -450,8 +462,8 @@ function drawColorBar(g, opts, gd) {
|
|
|
450
462
|
// force full redraw of labels and ticks
|
|
451
463
|
axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
|
|
452
464
|
|
|
453
|
-
var shift =
|
|
454
|
-
(
|
|
465
|
+
var shift = uPx + thickPx +
|
|
466
|
+
(outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
|
|
455
467
|
|
|
456
468
|
var vals = Axes.calcTicks(ax);
|
|
457
469
|
var tickSign = Axes.getTickSigns(ax)[2];
|
|
@@ -476,9 +488,9 @@ function drawColorBar(g, opts, gd) {
|
|
|
476
488
|
// TODO: why are we redrawing multiple times now with this?
|
|
477
489
|
// I guess autoMargin doesn't like being post-promise?
|
|
478
490
|
function positionCB() {
|
|
479
|
-
var
|
|
491
|
+
var innerThickness = thickPx + outlinewidth / 2;
|
|
480
492
|
if(ax.ticklabelposition.indexOf('inside') === -1) {
|
|
481
|
-
|
|
493
|
+
innerThickness += Drawing.bBox(axLayer.node()).width;
|
|
482
494
|
}
|
|
483
495
|
|
|
484
496
|
titleEl = titleCont.select('text');
|
|
@@ -493,66 +505,65 @@ function drawColorBar(g, opts, gd) {
|
|
|
493
505
|
// (except for top/bottom mathjax, above)
|
|
494
506
|
// but the weird gs.l is because the titleunshift
|
|
495
507
|
// transform gets removed by Drawing.bBox
|
|
496
|
-
titleWidth = Drawing.bBox(titleCont.node()).right -
|
|
508
|
+
titleWidth = Drawing.bBox(titleCont.node()).right - uPx - gs.l;
|
|
497
509
|
}
|
|
498
|
-
|
|
510
|
+
innerThickness = Math.max(innerThickness, titleWidth);
|
|
499
511
|
}
|
|
500
512
|
|
|
501
|
-
var
|
|
502
|
-
var outerheight = yBottomPx - yTopPx;
|
|
513
|
+
var outerThickness = 2 * xpad + innerThickness + borderwidth + outlinewidth / 2;
|
|
503
514
|
|
|
504
515
|
g.select('.' + cn.cbbg).attr({
|
|
505
|
-
x:
|
|
506
|
-
y:
|
|
507
|
-
width: Math.max(
|
|
508
|
-
height: Math.max(
|
|
516
|
+
x: uPx - xpad - (borderwidth + outlinewidth) / 2,
|
|
517
|
+
y: vPx - lenPx - yExtraPx,
|
|
518
|
+
width: Math.max(outerThickness, 2),
|
|
519
|
+
height: Math.max(lenPx + 2 * yExtraPx, 2)
|
|
509
520
|
})
|
|
510
521
|
.call(Color.fill, opts.bgcolor)
|
|
511
522
|
.call(Color.stroke, opts.bordercolor)
|
|
512
|
-
.style('stroke-width',
|
|
523
|
+
.style('stroke-width', borderwidth);
|
|
513
524
|
|
|
514
525
|
g.selectAll('.' + cn.cboutline).attr({
|
|
515
|
-
x:
|
|
516
|
-
y:
|
|
526
|
+
x: uPx,
|
|
527
|
+
y: vPx - lenPx + ypad + (titleSide === 'top' ? titleHeight : 0),
|
|
517
528
|
width: Math.max(thickPx, 2),
|
|
518
|
-
height: Math.max(
|
|
529
|
+
height: Math.max(lenPx - 2 * ypad - titleHeight, 2)
|
|
519
530
|
})
|
|
520
531
|
.call(Color.stroke, opts.outlinecolor)
|
|
521
532
|
.style({
|
|
522
533
|
fill: 'none',
|
|
523
|
-
'stroke-width':
|
|
534
|
+
'stroke-width': outlinewidth
|
|
524
535
|
});
|
|
525
536
|
|
|
526
537
|
// fix positioning for xanchor!='left'
|
|
527
|
-
var xoffset = ({center: 0.5, right: 1}[
|
|
538
|
+
var xoffset = ({center: 0.5, right: 1}[xanchor] || 0) * outerThickness;
|
|
528
539
|
g.attr('transform', strTranslate(gs.l - xoffset, gs.t));
|
|
529
540
|
|
|
530
541
|
// auto margin adjustment
|
|
531
542
|
var marginOpts = {};
|
|
532
|
-
var tFrac = FROM_TL[
|
|
533
|
-
var bFrac = FROM_BR[
|
|
534
|
-
if(
|
|
535
|
-
marginOpts.y =
|
|
536
|
-
marginOpts.t =
|
|
537
|
-
marginOpts.b =
|
|
543
|
+
var tFrac = FROM_TL[yanchor];
|
|
544
|
+
var bFrac = FROM_BR[yanchor];
|
|
545
|
+
if(lenmode === 'pixels') {
|
|
546
|
+
marginOpts.y = optsY;
|
|
547
|
+
marginOpts.t = lenPx * tFrac;
|
|
548
|
+
marginOpts.b = lenPx * bFrac;
|
|
538
549
|
} else {
|
|
539
550
|
marginOpts.t = marginOpts.b = 0;
|
|
540
|
-
marginOpts.yt =
|
|
541
|
-
marginOpts.yb =
|
|
551
|
+
marginOpts.yt = optsY + len * tFrac;
|
|
552
|
+
marginOpts.yb = optsY - len * bFrac;
|
|
542
553
|
}
|
|
543
554
|
|
|
544
|
-
var lFrac = FROM_TL[
|
|
545
|
-
var rFrac = FROM_BR[
|
|
546
|
-
if(
|
|
547
|
-
marginOpts.x =
|
|
548
|
-
marginOpts.l =
|
|
549
|
-
marginOpts.r =
|
|
555
|
+
var lFrac = FROM_TL[xanchor];
|
|
556
|
+
var rFrac = FROM_BR[xanchor];
|
|
557
|
+
if(thicknessmode === 'pixels') {
|
|
558
|
+
marginOpts.x = optsX;
|
|
559
|
+
marginOpts.l = outerThickness * lFrac;
|
|
560
|
+
marginOpts.r = outerThickness * rFrac;
|
|
550
561
|
} else {
|
|
551
|
-
var extraThickness =
|
|
562
|
+
var extraThickness = outerThickness - thickPx;
|
|
552
563
|
marginOpts.l = extraThickness * lFrac;
|
|
553
564
|
marginOpts.r = extraThickness * rFrac;
|
|
554
|
-
marginOpts.xl =
|
|
555
|
-
marginOpts.xr =
|
|
565
|
+
marginOpts.xl = optsX - thickness * lFrac;
|
|
566
|
+
marginOpts.xr = optsX + thickness * rFrac;
|
|
556
567
|
}
|
|
557
568
|
|
|
558
569
|
Plots.autoMargin(gd, opts._id, marginOpts);
|
|
@@ -583,9 +594,9 @@ function makeEditable(g, opts, gd) {
|
|
|
583
594
|
moveFn: function(dx, dy) {
|
|
584
595
|
g.attr('transform', t0 + strTranslate(dx, dy));
|
|
585
596
|
|
|
586
|
-
xf = dragElement.align(opts.
|
|
597
|
+
xf = dragElement.align(opts._uFrac + (dx / gs.w), opts._thickFrac,
|
|
587
598
|
0, 1, opts.xanchor);
|
|
588
|
-
yf = dragElement.align(opts.
|
|
599
|
+
yf = dragElement.align(opts._vFrac - (dy / gs.h), opts._lenFrac,
|
|
589
600
|
0, 1, opts.yanchor);
|
|
590
601
|
|
|
591
602
|
var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
|
|
@@ -927,7 +927,7 @@ var TEXTOFFSETSIGN = {
|
|
|
927
927
|
start: 1, end: -1, middle: 0, bottom: 1, top: -1
|
|
928
928
|
};
|
|
929
929
|
|
|
930
|
-
function textPointPosition(s, textPosition, fontSize, markerRadius) {
|
|
930
|
+
function textPointPosition(s, textPosition, fontSize, markerRadius, dontTouchParent) {
|
|
931
931
|
var group = d3.select(s.node().parentNode);
|
|
932
932
|
|
|
933
933
|
var v = textPosition.indexOf('top') !== -1 ?
|
|
@@ -949,7 +949,9 @@ function textPointPosition(s, textPosition, fontSize, markerRadius) {
|
|
|
949
949
|
|
|
950
950
|
// fix the overall text group position
|
|
951
951
|
s.attr('text-anchor', h);
|
|
952
|
-
|
|
952
|
+
if(!dontTouchParent) {
|
|
953
|
+
group.attr('transform', strTranslate(dx, dy));
|
|
954
|
+
}
|
|
953
955
|
}
|
|
954
956
|
|
|
955
957
|
function extracTextFontSize(d, trace) {
|
|
@@ -1019,7 +1021,8 @@ drawing.selectedTextStyle = function(s, trace) {
|
|
|
1019
1021
|
var fontSize = extracTextFontSize(d, trace);
|
|
1020
1022
|
|
|
1021
1023
|
Color.fill(tx, tc);
|
|
1022
|
-
|
|
1024
|
+
var dontTouchParent = Registry.traceIs(trace, 'bar-like');
|
|
1025
|
+
textPointPosition(tx, tp, fontSize, d.mrc2 || d.mrc, dontTouchParent);
|
|
1023
1026
|
});
|
|
1024
1027
|
};
|
|
1025
1028
|
|
|
@@ -78,11 +78,13 @@ var cartesianScatterPoints = {
|
|
|
78
78
|
// The actual rendering is done by private function _hover.
|
|
79
79
|
exports.hover = function hover(gd, evt, subplot, noHoverEvent) {
|
|
80
80
|
gd = Lib.getGraphDiv(gd);
|
|
81
|
-
|
|
81
|
+
// The 'target' property changes when bubbling out of Shadow DOM.
|
|
82
|
+
// Throttling can delay reading the target, so we save the current value.
|
|
83
|
+
var eventTarget = evt.target;
|
|
82
84
|
Lib.throttle(
|
|
83
85
|
gd._fullLayout._uid + constants.HOVERID,
|
|
84
86
|
constants.HOVERMINTIME,
|
|
85
|
-
function() { _hover(gd, evt, subplot, noHoverEvent); }
|
|
87
|
+
function() { _hover(gd, evt, subplot, noHoverEvent, eventTarget); }
|
|
86
88
|
);
|
|
87
89
|
};
|
|
88
90
|
|
|
@@ -247,7 +249,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
|
|
|
247
249
|
};
|
|
248
250
|
|
|
249
251
|
// The actual implementation is here:
|
|
250
|
-
function _hover(gd, evt, subplot, noHoverEvent) {
|
|
252
|
+
function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
|
|
251
253
|
if(!subplot) subplot = 'xy';
|
|
252
254
|
|
|
253
255
|
// if the user passed in an array of subplots,
|
|
@@ -366,7 +368,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
366
368
|
// [x|y]px: the pixels (from top left) of the mouse location
|
|
367
369
|
// on the currently selected plot area
|
|
368
370
|
// add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
|
|
369
|
-
var hasUserCalledHover = !
|
|
371
|
+
var hasUserCalledHover = !eventTarget;
|
|
370
372
|
var xpx, ypx;
|
|
371
373
|
|
|
372
374
|
if(hasUserCalledHover) {
|
|
@@ -383,13 +385,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
383
385
|
return;
|
|
384
386
|
}
|
|
385
387
|
|
|
386
|
-
|
|
387
|
-
var target = evt.composedPath && evt.composedPath()[0];
|
|
388
|
-
if(!target) {
|
|
389
|
-
// Fallback for browsers not supporting composedPath
|
|
390
|
-
target = evt.target;
|
|
391
|
-
}
|
|
392
|
-
var dbb = target.getBoundingClientRect();
|
|
388
|
+
var dbb = eventTarget.getBoundingClientRect();
|
|
393
389
|
|
|
394
390
|
xpx = evt.clientX - dbb.left;
|
|
395
391
|
ypx = evt.clientY - dbb.top;
|
|
@@ -837,15 +833,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
|
|
|
837
833
|
if(!helpers.isUnifiedHover(hovermode)) {
|
|
838
834
|
hoverAvoidOverlaps(hoverLabels, rotateLabels ? 'xa' : 'ya', fullLayout);
|
|
839
835
|
alignHoverText(hoverLabels, rotateLabels, fullLayout._invScaleX, fullLayout._invScaleY);
|
|
840
|
-
} // TODO: tagName hack is needed to appease geo.js's hack of using
|
|
836
|
+
} // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget=true
|
|
841
837
|
// we should improve the "fx" API so other plots can use it without these hack.
|
|
842
|
-
if(
|
|
838
|
+
if(eventTarget && eventTarget.tagName) {
|
|
843
839
|
var hasClickToShow = Registry.getComponentMethod('annotations', 'hasClickToShow')(gd, newhoverdata);
|
|
844
|
-
overrideCursor(d3.select(
|
|
840
|
+
overrideCursor(d3.select(eventTarget), hasClickToShow ? 'pointer' : '');
|
|
845
841
|
}
|
|
846
842
|
|
|
847
843
|
// don't emit events if called manually
|
|
848
|
-
if(!
|
|
844
|
+
if(!eventTarget || noHoverEvent || !hoverChanged(gd, evt, oldhoverdata)) return;
|
|
849
845
|
|
|
850
846
|
if(oldhoverdata) {
|
|
851
847
|
gd.emit('plotly_unhover', {
|
package/src/plot_api/plot_api.js
CHANGED
|
@@ -2396,7 +2396,8 @@ function findUIPattern(key, patternSpecs) {
|
|
|
2396
2396
|
var spec = patternSpecs[i];
|
|
2397
2397
|
var match = key.match(spec.pattern);
|
|
2398
2398
|
if(match) {
|
|
2399
|
-
|
|
2399
|
+
var head = match[1] || '';
|
|
2400
|
+
return {head: head, tail: key.substr(head.length + 1), attr: spec.attr};
|
|
2400
2401
|
}
|
|
2401
2402
|
}
|
|
2402
2403
|
}
|
|
@@ -2448,26 +2449,54 @@ function valsMatch(v1, v2) {
|
|
|
2448
2449
|
|
|
2449
2450
|
function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
|
|
2450
2451
|
var layoutPreGUI = oldFullLayout._preGUI;
|
|
2451
|
-
var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal;
|
|
2452
|
+
var key, revAttr, oldRev, newRev, match, preGUIVal, newNP, newVal, head, tail;
|
|
2452
2453
|
var bothInheritAutorange = [];
|
|
2454
|
+
var newAutorangeIn = {};
|
|
2453
2455
|
var newRangeAccepted = {};
|
|
2454
2456
|
for(key in layoutPreGUI) {
|
|
2455
2457
|
match = findUIPattern(key, layoutUIControlPatterns);
|
|
2456
2458
|
if(match) {
|
|
2457
|
-
|
|
2459
|
+
head = match.head;
|
|
2460
|
+
tail = match.tail;
|
|
2461
|
+
revAttr = match.attr || (head + '.uirevision');
|
|
2458
2462
|
oldRev = nestedProperty(oldFullLayout, revAttr).get();
|
|
2459
2463
|
newRev = oldRev && getNewRev(revAttr, layout);
|
|
2464
|
+
|
|
2460
2465
|
if(newRev && (newRev === oldRev)) {
|
|
2461
2466
|
preGUIVal = layoutPreGUI[key];
|
|
2462
2467
|
if(preGUIVal === null) preGUIVal = undefined;
|
|
2463
2468
|
newNP = nestedProperty(layout, key);
|
|
2464
2469
|
newVal = newNP.get();
|
|
2470
|
+
|
|
2465
2471
|
if(valsMatch(newVal, preGUIVal)) {
|
|
2466
|
-
if(newVal === undefined &&
|
|
2467
|
-
bothInheritAutorange.push(
|
|
2472
|
+
if(newVal === undefined && tail === 'autorange') {
|
|
2473
|
+
bothInheritAutorange.push(head);
|
|
2468
2474
|
}
|
|
2469
2475
|
newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
|
|
2470
2476
|
continue;
|
|
2477
|
+
} else if(tail === 'autorange' || tail.substr(0, 6) === 'range[') {
|
|
2478
|
+
// Special case for (auto)range since we push it back into the layout
|
|
2479
|
+
// so all null should be treated equivalently to autorange: true with any range
|
|
2480
|
+
var pre0 = layoutPreGUI[head + '.range[0]'];
|
|
2481
|
+
var pre1 = layoutPreGUI[head + '.range[1]'];
|
|
2482
|
+
var preAuto = layoutPreGUI[head + '.autorange'];
|
|
2483
|
+
if(preAuto || (preAuto === null && pre0 === null && pre1 === null)) {
|
|
2484
|
+
// Only read the input layout once and stash the result,
|
|
2485
|
+
// so we get it before we start modifying it
|
|
2486
|
+
if(!(head in newAutorangeIn)) {
|
|
2487
|
+
var newContainer = nestedProperty(layout, head).get();
|
|
2488
|
+
newAutorangeIn[head] = newContainer && (
|
|
2489
|
+
newContainer.autorange ||
|
|
2490
|
+
(newContainer.autorange !== false && (
|
|
2491
|
+
!newContainer.range || newContainer.range.length !== 2)
|
|
2492
|
+
)
|
|
2493
|
+
);
|
|
2494
|
+
}
|
|
2495
|
+
if(newAutorangeIn[head]) {
|
|
2496
|
+
newNP.set(undefinedToNull(nestedProperty(oldFullLayout, key).get()));
|
|
2497
|
+
continue;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2471
2500
|
}
|
|
2472
2501
|
}
|
|
2473
2502
|
} else {
|
|
@@ -2478,12 +2507,12 @@ function applyUIRevisions(data, layout, oldFullData, oldFullLayout) {
|
|
|
2478
2507
|
// so remove it from _preGUI for next time.
|
|
2479
2508
|
delete layoutPreGUI[key];
|
|
2480
2509
|
|
|
2481
|
-
if(
|
|
2482
|
-
newRangeAccepted[
|
|
2510
|
+
if(match && match.tail.substr(0, 6) === 'range[') {
|
|
2511
|
+
newRangeAccepted[match.head] = 1;
|
|
2483
2512
|
}
|
|
2484
2513
|
}
|
|
2485
2514
|
|
|
2486
|
-
//
|
|
2515
|
+
// More special logic for `autorange`, since it interacts with `range`:
|
|
2487
2516
|
// If the new figure's matching `range` was kept, and `autorange`
|
|
2488
2517
|
// wasn't supplied explicitly in either the original or the new figure,
|
|
2489
2518
|
// we shouldn't alter that - but we may just have done that, so fix it.
|
|
@@ -722,11 +722,14 @@ proto.project = function(v) {
|
|
|
722
722
|
proto.getView = function() {
|
|
723
723
|
var map = this.map;
|
|
724
724
|
var mapCenter = map.getCenter();
|
|
725
|
-
var
|
|
725
|
+
var lon = mapCenter.lng;
|
|
726
|
+
var lat = mapCenter.lat;
|
|
727
|
+
var center = { lon: lon, lat: lat };
|
|
726
728
|
|
|
727
729
|
var canvas = map.getCanvas();
|
|
728
|
-
var w = canvas.width;
|
|
729
|
-
var h = canvas.height;
|
|
730
|
+
var w = parseInt(canvas.style.width);
|
|
731
|
+
var h = parseInt(canvas.style.height);
|
|
732
|
+
|
|
730
733
|
return {
|
|
731
734
|
center: center,
|
|
732
735
|
zoom: map.getZoom(),
|
package/src/traces/bar/plot.js
CHANGED
|
@@ -428,7 +428,7 @@ function appendBarText(gd, plotinfo, bar, cd, i, x0, x1, y0, y1, opts, makeOnCom
|
|
|
428
428
|
}
|
|
429
429
|
|
|
430
430
|
transform.fontSize = font.size;
|
|
431
|
-
recordMinTextSize(trace.type, transform, fullLayout);
|
|
431
|
+
recordMinTextSize(trace.type === 'histogram' ? 'bar' : trace.type, transform, fullLayout);
|
|
432
432
|
calcBar.transform = transform;
|
|
433
433
|
|
|
434
434
|
transition(textSelection, fullLayout, opts, makeOnCompleteCallback)
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
var barAttrs = require('../bar/attributes');
|
|
4
4
|
var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
|
|
5
5
|
var hovertemplateAttrs = require('../../plots/template_attributes').hovertemplateAttrs;
|
|
6
|
+
var texttemplateAttrs = require('../../plots/template_attributes').texttemplateAttrs;
|
|
7
|
+
var fontAttrs = require('../../plots/font_attributes');
|
|
6
8
|
var makeBinAttrs = require('./bin_attributes');
|
|
7
9
|
var constants = require('./constants');
|
|
8
10
|
var extendFlat = require('../../lib/extend').extendFlat;
|
|
@@ -198,6 +200,44 @@ module.exports = {
|
|
|
198
200
|
keys: constants.eventDataKeys
|
|
199
201
|
}),
|
|
200
202
|
|
|
203
|
+
texttemplate: texttemplateAttrs({
|
|
204
|
+
arrayOk: false,
|
|
205
|
+
editType: 'plot'
|
|
206
|
+
}, {
|
|
207
|
+
keys: ['label', 'value']
|
|
208
|
+
}),
|
|
209
|
+
|
|
210
|
+
textposition: extendFlat({}, barAttrs.textposition, {
|
|
211
|
+
arrayOk: false
|
|
212
|
+
}),
|
|
213
|
+
|
|
214
|
+
textfont: fontAttrs({
|
|
215
|
+
arrayOk: false,
|
|
216
|
+
editType: 'plot',
|
|
217
|
+
colorEditType: 'style',
|
|
218
|
+
description: 'Sets the text font.'
|
|
219
|
+
}),
|
|
220
|
+
|
|
221
|
+
outsidetextfont: fontAttrs({
|
|
222
|
+
arrayOk: false,
|
|
223
|
+
editType: 'plot',
|
|
224
|
+
colorEditType: 'style',
|
|
225
|
+
description: 'Sets the font used for `text` lying outside the bar.'
|
|
226
|
+
}),
|
|
227
|
+
|
|
228
|
+
insidetextfont: fontAttrs({
|
|
229
|
+
arrayOk: false,
|
|
230
|
+
editType: 'plot',
|
|
231
|
+
colorEditType: 'style',
|
|
232
|
+
description: 'Sets the font used for `text` lying inside the bar.'
|
|
233
|
+
}),
|
|
234
|
+
|
|
235
|
+
insidetextanchor: barAttrs.insidetextanchor,
|
|
236
|
+
|
|
237
|
+
textangle: barAttrs.textangle,
|
|
238
|
+
cliponaxis: barAttrs.cliponaxis,
|
|
239
|
+
constraintext: barAttrs.constraintext,
|
|
240
|
+
|
|
201
241
|
marker: barAttrs.marker,
|
|
202
242
|
|
|
203
243
|
offsetgroup: barAttrs.offsetgroup,
|
|
@@ -4,6 +4,7 @@ var Registry = require('../../registry');
|
|
|
4
4
|
var Lib = require('../../lib');
|
|
5
5
|
var Color = require('../../components/color');
|
|
6
6
|
|
|
7
|
+
var handleText = require('../bar/defaults').handleText;
|
|
7
8
|
var handleStyleDefaults = require('../bar/style_defaults');
|
|
8
9
|
var attributes = require('./attributes');
|
|
9
10
|
|
|
@@ -22,6 +23,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
coerce('text');
|
|
26
|
+
var textposition = coerce('textposition');
|
|
27
|
+
handleText(traceIn, traceOut, layout, coerce, textposition, {
|
|
28
|
+
moduleHasSelected: true,
|
|
29
|
+
moduleHasUnselected: true,
|
|
30
|
+
moduleHasConstrain: true,
|
|
31
|
+
moduleHasCliponaxis: true,
|
|
32
|
+
moduleHasTextangle: true,
|
|
33
|
+
moduleHasInsideanchor: true
|
|
34
|
+
});
|
|
35
|
+
|
|
25
36
|
coerce('hovertext');
|
|
26
37
|
coerce('hovertemplate');
|
|
27
38
|
coerce('xhoverformat');
|
package/src/version.js
CHANGED