plotly.js 2.6.2 → 2.8.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 +43 -0
- package/README.md +3 -3
- package/dist/README.md +26 -26
- package/dist/plot-schema.json +1015 -407
- package/dist/plotly-basic.js +568 -225
- package/dist/plotly-basic.min.js +4 -4
- package/dist/plotly-cartesian.js +1029 -371
- package/dist/plotly-cartesian.min.js +3 -3
- package/dist/plotly-finance.js +618 -227
- package/dist/plotly-finance.min.js +4 -4
- package/dist/plotly-geo-assets.js +2 -2
- package/dist/plotly-geo.js +564 -223
- package/dist/plotly-geo.min.js +2 -2
- package/dist/plotly-gl2d.js +580 -224
- package/dist/plotly-gl2d.min.js +2 -2
- package/dist/plotly-gl3d.js +564 -223
- package/dist/plotly-gl3d.min.js +2 -2
- package/dist/plotly-mapbox.js +570 -226
- package/dist/plotly-mapbox.min.js +2 -2
- package/dist/plotly-strict.js +1253 -592
- package/dist/plotly-strict.min.js +3 -3
- package/dist/plotly-with-meta.js +1345 -654
- package/dist/plotly.js +1307 -646
- package/dist/plotly.min.js +10 -10
- package/package.json +9 -9
- package/src/components/colorbar/attributes.js +29 -20
- package/src/components/colorbar/defaults.js +30 -8
- package/src/components/colorbar/draw.js +398 -141
- package/src/components/drawing/index.js +6 -3
- package/src/components/fx/hover.js +16 -17
- package/src/components/fx/hoverlabel_defaults.js +4 -2
- package/src/components/fx/layout_attributes.js +14 -4
- package/src/components/fx/layout_defaults.js +2 -0
- package/src/components/legend/attributes.js +7 -0
- package/src/components/legend/defaults.js +24 -7
- package/src/components/titles/index.js +8 -2
- package/src/plot_api/plot_api.js +38 -9
- package/src/plots/font_attributes.js +3 -0
- package/src/plots/layout_attributes.js +1 -0
- package/src/plots/mapbox/mapbox.js +6 -3
- package/src/plots/plots.js +7 -15
- package/src/traces/bar/plot.js +1 -1
- package/src/traces/contour/attributes.js +12 -0
- package/src/traces/contour/defaults.js +9 -1
- package/src/traces/heatmap/attributes.js +16 -0
- package/src/traces/heatmap/defaults.js +2 -0
- package/src/traces/heatmap/label_defaults.js +13 -0
- package/src/traces/heatmap/plot.js +203 -4
- package/src/traces/histogram/attributes.js +40 -0
- package/src/traces/histogram/defaults.js +11 -0
- package/src/traces/histogram2d/attributes.js +8 -0
- package/src/traces/histogram2d/defaults.js +4 -0
- package/src/traces/histogram2dcontour/attributes.js +3 -1
- package/src/traces/histogram2dcontour/defaults.js +8 -1
- package/src/traces/pie/calc.js +3 -1
- package/src/version.js +1 -1
- package/tasks/test_mock.js +1 -0
|
@@ -167,6 +167,21 @@ function makeColorBarData(gd) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
function drawColorBar(g, opts, gd) {
|
|
170
|
+
var isVertical = opts.orientation === 'v';
|
|
171
|
+
var len = opts.len;
|
|
172
|
+
var lenmode = opts.lenmode;
|
|
173
|
+
var thickness = opts.thickness;
|
|
174
|
+
var thicknessmode = opts.thicknessmode;
|
|
175
|
+
var outlinewidth = opts.outlinewidth;
|
|
176
|
+
var borderwidth = opts.borderwidth;
|
|
177
|
+
var bgcolor = opts.bgcolor;
|
|
178
|
+
var xanchor = opts.xanchor;
|
|
179
|
+
var yanchor = opts.yanchor;
|
|
180
|
+
var xpad = opts.xpad;
|
|
181
|
+
var ypad = opts.ypad;
|
|
182
|
+
var optsX = opts.x;
|
|
183
|
+
var optsY = isVertical ? opts.y : 1 - opts.y;
|
|
184
|
+
|
|
170
185
|
var fullLayout = gd._fullLayout;
|
|
171
186
|
var gs = fullLayout._size;
|
|
172
187
|
|
|
@@ -196,42 +211,64 @@ function drawColorBar(g, opts, gd) {
|
|
|
196
211
|
// when the colorbar itself is pushing the margins.
|
|
197
212
|
// but then the fractional size is calculated based on the
|
|
198
213
|
// actual graph size, so that the axes will size correctly.
|
|
199
|
-
var thickPx = Math.round(
|
|
200
|
-
var thickFrac = thickPx / gs.w;
|
|
201
|
-
var lenPx = Math.round(
|
|
202
|
-
var lenFrac = lenPx / gs.h;
|
|
203
|
-
var xpadFrac = opts.xpad / gs.w;
|
|
204
|
-
var yExtraPx = (opts.borderwidth + opts.outlinewidth) / 2;
|
|
205
|
-
var ypadFrac = opts.ypad / gs.h;
|
|
214
|
+
var thickPx = Math.round(thickness * (thicknessmode === 'fraction' ? (isVertical ? gs.w : gs.h) : 1));
|
|
215
|
+
var thickFrac = thickPx / (isVertical ? gs.w : gs.h);
|
|
216
|
+
var lenPx = Math.round(len * (lenmode === 'fraction' ? (isVertical ? gs.h : gs.w) : 1));
|
|
217
|
+
var lenFrac = lenPx / (isVertical ? gs.h : gs.w);
|
|
206
218
|
|
|
207
219
|
// x positioning: do it initially just for left anchor,
|
|
208
220
|
// then fix at the end (since we don't know the width yet)
|
|
209
|
-
var
|
|
221
|
+
var uPx = Math.round(isVertical ?
|
|
222
|
+
optsX * gs.w + xpad :
|
|
223
|
+
optsY * gs.h + ypad
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
var xRatio = {center: 0.5, right: 1}[xanchor] || 0;
|
|
227
|
+
var yRatio = {top: 1, middle: 0.5}[yanchor] || 0;
|
|
228
|
+
|
|
210
229
|
// for dragging... this is getting a little muddled...
|
|
211
|
-
var
|
|
230
|
+
var uFrac = isVertical ?
|
|
231
|
+
optsX - xRatio * thickFrac :
|
|
232
|
+
optsY - yRatio * thickFrac;
|
|
233
|
+
|
|
234
|
+
// y/x positioning (for v/h) we can do correctly from the start
|
|
235
|
+
var vFrac = isVertical ?
|
|
236
|
+
optsY - yRatio * lenFrac :
|
|
237
|
+
optsX - xRatio * lenFrac;
|
|
212
238
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
239
|
+
var vPx = Math.round(isVertical ?
|
|
240
|
+
gs.h * (1 - vFrac) :
|
|
241
|
+
gs.w * vFrac
|
|
242
|
+
);
|
|
217
243
|
|
|
218
244
|
// stash a few things for makeEditable
|
|
219
245
|
opts._lenFrac = lenFrac;
|
|
220
246
|
opts._thickFrac = thickFrac;
|
|
221
|
-
opts.
|
|
222
|
-
opts.
|
|
247
|
+
opts._uFrac = uFrac;
|
|
248
|
+
opts._vFrac = vFrac;
|
|
223
249
|
|
|
224
250
|
// stash mocked axis for contour label formatting
|
|
225
251
|
var ax = opts._axis = mockColorBarAxis(gd, opts, zrange);
|
|
226
252
|
|
|
227
253
|
// position can't go in through supplyDefaults
|
|
228
254
|
// because that restricts it to [0,1]
|
|
229
|
-
ax.position =
|
|
255
|
+
ax.position = thickFrac + (isVertical ?
|
|
256
|
+
optsX + xpad / gs.w :
|
|
257
|
+
optsY + ypad / gs.h
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
var topOrBottom = ['top', 'bottom'].indexOf(titleSide) !== -1;
|
|
261
|
+
|
|
262
|
+
if(isVertical && topOrBottom) {
|
|
263
|
+
ax.title.side = titleSide;
|
|
264
|
+
ax.titlex = optsX + xpad / gs.w;
|
|
265
|
+
ax.titley = vFrac + (title.side === 'top' ? lenFrac - ypad / gs.h : ypad / gs.h);
|
|
266
|
+
}
|
|
230
267
|
|
|
231
|
-
if(
|
|
268
|
+
if(!isVertical && !topOrBottom) {
|
|
232
269
|
ax.title.side = titleSide;
|
|
233
|
-
ax.
|
|
234
|
-
ax.
|
|
270
|
+
ax.titley = optsY + ypad / gs.h;
|
|
271
|
+
ax.titlex = vFrac + xpad / gs.w; // right side
|
|
235
272
|
}
|
|
236
273
|
|
|
237
274
|
if(line.color && opts.tickmode === 'auto') {
|
|
@@ -239,7 +276,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
239
276
|
ax.tick0 = levelsIn.start;
|
|
240
277
|
var dtick = levelsIn.size;
|
|
241
278
|
// expand if too many contours, so we don't get too many ticks
|
|
242
|
-
var autoNtick = Lib.constrain(
|
|
279
|
+
var autoNtick = Lib.constrain(lenPx / 50, 4, 15) + 1;
|
|
243
280
|
var dtFactor = (zrange[1] - zrange[0]) / ((opts.nticks || autoNtick) * dtick);
|
|
244
281
|
if(dtFactor > 1) {
|
|
245
282
|
var dtexp = Math.pow(10, Math.floor(Math.log(dtFactor) / Math.LN10));
|
|
@@ -256,9 +293,12 @@ function drawColorBar(g, opts, gd) {
|
|
|
256
293
|
|
|
257
294
|
// set domain after init, because we may want to
|
|
258
295
|
// allow it outside [0,1]
|
|
259
|
-
ax.domain = [
|
|
260
|
-
|
|
261
|
-
|
|
296
|
+
ax.domain = isVertical ? [
|
|
297
|
+
vFrac + ypad / gs.h,
|
|
298
|
+
vFrac + lenFrac - ypad / gs.h
|
|
299
|
+
] : [
|
|
300
|
+
vFrac + xpad / gs.w,
|
|
301
|
+
vFrac + lenFrac - xpad / gs.w
|
|
262
302
|
];
|
|
263
303
|
|
|
264
304
|
ax.setScale();
|
|
@@ -268,9 +308,13 @@ function drawColorBar(g, opts, gd) {
|
|
|
268
308
|
var titleCont = g.select('.' + cn.cbtitleunshift)
|
|
269
309
|
.attr('transform', strTranslate(-Math.round(gs.l), -Math.round(gs.t)));
|
|
270
310
|
|
|
311
|
+
var ticklabelposition = ax.ticklabelposition;
|
|
312
|
+
var titleFontSize = ax.title.font.size;
|
|
313
|
+
|
|
271
314
|
var axLayer = g.select('.' + cn.cbaxis);
|
|
272
315
|
var titleEl;
|
|
273
316
|
var titleHeight = 0;
|
|
317
|
+
var titleWidth = 0;
|
|
274
318
|
|
|
275
319
|
function drawTitle(titleClass, titleOpts) {
|
|
276
320
|
var dfltTitleOpts = {
|
|
@@ -295,58 +339,102 @@ function drawColorBar(g, opts, gd) {
|
|
|
295
339
|
}
|
|
296
340
|
|
|
297
341
|
function drawDummyTitle() {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
342
|
+
// draw the title so we know how much room it needs
|
|
343
|
+
// when we squish the axis.
|
|
344
|
+
// On vertical colorbars this only applies to top or bottom titles, not right side.
|
|
345
|
+
// On horizontal colorbars this only applies to right, etc.
|
|
346
|
+
|
|
347
|
+
if(
|
|
348
|
+
(isVertical && topOrBottom) ||
|
|
349
|
+
(!isVertical && !topOrBottom)
|
|
350
|
+
) {
|
|
351
|
+
var x, y;
|
|
305
352
|
|
|
306
353
|
if(titleSide === 'top') {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
|
|
354
|
+
x = xpad + gs.l + gs.w * optsX;
|
|
355
|
+
y = ypad + gs.t + gs.h * (1 - vFrac - lenFrac) + 3 + titleFontSize * 0.75;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if(titleSide === 'bottom') {
|
|
359
|
+
x = xpad + gs.l + gs.w * optsX;
|
|
360
|
+
y = ypad + gs.t + gs.h * (1 - vFrac) - 3 - titleFontSize * 0.25;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if(titleSide === 'right') {
|
|
364
|
+
y = ypad + gs.t + gs.h * optsY + 3 + titleFontSize * 0.75;
|
|
365
|
+
x = xpad + gs.l + gs.w * vFrac;
|
|
312
366
|
}
|
|
367
|
+
|
|
313
368
|
drawTitle(ax._id + 'title', {
|
|
314
|
-
attributes: {x: x, y: y, 'text-anchor': 'start'}
|
|
369
|
+
attributes: {x: x, y: y, 'text-anchor': isVertical ? 'start' : 'middle'}
|
|
315
370
|
});
|
|
316
371
|
}
|
|
317
372
|
}
|
|
318
373
|
|
|
319
374
|
function drawCbTitle() {
|
|
320
|
-
if(
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
375
|
+
if(
|
|
376
|
+
(isVertical && !topOrBottom) ||
|
|
377
|
+
(!isVertical && topOrBottom)
|
|
378
|
+
) {
|
|
379
|
+
var pos = ax.position || 0;
|
|
380
|
+
var mid = ax._offset + ax._length / 2;
|
|
381
|
+
var x, y;
|
|
382
|
+
|
|
383
|
+
if(titleSide === 'right') {
|
|
384
|
+
y = mid;
|
|
385
|
+
x = gs.l + gs.w * pos + 10 + titleFontSize * (
|
|
386
|
+
ax.showticklabels ? 1 : 0.5
|
|
387
|
+
);
|
|
388
|
+
} else {
|
|
389
|
+
x = mid;
|
|
390
|
+
|
|
391
|
+
if(titleSide === 'bottom') {
|
|
392
|
+
y = gs.t + gs.h * pos + 10 + (
|
|
393
|
+
ticklabelposition.indexOf('inside') === -1 ?
|
|
394
|
+
ax.tickfont.size :
|
|
395
|
+
0
|
|
396
|
+
) + (
|
|
397
|
+
ax.ticks !== 'intside' ?
|
|
398
|
+
opts.ticklen || 0 :
|
|
399
|
+
0
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if(titleSide === 'top') {
|
|
404
|
+
var nlines = title.text.split('<br>').length;
|
|
405
|
+
y = gs.t + gs.h * pos + 10 - thickPx - LINE_SPACING * titleFontSize * nlines;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
drawTitle((isVertical ?
|
|
410
|
+
// the 'h' + is a hack to get around the fact that
|
|
411
|
+
// convertToTspans rotates any 'y...' class by 90 degrees.
|
|
412
|
+
// TODO: find a better way to control this.
|
|
413
|
+
'h' :
|
|
414
|
+
'v'
|
|
415
|
+
) + ax._id + 'title', {
|
|
331
416
|
avoid: {
|
|
332
417
|
selection: d3.select(gd).selectAll('g.' + ax._id + 'tick'),
|
|
333
418
|
side: titleSide,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
maxShift: fullLayout.width
|
|
419
|
+
offsetTop: isVertical ? 0 : gs.t,
|
|
420
|
+
offsetLeft: isVertical ? gs.l : 0,
|
|
421
|
+
maxShift: isVertical ? fullLayout.width : fullLayout.height
|
|
337
422
|
},
|
|
338
423
|
attributes: {x: x, y: y, 'text-anchor': 'middle'},
|
|
339
|
-
transform: {rotate:
|
|
424
|
+
transform: {rotate: isVertical ? -90 : 0, offset: 0}
|
|
340
425
|
});
|
|
341
426
|
}
|
|
342
427
|
}
|
|
343
428
|
|
|
344
429
|
function drawAxis() {
|
|
345
|
-
if(
|
|
430
|
+
if(
|
|
431
|
+
(!isVertical && !topOrBottom) ||
|
|
432
|
+
(isVertical && topOrBottom)
|
|
433
|
+
) {
|
|
346
434
|
// squish the axis top to make room for the title
|
|
347
435
|
var titleGroup = g.select('.' + cn.cbtitle);
|
|
348
436
|
var titleText = titleGroup.select('text');
|
|
349
|
-
var titleTrans = [-
|
|
437
|
+
var titleTrans = [-outlinewidth / 2, outlinewidth / 2];
|
|
350
438
|
var mathJaxNode = titleGroup
|
|
351
439
|
.select('.h' + ax._id + 'title-math-group')
|
|
352
440
|
.node();
|
|
@@ -354,39 +442,63 @@ function drawColorBar(g, opts, gd) {
|
|
|
354
442
|
if(titleText.node()) {
|
|
355
443
|
lineSize = parseInt(titleText.node().style.fontSize, 10) * LINE_SPACING;
|
|
356
444
|
}
|
|
445
|
+
|
|
446
|
+
var bb;
|
|
357
447
|
if(mathJaxNode) {
|
|
358
|
-
|
|
448
|
+
bb = Drawing.bBox(mathJaxNode);
|
|
449
|
+
titleWidth = bb.width;
|
|
450
|
+
titleHeight = bb.height;
|
|
359
451
|
if(titleHeight > lineSize) {
|
|
360
452
|
// not entirely sure how mathjax is doing
|
|
361
453
|
// vertical alignment, but this seems to work.
|
|
362
454
|
titleTrans[1] -= (titleHeight - lineSize) / 2;
|
|
363
455
|
}
|
|
364
456
|
} else if(titleText.node() && !titleText.classed(cn.jsPlaceholder)) {
|
|
365
|
-
|
|
457
|
+
bb = Drawing.bBox(titleText.node());
|
|
458
|
+
titleWidth = bb.width;
|
|
459
|
+
titleHeight = bb.height;
|
|
366
460
|
}
|
|
367
|
-
if(titleHeight) {
|
|
368
|
-
// buffer btwn colorbar and title
|
|
369
|
-
// TODO: configurable
|
|
370
|
-
titleHeight += 5;
|
|
371
461
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
462
|
+
if(isVertical) {
|
|
463
|
+
if(titleHeight) {
|
|
464
|
+
// buffer btwn colorbar and title
|
|
465
|
+
// TODO: configurable
|
|
466
|
+
titleHeight += 5;
|
|
467
|
+
|
|
468
|
+
if(titleSide === 'top') {
|
|
469
|
+
ax.domain[1] -= titleHeight / gs.h;
|
|
470
|
+
titleTrans[1] *= -1;
|
|
471
|
+
} else {
|
|
472
|
+
ax.domain[0] += titleHeight / gs.h;
|
|
473
|
+
var nlines = svgTextUtils.lineCount(titleText);
|
|
474
|
+
titleTrans[1] += (1 - nlines) * lineSize;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
|
|
478
|
+
ax.setScale();
|
|
479
|
+
}
|
|
480
|
+
} else { // horizontal colorbars
|
|
481
|
+
if(titleWidth) {
|
|
482
|
+
if(titleSide === 'right') {
|
|
483
|
+
ax.domain[0] += (titleWidth + titleFontSize / 2) / gs.w;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
|
|
487
|
+
ax.setScale();
|
|
379
488
|
}
|
|
380
|
-
|
|
381
|
-
titleGroup.attr('transform', strTranslate(titleTrans[0], titleTrans[1]));
|
|
382
|
-
ax.setScale();
|
|
383
489
|
}
|
|
384
490
|
}
|
|
385
491
|
|
|
386
492
|
g.selectAll('.' + cn.cbfills + ',.' + cn.cblines)
|
|
387
|
-
.attr('transform',
|
|
493
|
+
.attr('transform', isVertical ?
|
|
494
|
+
strTranslate(0, Math.round(gs.h * (1 - ax.domain[1]))) :
|
|
495
|
+
strTranslate(Math.round(gs.w * ax.domain[0]), 0)
|
|
496
|
+
);
|
|
388
497
|
|
|
389
|
-
axLayer.attr('transform',
|
|
498
|
+
axLayer.attr('transform', isVertical ?
|
|
499
|
+
strTranslate(0, Math.round(-gs.t)) :
|
|
500
|
+
strTranslate(Math.round(-gs.l), 0)
|
|
501
|
+
);
|
|
390
502
|
|
|
391
503
|
var fills = g.select('.' + cn.cbfills)
|
|
392
504
|
.selectAll('rect.' + cn.cbfill)
|
|
@@ -412,20 +524,22 @@ function drawColorBar(g, opts, gd) {
|
|
|
412
524
|
|
|
413
525
|
// offset the side adjoining the next rectangle so they
|
|
414
526
|
// overlap, to prevent antialiasing gaps
|
|
415
|
-
|
|
416
|
-
|
|
527
|
+
if(isVertical) {
|
|
528
|
+
z[1] = Lib.constrain(z[1] + (z[1] > z[0]) ? 1 : -1, zBounds[0], zBounds[1]);
|
|
529
|
+
} /* else {
|
|
530
|
+
// TODO: horizontal case
|
|
531
|
+
} */
|
|
417
532
|
|
|
418
533
|
// Colorbar cannot currently support opacities so we
|
|
419
534
|
// use an opaque fill even when alpha channels present
|
|
420
|
-
var fillEl = d3.select(this)
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
});
|
|
535
|
+
var fillEl = d3.select(this)
|
|
536
|
+
.attr(isVertical ? 'x' : 'y', uPx)
|
|
537
|
+
.attr(isVertical ? 'y' : 'x', d3.min(z))
|
|
538
|
+
.attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
|
|
539
|
+
.attr(isVertical ? 'height' : 'width', Math.max(d3.max(z) - d3.min(z), 2));
|
|
426
540
|
|
|
427
541
|
if(opts._fillgradient) {
|
|
428
|
-
Drawing.gradient(fillEl, gd, opts._id, 'vertical', opts._fillgradient, 'fill');
|
|
542
|
+
Drawing.gradient(fillEl, gd, opts._id, isVertical ? 'vertical' : 'horizontalreversed', opts._fillgradient, 'fill');
|
|
429
543
|
} else {
|
|
430
544
|
// tinycolor can't handle exponents and
|
|
431
545
|
// at this scale, removing it makes no difference.
|
|
@@ -441,17 +555,23 @@ function drawColorBar(g, opts, gd) {
|
|
|
441
555
|
.classed(cn.cbline, true);
|
|
442
556
|
lines.exit().remove();
|
|
443
557
|
lines.each(function(d) {
|
|
558
|
+
var a = uPx;
|
|
559
|
+
var b = (Math.round(ax.c2p(d)) + (line.width / 2) % 1);
|
|
560
|
+
|
|
444
561
|
d3.select(this)
|
|
445
|
-
.attr('d', 'M' +
|
|
446
|
-
(
|
|
562
|
+
.attr('d', 'M' +
|
|
563
|
+
(isVertical ? a + ',' + b : b + ',' + a) +
|
|
564
|
+
(isVertical ? 'h' : 'v') +
|
|
565
|
+
thickPx
|
|
566
|
+
)
|
|
447
567
|
.call(Drawing.lineGroupStyle, line.width, lineColormap(d), line.dash);
|
|
448
568
|
});
|
|
449
569
|
|
|
450
570
|
// force full redraw of labels and ticks
|
|
451
571
|
axLayer.selectAll('g.' + ax._id + 'tick,path').remove();
|
|
452
572
|
|
|
453
|
-
var shift =
|
|
454
|
-
(
|
|
573
|
+
var shift = uPx + thickPx +
|
|
574
|
+
(outlinewidth || 0) / 2 - (opts.ticks === 'outside' ? 1 : 0);
|
|
455
575
|
|
|
456
576
|
var vals = Axes.calcTicks(ax);
|
|
457
577
|
var tickSign = Axes.getTickSigns(ax)[2];
|
|
@@ -476,83 +596,211 @@ function drawColorBar(g, opts, gd) {
|
|
|
476
596
|
// TODO: why are we redrawing multiple times now with this?
|
|
477
597
|
// I guess autoMargin doesn't like being post-promise?
|
|
478
598
|
function positionCB() {
|
|
479
|
-
var
|
|
480
|
-
|
|
481
|
-
|
|
599
|
+
var bb;
|
|
600
|
+
var innerThickness = thickPx + outlinewidth / 2;
|
|
601
|
+
if(ticklabelposition.indexOf('inside') === -1) {
|
|
602
|
+
bb = Drawing.bBox(axLayer.node());
|
|
603
|
+
innerThickness += isVertical ? bb.width : bb.height;
|
|
482
604
|
}
|
|
483
605
|
|
|
484
606
|
titleEl = titleCont.select('text');
|
|
485
607
|
|
|
608
|
+
var titleWidth = 0;
|
|
609
|
+
|
|
610
|
+
var topSideVertical = isVertical && titleSide === 'top';
|
|
611
|
+
var rightSideHorizontal = !isVertical && titleSide === 'right';
|
|
612
|
+
|
|
613
|
+
var moveY = 0;
|
|
614
|
+
|
|
486
615
|
if(titleEl.node() && !titleEl.classed(cn.jsPlaceholder)) {
|
|
616
|
+
var _titleHeight;
|
|
617
|
+
|
|
487
618
|
var mathJaxNode = titleCont.select('.h' + ax._id + 'title-math-group').node();
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
619
|
+
if(mathJaxNode && (
|
|
620
|
+
(isVertical && topOrBottom) ||
|
|
621
|
+
(!isVertical && !topOrBottom)
|
|
622
|
+
)) {
|
|
623
|
+
bb = Drawing.bBox(mathJaxNode);
|
|
624
|
+
titleWidth = bb.width;
|
|
625
|
+
_titleHeight = bb.height;
|
|
491
626
|
} else {
|
|
492
627
|
// note: the formula below works for all title sides,
|
|
493
628
|
// (except for top/bottom mathjax, above)
|
|
494
629
|
// but the weird gs.l is because the titleunshift
|
|
495
630
|
// transform gets removed by Drawing.bBox
|
|
496
|
-
|
|
631
|
+
bb = Drawing.bBox(titleCont.node());
|
|
632
|
+
titleWidth = bb.right - gs.l - (isVertical ? uPx : vPx);
|
|
633
|
+
_titleHeight = bb.bottom - gs.t - (isVertical ? vPx : uPx);
|
|
634
|
+
|
|
635
|
+
if(
|
|
636
|
+
!isVertical && titleSide === 'top'
|
|
637
|
+
) {
|
|
638
|
+
innerThickness += bb.height;
|
|
639
|
+
moveY = bb.height;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if(rightSideHorizontal) {
|
|
644
|
+
titleEl.attr('transform', strTranslate(titleWidth / 2 + titleFontSize / 2, 0));
|
|
645
|
+
|
|
646
|
+
titleWidth *= 2;
|
|
497
647
|
}
|
|
498
|
-
|
|
648
|
+
|
|
649
|
+
innerThickness = Math.max(innerThickness,
|
|
650
|
+
isVertical ? titleWidth : _titleHeight
|
|
651
|
+
);
|
|
499
652
|
}
|
|
500
653
|
|
|
501
|
-
var
|
|
502
|
-
|
|
654
|
+
var outerThickness = (isVertical ?
|
|
655
|
+
xpad :
|
|
656
|
+
ypad
|
|
657
|
+
) * 2 + innerThickness + borderwidth + outlinewidth / 2;
|
|
658
|
+
|
|
659
|
+
var hColorbarMoveTitle = 0;
|
|
660
|
+
if(!isVertical && title.text && yanchor === 'bottom' && optsY <= 0) {
|
|
661
|
+
hColorbarMoveTitle = outerThickness / 2;
|
|
662
|
+
|
|
663
|
+
outerThickness += hColorbarMoveTitle;
|
|
664
|
+
moveY += hColorbarMoveTitle;
|
|
665
|
+
}
|
|
666
|
+
fullLayout._hColorbarMoveTitle = hColorbarMoveTitle;
|
|
667
|
+
fullLayout._hColorbarMoveCBTitle = moveY;
|
|
503
668
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
.
|
|
669
|
+
var extraW = borderwidth + outlinewidth;
|
|
670
|
+
|
|
671
|
+
g.select('.' + cn.cbbg)
|
|
672
|
+
.attr('x', (isVertical ? uPx : vPx) - extraW / 2 - (isVertical ? xpad : 0))
|
|
673
|
+
.attr('y', (isVertical ? vPx : uPx) - (isVertical ? lenPx : ypad + moveY - hColorbarMoveTitle))
|
|
674
|
+
.attr(isVertical ? 'width' : 'height', Math.max(outerThickness - hColorbarMoveTitle, 2))
|
|
675
|
+
.attr(isVertical ? 'height' : 'width', Math.max(lenPx + extraW, 2))
|
|
676
|
+
.call(Color.fill, bgcolor)
|
|
511
677
|
.call(Color.stroke, opts.bordercolor)
|
|
512
|
-
.style('stroke-width',
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
678
|
+
.style('stroke-width', borderwidth);
|
|
679
|
+
|
|
680
|
+
var moveX = rightSideHorizontal ? Math.max(titleWidth - 10, 0) : 0;
|
|
681
|
+
|
|
682
|
+
g.selectAll('.' + cn.cboutline)
|
|
683
|
+
.attr('x', (isVertical ? uPx : vPx + xpad) + moveX)
|
|
684
|
+
.attr('y', (isVertical ? vPx + ypad - lenPx : uPx) + (topSideVertical ? titleHeight : 0))
|
|
685
|
+
.attr(isVertical ? 'width' : 'height', Math.max(thickPx, 2))
|
|
686
|
+
.attr(isVertical ? 'height' : 'width', Math.max(lenPx - (isVertical ?
|
|
687
|
+
2 * ypad + titleHeight :
|
|
688
|
+
2 * xpad + moveX
|
|
689
|
+
), 2))
|
|
520
690
|
.call(Color.stroke, opts.outlinecolor)
|
|
521
691
|
.style({
|
|
522
692
|
fill: 'none',
|
|
523
|
-
'stroke-width':
|
|
693
|
+
'stroke-width': outlinewidth
|
|
524
694
|
});
|
|
525
695
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
696
|
+
g.attr('transform', strTranslate(
|
|
697
|
+
gs.l - (isVertical ? xRatio * outerThickness : 0),
|
|
698
|
+
gs.t - (isVertical ? 0 : (1 - yRatio) * outerThickness - moveY)
|
|
699
|
+
));
|
|
700
|
+
|
|
701
|
+
if(!isVertical && (
|
|
702
|
+
borderwidth || (
|
|
703
|
+
tinycolor(bgcolor).getAlpha() &&
|
|
704
|
+
!tinycolor.equals(fullLayout.paper_bgcolor, bgcolor)
|
|
705
|
+
)
|
|
706
|
+
)) {
|
|
707
|
+
// for horizontal colorbars when there is a border line or having different background color
|
|
708
|
+
// hide/adjust x positioning for the first/last tick labels if they go outside the border
|
|
709
|
+
var tickLabels = axLayer.selectAll('text');
|
|
710
|
+
var numTicks = tickLabels[0].length;
|
|
711
|
+
|
|
712
|
+
var border = g.select('.' + cn.cbbg).node();
|
|
713
|
+
var oBb = Drawing.bBox(border);
|
|
714
|
+
var oTr = Drawing.getTranslate(g);
|
|
715
|
+
|
|
716
|
+
var TEXTPAD = 2;
|
|
717
|
+
|
|
718
|
+
tickLabels.each(function(d, i) {
|
|
719
|
+
var first = 0;
|
|
720
|
+
var last = numTicks - 1;
|
|
721
|
+
if(i === first || i === last) {
|
|
722
|
+
var iBb = Drawing.bBox(this);
|
|
723
|
+
var iTr = Drawing.getTranslate(this);
|
|
724
|
+
var deltaX;
|
|
725
|
+
|
|
726
|
+
if(i === last) {
|
|
727
|
+
var iRight = iBb.right + iTr.x;
|
|
728
|
+
var oRight = oBb.right + oTr.x + vPx - borderwidth - TEXTPAD + optsX;
|
|
729
|
+
|
|
730
|
+
deltaX = oRight - iRight;
|
|
731
|
+
if(deltaX > 0) deltaX = 0;
|
|
732
|
+
} else if(i === first) {
|
|
733
|
+
var iLeft = iBb.left + iTr.x;
|
|
734
|
+
var oLeft = oBb.left + oTr.x + vPx + borderwidth + TEXTPAD;
|
|
735
|
+
|
|
736
|
+
deltaX = oLeft - iLeft;
|
|
737
|
+
if(deltaX < 0) deltaX = 0;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
if(deltaX) {
|
|
741
|
+
if(numTicks < 3) { // adjust position
|
|
742
|
+
this.setAttribute('transform',
|
|
743
|
+
'translate(' + deltaX + ',0) ' +
|
|
744
|
+
this.getAttribute('transform')
|
|
745
|
+
);
|
|
746
|
+
} else { // hide
|
|
747
|
+
this.setAttribute('visibility', 'hidden');
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
}
|
|
529
753
|
|
|
530
754
|
// auto margin adjustment
|
|
531
755
|
var marginOpts = {};
|
|
532
|
-
var
|
|
533
|
-
var
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
756
|
+
var lFrac = FROM_TL[xanchor];
|
|
757
|
+
var rFrac = FROM_BR[xanchor];
|
|
758
|
+
var tFrac = FROM_TL[yanchor];
|
|
759
|
+
var bFrac = FROM_BR[yanchor];
|
|
760
|
+
|
|
761
|
+
var extraThickness = outerThickness - thickPx;
|
|
762
|
+
if(isVertical) {
|
|
763
|
+
if(lenmode === 'pixels') {
|
|
764
|
+
marginOpts.y = optsY;
|
|
765
|
+
marginOpts.t = lenPx * tFrac;
|
|
766
|
+
marginOpts.b = lenPx * bFrac;
|
|
767
|
+
} else {
|
|
768
|
+
marginOpts.t = marginOpts.b = 0;
|
|
769
|
+
marginOpts.yt = optsY + len * tFrac;
|
|
770
|
+
marginOpts.yb = optsY - len * bFrac;
|
|
771
|
+
}
|
|
543
772
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
773
|
+
if(thicknessmode === 'pixels') {
|
|
774
|
+
marginOpts.x = optsX;
|
|
775
|
+
marginOpts.l = outerThickness * lFrac;
|
|
776
|
+
marginOpts.r = outerThickness * rFrac;
|
|
777
|
+
} else {
|
|
778
|
+
marginOpts.l = extraThickness * lFrac;
|
|
779
|
+
marginOpts.r = extraThickness * rFrac;
|
|
780
|
+
marginOpts.xl = optsX - thickness * lFrac;
|
|
781
|
+
marginOpts.xr = optsX + thickness * rFrac;
|
|
782
|
+
}
|
|
783
|
+
} else { // horizontal colorbars
|
|
784
|
+
if(lenmode === 'pixels') {
|
|
785
|
+
marginOpts.x = optsX;
|
|
786
|
+
marginOpts.l = lenPx * lFrac;
|
|
787
|
+
marginOpts.r = lenPx * rFrac;
|
|
788
|
+
} else {
|
|
789
|
+
marginOpts.l = marginOpts.r = 0;
|
|
790
|
+
marginOpts.xl = optsX + len * lFrac;
|
|
791
|
+
marginOpts.xr = optsX - len * rFrac;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
if(thicknessmode === 'pixels') {
|
|
795
|
+
marginOpts.y = 1 - optsY;
|
|
796
|
+
marginOpts.t = outerThickness * tFrac;
|
|
797
|
+
marginOpts.b = outerThickness * bFrac;
|
|
798
|
+
} else {
|
|
799
|
+
marginOpts.t = extraThickness * tFrac;
|
|
800
|
+
marginOpts.b = extraThickness * bFrac;
|
|
801
|
+
marginOpts.yt = optsY - thickness * tFrac;
|
|
802
|
+
marginOpts.yb = optsY + thickness * bFrac;
|
|
803
|
+
}
|
|
556
804
|
}
|
|
557
805
|
|
|
558
806
|
Plots.autoMargin(gd, opts._id, marginOpts);
|
|
@@ -569,6 +817,7 @@ function drawColorBar(g, opts, gd) {
|
|
|
569
817
|
}
|
|
570
818
|
|
|
571
819
|
function makeEditable(g, opts, gd) {
|
|
820
|
+
var isVertical = opts.orientation === 'v';
|
|
572
821
|
var fullLayout = gd._fullLayout;
|
|
573
822
|
var gs = fullLayout._size;
|
|
574
823
|
var t0, xf, yf;
|
|
@@ -583,9 +832,13 @@ function makeEditable(g, opts, gd) {
|
|
|
583
832
|
moveFn: function(dx, dy) {
|
|
584
833
|
g.attr('transform', t0 + strTranslate(dx, dy));
|
|
585
834
|
|
|
586
|
-
xf = dragElement.align(
|
|
835
|
+
xf = dragElement.align(
|
|
836
|
+
(isVertical ? opts._uFrac : opts._vFrac) + (dx / gs.w),
|
|
837
|
+
isVertical ? opts._thickFrac : opts._lenFrac,
|
|
587
838
|
0, 1, opts.xanchor);
|
|
588
|
-
yf = dragElement.align(
|
|
839
|
+
yf = dragElement.align(
|
|
840
|
+
(isVertical ? opts._vFrac : (1 - opts._uFrac)) - (dy / gs.h),
|
|
841
|
+
isVertical ? opts._lenFrac : opts._thickFrac,
|
|
589
842
|
0, 1, opts.yanchor);
|
|
590
843
|
|
|
591
844
|
var csr = dragElement.getCursor(xf, yf, opts.xanchor, opts.yanchor);
|
|
@@ -662,6 +915,8 @@ function calcLevels(gd, opts, zrange) {
|
|
|
662
915
|
function mockColorBarAxis(gd, opts, zrange) {
|
|
663
916
|
var fullLayout = gd._fullLayout;
|
|
664
917
|
|
|
918
|
+
var isVertical = opts.orientation === 'v';
|
|
919
|
+
|
|
665
920
|
var cbAxisIn = {
|
|
666
921
|
type: 'linear',
|
|
667
922
|
range: zrange,
|
|
@@ -692,17 +947,19 @@ function mockColorBarAxis(gd, opts, zrange) {
|
|
|
692
947
|
title: opts.title,
|
|
693
948
|
showline: true,
|
|
694
949
|
anchor: 'free',
|
|
695
|
-
side: 'right',
|
|
950
|
+
side: isVertical ? 'right' : 'bottom',
|
|
696
951
|
position: 1
|
|
697
952
|
};
|
|
698
953
|
|
|
954
|
+
var letter = isVertical ? 'y' : 'x';
|
|
955
|
+
|
|
699
956
|
var cbAxisOut = {
|
|
700
957
|
type: 'linear',
|
|
701
|
-
_id:
|
|
958
|
+
_id: letter + opts._id
|
|
702
959
|
};
|
|
703
960
|
|
|
704
961
|
var axisOptions = {
|
|
705
|
-
letter:
|
|
962
|
+
letter: letter,
|
|
706
963
|
font: fullLayout.font,
|
|
707
964
|
noHover: true,
|
|
708
965
|
noTickson: true,
|