Skip to content

Commit 46858a7

Browse files
committed
Merge branch 'master' into scatter-select-perf
2 parents 4adc091 + 776ddca commit 46858a7

File tree

113 files changed

+2215
-1138
lines changed

Some content is hidden

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

113 files changed

+2215
-1138
lines changed

lib/locales/sw.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Copyright 2012-2018, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
module.exports = {
12+
moduleType: 'locale',
13+
name: 'sw',
14+
dictionary: {
15+
'Autoscale': 'Kigezo - otomatiki',
16+
'Box Select': 'Teua kisanduku',
17+
'Click to enter Colorscale title': 'Bonyeza kuandika kichwa cha Colorscale',
18+
'Click to enter Component A title': 'Bonyeza kuandika kichwa cha sehemu A',
19+
'Click to enter Component B title': 'Bonyeza kuandika kichwa cha sehemu B',
20+
'Click to enter Component C title': 'Bonyeza kuandika kichwa cha sehemu C',
21+
'Click to enter Plot title': 'Bonyeza kuandika kichwa cha Plot',
22+
'Click to enter X axis title': 'Bonyeza kuandika kichwa cha mhimili wa X',
23+
'Click to enter Y axis title': 'Bonyeza kuandika kichwa cha mhimili wa Y',
24+
'Click to enter radial axis title': 'Bonyeza kuandika kichwa cha mhimili wa radial',
25+
'Compare data on hover': 'Linganisha data kwa kuelea kielekezi',
26+
'Double-click on legend to isolate one trace': 'Bonyeza mara mbili juu ya hadithi ili kutenganisha moja kwa moja',
27+
'Double-click to zoom back out': 'Bonyeza mara mbili ili kuvuta nje',
28+
'Download plot as a png': 'Pakua mpango kama png',
29+
'Edit in Chart Studio': 'Hariri katika Chart studio',
30+
'IE only supports svg. Changing format to svg.': 'IE inatumia tu svg. Tunabadilisha muundo kuwa svg.',
31+
'Lasso Select': 'Kuteua lasso',
32+
'Orbital rotation': 'Mzunguko wa mazao',
33+
'Pan': 'Tandaza',
34+
'Produced with Plotly': 'Ilitengenezwa na Plotly',
35+
'Reset': 'Weka upya',
36+
'Reset axes': 'Weka upya axes',
37+
'Reset camera to default': 'Rudisha kamera kwenye uhifadhi wa default',
38+
'Reset camera to last save': 'Rudisha kamera kwenye uhifadhi wa mwisho',
39+
'Reset view': 'Weka upya mtazamo',
40+
'Reset views': 'Weka upya maoni',
41+
'Show closest data on hover': 'Onyesha data iliyo karibu zaidi kielekezi kinapoelea',
42+
'Snapshot succeeded': 'Snapshot ilifanikiwa',
43+
'Sorry, there was a problem downloading your snapshot!': 'Samahani, kulikuwa na shida kupakua picha yako!',
44+
'Taking snapshot - this may take a few seconds': 'Kuchukua snapshot - hii inaweza kuchukua sekunde chache',
45+
'Toggle Spike Lines': 'Badilisha Mistari ya Spike',
46+
'Toggle show closest data on hover': 'Badilisha mabadiliko ya karibu zaidi kwenye hover',
47+
'Turntable rotation': 'Zunguka kwa mhimili wa Z',
48+
'Zoom': 'Vuta',
49+
'Zoom in': 'Vuta nje',
50+
'Zoom out': 'Vuta ndani',
51+
'close:': 'funga:',
52+
'high:': 'juu:',
53+
'incoming flow count:': 'hesabu ya mtiririko unaokuja:',
54+
'kde:': 'kde:',
55+
'lat:': 'lat:',
56+
'lon:': 'lon:',
57+
'low:': 'chini:',
58+
'lower fence:': 'fensi ya chini:',
59+
'max:': 'upeo:',
60+
'mean ± σ:': 'maana ± σ:',
61+
'mean:': 'maana:',
62+
'median:': 'wastani:',
63+
'min:': 'kidogo:',
64+
'new text': 'nakala mpya',
65+
'open:': 'fungua:',
66+
'outgoing flow count:': 'hesabu ya mtiririko unaotoka:',
67+
'q1:': 'q1:',
68+
'q3:': 'q3:',
69+
'source:': 'chanzo:',
70+
'target:': 'lengo:',
71+
'trace': 'fuatilia',
72+
'upper fence:': 'Fensi ya juu:'
73+
},
74+
format: {
75+
days: ['Jumapili', 'Jumatatu', 'Jumanne', 'Jumatano', 'Alhamisi', 'Ijumaa', 'Jumamosi'],
76+
shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
77+
months: ['Januari', 'Februari', 'Machi', 'Aprili', 'Mei', 'Juni', 'Julai', 'Agosti', 'Septemba', 'Oktoba', 'Novemba', 'Desemba'],
78+
shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Ago', 'Sep', 'Okt', 'Nov', 'Des'],
79+
date: '%d/%m/%Y',
80+
decimal: '.',
81+
thousands: ','
82+
}
83+
};

src/components/colorscale/calc.js

+49-24
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,47 @@ var flipScale = require('./flip_scale');
1616

1717

1818
module.exports = function calc(trace, vals, containerStr, cLetter) {
19-
var container, inputContainer;
19+
var container = trace;
20+
var inputContainer = trace._input;
21+
var fullInputContainer = trace._fullInput;
22+
23+
// set by traces with groupby transforms
24+
var updateStyle = trace.updateStyle;
25+
26+
function doUpdate(attr, inputVal, fullVal) {
27+
if(fullVal === undefined) fullVal = inputVal;
28+
29+
if(updateStyle) {
30+
updateStyle(trace._input, containerStr ? (containerStr + '.' + attr) : attr, inputVal);
31+
}
32+
else {
33+
inputContainer[attr] = inputVal;
34+
}
35+
36+
container[attr] = fullVal;
37+
if(fullInputContainer && (trace !== trace._fullInput)) {
38+
if(updateStyle) {
39+
updateStyle(trace._fullInput, containerStr ? (containerStr + '.' + attr) : attr, fullVal);
40+
}
41+
else {
42+
fullInputContainer[attr] = fullVal;
43+
}
44+
}
45+
}
2046

2147
if(containerStr) {
22-
container = Lib.nestedProperty(trace, containerStr).get();
23-
inputContainer = Lib.nestedProperty(trace._input, containerStr).get();
24-
}
25-
else {
26-
container = trace;
27-
inputContainer = trace._input;
48+
container = Lib.nestedProperty(container, containerStr).get();
49+
inputContainer = Lib.nestedProperty(inputContainer, containerStr).get();
50+
fullInputContainer = Lib.nestedProperty(fullInputContainer, containerStr).get() || {};
2851
}
2952

30-
var autoAttr = cLetter + 'auto',
31-
minAttr = cLetter + 'min',
32-
maxAttr = cLetter + 'max',
33-
auto = container[autoAttr],
34-
min = container[minAttr],
35-
max = container[maxAttr],
36-
scl = container.colorscale;
53+
var autoAttr = cLetter + 'auto';
54+
var minAttr = cLetter + 'min';
55+
var maxAttr = cLetter + 'max';
56+
var auto = container[autoAttr];
57+
var min = container[minAttr];
58+
var max = container[maxAttr];
59+
var scl = container.colorscale;
3760

3861
if(auto !== false || min === undefined) {
3962
min = Lib.aggNums(Math.min, null, vals);
@@ -48,11 +71,8 @@ module.exports = function calc(trace, vals, containerStr, cLetter) {
4871
max += 0.5;
4972
}
5073

51-
container[minAttr] = min;
52-
container[maxAttr] = max;
53-
54-
inputContainer[minAttr] = min;
55-
inputContainer[maxAttr] = max;
74+
doUpdate(minAttr, min);
75+
doUpdate(maxAttr, max);
5676

5777
/*
5878
* If auto was explicitly false but min or max was missing,
@@ -61,17 +81,22 @@ module.exports = function calc(trace, vals, containerStr, cLetter) {
6181
* Otherwise make sure the trace still looks auto as far as later
6282
* changes are concerned.
6383
*/
64-
inputContainer[autoAttr] = (auto !== false ||
65-
(min === undefined && max === undefined));
84+
doUpdate(autoAttr, (auto !== false || (min === undefined && max === undefined)));
6685

6786
if(container.autocolorscale) {
6887
if(min * max < 0) scl = scales.RdBu;
6988
else if(min >= 0) scl = scales.Reds;
7089
else scl = scales.Blues;
7190

7291
// reversescale is handled at the containerOut level
73-
inputContainer.colorscale = scl;
74-
if(container.reversescale) scl = flipScale(scl);
75-
container.colorscale = scl;
92+
doUpdate('colorscale', scl, container.reversescale ? flipScale(scl) : scl);
93+
94+
// We pushed a colorscale back to input, which will change the default autocolorscale next time
95+
// to avoid spurious redraws from Plotly.react, update resulting autocolorscale now
96+
// This is a conscious decision so that changing the data later does not unexpectedly
97+
// give you a new colorscale
98+
if(!inputContainer.autocolorscale) {
99+
doUpdate('autocolorscale', false);
100+
}
76101
}
77102
};

src/components/fx/hover.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,9 @@ function _hover(gd, evt, subplot, noHoverEvent) {
279279
if(hasUserCalledHover) {
280280
if('xpx' in evt) xpx = evt.xpx;
281281
else xpx = xaArray[0]._length / 2;
282-
evt.pointerX = xpx + xaArray[0]._offset;
283282

284283
if('ypx' in evt) ypx = evt.ypx;
285284
else ypx = yaArray[0]._length / 2;
286-
evt.pointerY = ypx + yaArray[0]._offset;
287285
}
288286
else {
289287
// fire the beforehover event and quit if it returns false
@@ -300,13 +298,14 @@ function _hover(gd, evt, subplot, noHoverEvent) {
300298

301299
// in case hover was called from mouseout into hovertext,
302300
// it's possible you're not actually over the plot anymore
303-
if(xpx < 0 || xpx > dbb.width || ypx < 0 || ypx > dbb.height) {
301+
if(xpx < 0 || xpx > xaArray[0]._length || ypx < 0 || ypx > yaArray[0]._length) {
304302
return dragElement.unhoverRaw(gd, evt);
305303
}
306-
evt.pointerX = evt.offsetX;
307-
evt.pointerY = evt.offsetY;
308304
}
309305

306+
evt.pointerX = xpx + xaArray[0]._offset;
307+
evt.pointerY = ypx + yaArray[0]._offset;
308+
310309
if('xval' in evt) xvalArray = helpers.flat(subplots, evt.xval);
311310
else xvalArray = helpers.p2c(xaArray, xpx);
312311

@@ -713,9 +712,12 @@ function createHoverText(hoverData, opts, gd) {
713712
s.attr('data-notex', 1);
714713
});
715714

715+
var commonBgColor = commonLabelOpts.bgcolor || Color.defaultLine;
716+
var commonStroke = commonLabelOpts.bordercolor || Color.contrast(commonBgColor);
717+
716718
lpath.style({
717-
fill: commonLabelOpts.bgcolor || Color.defaultLine,
718-
stroke: commonLabelOpts.bordercolor || Color.background,
719+
fill: commonBgColor,
720+
stroke: commonStroke
719721
});
720722

721723
ltext.text(t0)

src/components/legend/draw.js

+48-29
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ module.exports = function draw(gd) {
4141

4242
if(!gd._legendMouseDownTime) gd._legendMouseDownTime = 0;
4343

44-
var opts = fullLayout.legend,
45-
legendData = fullLayout.showlegend && getLegendData(gd.calcdata, opts),
46-
hiddenSlices = fullLayout.hiddenlabels || [];
44+
var opts = fullLayout.legend;
45+
var legendData = fullLayout.showlegend && getLegendData(gd.calcdata, opts);
46+
var hiddenSlices = fullLayout.hiddenlabels || [];
4747

4848
if(!fullLayout.showlegend || !legendData.length) {
4949
fullLayout._infolayer.selectAll('.legend').remove();
@@ -53,6 +53,17 @@ module.exports = function draw(gd) {
5353
return;
5454
}
5555

56+
var maxLength = 0;
57+
for(var i = 0; i < legendData.length; i++) {
58+
for(var j = 0; j < legendData[i].length; j++) {
59+
var item = legendData[i][j][0];
60+
var trace = item.trace;
61+
var isPie = Registry.traceIs(trace, 'pie');
62+
var name = isPie ? item.label : trace.name;
63+
maxLength = Math.max(maxLength, name && name.length || 0);
64+
}
65+
}
66+
5667
var firstRender = false;
5768
var legend = Lib.ensureSingle(fullLayout._infolayer, 'g', 'legend', function(s) {
5869
s.attr('pointer-events', 'all');
@@ -108,7 +119,7 @@ module.exports = function draw(gd) {
108119
})
109120
.each(function() {
110121
d3.select(this)
111-
.call(drawTexts, gd)
122+
.call(drawTexts, gd, maxLength)
112123
.call(setupTraceToggle, gd);
113124
});
114125

@@ -352,38 +363,35 @@ module.exports = function draw(gd) {
352363
}
353364
};
354365

355-
function drawTexts(g, gd) {
356-
var legendItem = g.data()[0][0],
357-
fullLayout = gd._fullLayout,
358-
trace = legendItem.trace,
359-
isPie = Registry.traceIs(trace, 'pie'),
360-
traceIndex = trace.index,
361-
name = isPie ? legendItem.label : trace.name;
366+
function drawTexts(g, gd, maxLength) {
367+
var legendItem = g.data()[0][0];
368+
var fullLayout = gd._fullLayout;
369+
var trace = legendItem.trace;
370+
var isPie = Registry.traceIs(trace, 'pie');
371+
var traceIndex = trace.index;
372+
var name = isPie ? legendItem.label : trace.name;
373+
var isEditable = gd._context.edits.legendText && !isPie;
362374

363-
var text = Lib.ensureSingle(g, 'text', 'legendtext');
375+
var textEl = Lib.ensureSingle(g, 'text', 'legendtext');
364376

365-
text.attr('text-anchor', 'start')
377+
textEl.attr('text-anchor', 'start')
366378
.classed('user-select-none', true)
367379
.call(Drawing.font, fullLayout.legend.font)
368-
.text(name);
380+
.text(isEditable ? ensureLength(name, maxLength) : name);
369381

370382
function textLayout(s) {
371383
svgTextUtils.convertToTspans(s, gd, function() {
372384
computeTextDimensions(g, gd);
373385
});
374386
}
375387

376-
if(gd._context.edits.legendText && !isPie) {
377-
text.call(svgTextUtils.makeEditable, {gd: gd})
388+
if(isEditable) {
389+
textEl.call(svgTextUtils.makeEditable, {gd: gd, text: name})
378390
.call(textLayout)
379-
.on('edit', function(text) {
380-
this.text(text)
391+
.on('edit', function(newName) {
392+
this.text(ensureLength(newName, maxLength))
381393
.call(textLayout);
382394

383-
var origText = text;
384-
385-
if(!this.text()) text = ' \u0020\u0020 ';
386-
387395
var fullInput = legendItem.trace._fullInput || {};
388396
var update = {};
389397

@@ -393,24 +401,35 @@ function drawTexts(g, gd) {
393401

394402
var kcont = Lib.keyedContainer(fullInput, 'transforms[' + index + '].styles', 'target', 'value.name');
395403

396-
if(origText === '') {
397-
kcont.remove(legendItem.trace._group);
398-
} else {
399-
kcont.set(legendItem.trace._group, text);
400-
}
404+
kcont.set(legendItem.trace._group, newName);
401405

402406
update = kcont.constructUpdate();
403407
} else {
404-
update.name = text;
408+
update.name = newName;
405409
}
406410

407411
return Registry.call('restyle', gd, update, traceIndex);
408412
});
409413
} else {
410-
textLayout(text);
414+
textLayout(textEl);
411415
}
412416
}
413417

418+
/*
419+
* Make sure we have a reasonably clickable region.
420+
* If this string is missing or very short, pad it with spaces out to at least
421+
* 4 characters, up to the max length of other labels, on the assumption that
422+
* most characters are wider than spaces so a string of spaces will usually be
423+
* no wider than the real labels.
424+
*/
425+
function ensureLength(str, maxLength) {
426+
var targetLength = Math.max(4, maxLength);
427+
if(str && str.trim().length >= targetLength / 2) return str;
428+
str = str || '';
429+
for(var i = targetLength - str.length; i > 0; i--) str += ' ';
430+
return str;
431+
}
432+
414433
function setupTraceToggle(g, gd) {
415434
var newMouseDownTime,
416435
numClicks = 1;

src/components/modebar/modebar.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,13 @@ proto.update = function(graphInfo, buttons) {
5252
else this.element.className = 'modebar';
5353

5454
// if buttons or logo have changed, redraw modebar interior
55-
var needsNewButtons = !this.hasButtons(buttons),
56-
needsNewLogo = (this.hasLogo !== context.displaylogo);
55+
var needsNewButtons = !this.hasButtons(buttons);
56+
var needsNewLogo = (this.hasLogo !== context.displaylogo);
57+
var needsNewLocale = (this.locale !== context.locale);
5758

58-
if(needsNewButtons || needsNewLogo) {
59+
this.locale = context.locale;
60+
61+
if(needsNewButtons || needsNewLogo || needsNewLocale) {
5962
this.removeAllButtons();
6063

6164
this.updateButtons(buttons);

src/components/rangeslider/draw.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ function drawRangePlot(rangeSlider, gd, axisOpts, opts) {
448448

449449
Plots.supplyDefaults(mockFigure);
450450

451-
var xa = mockFigure._fullLayout.xaxis,
452-
ya = mockFigure._fullLayout[oppAxisName];
451+
var xa = mockFigure._fullLayout.xaxis;
452+
var ya = mockFigure._fullLayout[oppAxisName];
453453

454454
var plotinfo = {
455455
id: id,

0 commit comments

Comments
 (0)