Skip to content

Commit 9cc641a

Browse files
committed
Merge branch 'master' into pr-2979
2 parents 126e29c + a285aeb commit 9cc641a

File tree

114 files changed

+8329
-1137
lines changed

Some content is hidden

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

114 files changed

+8329
-1137
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ and use the `Plotly` object in the window scope.
5757

5858
### Download the latest release
5959

60-
[Latest Release on Github](https://github.com/plotly/plotly.js/releases/)
60+
[Latest Release on GitHub](https://github.com/plotly/plotly.js/releases/)
6161

6262
and use the plotly.js `dist` file(s). More info [here](https://github.com/plotly/plotly.js/blob/master/dist/README.md).
6363

lib/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Plotly.register([
3838
require('./pointcloud'),
3939
require('./heatmapgl'),
4040
require('./parcoords'),
41-
41+
require('./parcats'),
4242
require('./scattermapbox'),
4343

4444
require('./sankey'),

lib/parcats.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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 = require('../src/traces/parcats');

package-lock.json

+6-6
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
@@ -110,7 +110,7 @@
110110
"sane-topojson": "^2.0.0",
111111
"strongly-connected-components": "^1.0.1",
112112
"superscript-text": "^1.0.0",
113-
"svg-path-sdf": "^1.1.1",
113+
"svg-path-sdf": "^1.1.2",
114114
"tinycolor2": "^1.3.0",
115115
"topojson-client": "^2.1.0",
116116
"webgl-context": "^2.2.0",

src/components/fx/hover.js

+79
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,81 @@ exports.loneHover = function loneHover(hoverItem, opts) {
153153
return hoverLabel.node();
154154
};
155155

156+
exports.multiHovers = function multiHovers(hoverItems, opts) {
157+
158+
if(!Array.isArray(hoverItems)) {
159+
hoverItems = [hoverItems];
160+
}
161+
162+
var pointsData = hoverItems.map(function(hoverItem) {
163+
return {
164+
color: hoverItem.color || Color.defaultLine,
165+
x0: hoverItem.x0 || hoverItem.x || 0,
166+
x1: hoverItem.x1 || hoverItem.x || 0,
167+
y0: hoverItem.y0 || hoverItem.y || 0,
168+
y1: hoverItem.y1 || hoverItem.y || 0,
169+
xLabel: hoverItem.xLabel,
170+
yLabel: hoverItem.yLabel,
171+
zLabel: hoverItem.zLabel,
172+
text: hoverItem.text,
173+
name: hoverItem.name,
174+
idealAlign: hoverItem.idealAlign,
175+
176+
// optional extra bits of styling
177+
borderColor: hoverItem.borderColor,
178+
fontFamily: hoverItem.fontFamily,
179+
fontSize: hoverItem.fontSize,
180+
fontColor: hoverItem.fontColor,
181+
182+
// filler to make createHoverText happy
183+
trace: {
184+
index: 0,
185+
hoverinfo: ''
186+
},
187+
xa: {_offset: 0},
188+
ya: {_offset: 0},
189+
index: 0
190+
};
191+
});
192+
193+
194+
var container3 = d3.select(opts.container),
195+
outerContainer3 = opts.outerContainer ?
196+
d3.select(opts.outerContainer) : container3;
197+
198+
var fullOpts = {
199+
hovermode: 'closest',
200+
rotateLabels: false,
201+
bgColor: opts.bgColor || Color.background,
202+
container: container3,
203+
outerContainer: outerContainer3
204+
};
205+
206+
var hoverLabel = createHoverText(pointsData, fullOpts, opts.gd);
207+
208+
// Fix vertical overlap
209+
var tooltipSpacing = 5;
210+
var lastBottomY = 0;
211+
hoverLabel
212+
.sort(function(a, b) {return a.y0 - b.y0;})
213+
.each(function(d) {
214+
var topY = d.y0 - d.by / 2;
215+
216+
if((topY - tooltipSpacing) < lastBottomY) {
217+
d.offset = (lastBottomY - topY) + tooltipSpacing;
218+
} else {
219+
d.offset = 0;
220+
}
221+
222+
lastBottomY = topY + d.by + d.offset;
223+
});
224+
225+
226+
alignHoverText(hoverLabel, fullOpts.rotateLabels);
227+
228+
return hoverLabel.node();
229+
};
230+
156231
// The actual implementation is here:
157232
function _hover(gd, evt, subplot, noHoverEvent) {
158233
if(!subplot) subplot = 'xy';
@@ -396,6 +471,10 @@ function _hover(gd, evt, subplot, noHoverEvent) {
396471
if(fullLayout[subplotId]) {
397472
pointData.subplot = fullLayout[subplotId]._subplot;
398473
}
474+
// add ref to splom scene
475+
if(fullLayout._splomScenes && fullLayout._splomScenes[trace.uid]) {
476+
pointData.scene = fullLayout._splomScenes[trace.uid];
477+
}
399478

400479
closedataPreviousLength = hoverData.length;
401480

src/components/fx/index.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var Lib = require('../../lib');
1313
var dragElement = require('../dragelement');
1414
var helpers = require('./helpers');
1515
var layoutAttributes = require('./layout_attributes');
16+
var hoverModule = require('./hover');
1617

1718
module.exports = {
1819
moduleType: 'component',
@@ -41,10 +42,11 @@ module.exports = {
4142
castHoverOption: castHoverOption,
4243
castHoverinfo: castHoverinfo,
4344

44-
hover: require('./hover').hover,
45+
hover: hoverModule.hover,
4546
unhover: dragElement.unhover,
4647

47-
loneHover: require('./hover').loneHover,
48+
loneHover: hoverModule.loneHover,
49+
multiHovers: hoverModule.multiHovers,
4850
loneUnhover: loneUnhover,
4951

5052
click: require('./click')

src/fonts/mathjax_config.js

+13-9
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@
1616
if(typeof MathJax !== 'undefined') {
1717
exports.MathJax = true;
1818

19-
MathJax.Hub.Config({
20-
messageStyle: 'none',
21-
skipStartupTypeset: true,
22-
displayAlign: 'left',
23-
tex2jax: {
24-
inlineMath: [['$', '$'], ['\\(', '\\)']]
25-
}
26-
});
19+
var globalConfig = (window.PlotlyConfig || {}).MathJaxConfig !== 'local';
20+
21+
if(globalConfig) {
22+
MathJax.Hub.Config({
23+
messageStyle: 'none',
24+
skipStartupTypeset: true,
25+
displayAlign: 'left',
26+
tex2jax: {
27+
inlineMath: [['$', '$'], ['\\(', '\\)']]
28+
}
29+
});
30+
MathJax.Hub.Configured();
31+
}
2732

28-
MathJax.Hub.Configured();
2933
} else {
3034
exports.MathJax = false;
3135
}

src/lib/dates.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,9 @@ function includeTime(dateStr, h, m, s, msec10) {
345345
// a Date object or milliseconds
346346
// optional dflt is the return value if cleaning fails
347347
exports.cleanDate = function(v, dflt, calendar) {
348-
if(exports.isJSDate(v) || typeof v === 'number') {
348+
// let us use cleanDate to provide a missing default without an error
349+
if(v === BADNUM) return dflt;
350+
if(exports.isJSDate(v) || (typeof v === 'number' && isFinite(v))) {
349351
// do not allow milliseconds (old) or jsdate objects (inherently
350352
// described as gregorian dates) with world calendars
351353
if(isWorldCalendar(calendar)) {

src/lib/svg_text_utils.js

+52-8
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,48 @@ function cleanEscapesForTex(s) {
163163
}
164164

165165
function texToSVG(_texString, _config, _callback) {
166-
var randomID = 'math-output-' + Lib.randstr({}, 64);
167-
var tmpDiv = d3.select('body').append('div')
168-
.attr({id: randomID})
169-
.style({visibility: 'hidden', position: 'absolute'})
170-
.style({'font-size': _config.fontSize + 'px'})
171-
.text(cleanEscapesForTex(_texString));
172-
173-
MathJax.Hub.Queue(['Typeset', MathJax.Hub, tmpDiv.node()], function() {
166+
167+
var originalRenderer,
168+
originalConfig,
169+
originalProcessSectionDelay,
170+
tmpDiv;
171+
172+
MathJax.Hub.Queue(
173+
function() {
174+
originalConfig = Lib.extendDeepAll({}, MathJax.Hub.config);
175+
176+
originalProcessSectionDelay = MathJax.Hub.processSectionDelay;
177+
if(MathJax.Hub.processSectionDelay !== undefined) {
178+
// MathJax 2.5+
179+
MathJax.Hub.processSectionDelay = 0;
180+
}
181+
182+
return MathJax.Hub.Config({
183+
messageStyle: 'none',
184+
tex2jax: {
185+
inlineMath: [['$', '$'], ['\\(', '\\)']]
186+
},
187+
displayAlign: 'left',
188+
});
189+
},
190+
function() {
191+
// Get original renderer
192+
originalRenderer = MathJax.Hub.config.menuSettings.renderer;
193+
if(originalRenderer !== 'SVG') {
194+
return MathJax.Hub.setRenderer('SVG');
195+
}
196+
},
197+
function() {
198+
var randomID = 'math-output-' + Lib.randstr({}, 64);
199+
tmpDiv = d3.select('body').append('div')
200+
.attr({id: randomID})
201+
.style({visibility: 'hidden', position: 'absolute'})
202+
.style({'font-size': _config.fontSize + 'px'})
203+
.text(cleanEscapesForTex(_texString));
204+
205+
return MathJax.Hub.Typeset(tmpDiv.node());
206+
},
207+
function() {
174208
var glyphDefs = d3.select('body').select('#MathJax_SVG_glyphs');
175209

176210
if(tmpDiv.select('.MathJax_SVG').empty() || !tmpDiv.select('svg').node()) {
@@ -183,6 +217,16 @@ function texToSVG(_texString, _config, _callback) {
183217
}
184218

185219
tmpDiv.remove();
220+
221+
if(originalRenderer !== 'SVG') {
222+
return MathJax.Hub.setRenderer(originalRenderer);
223+
}
224+
},
225+
function() {
226+
if(originalProcessSectionDelay !== undefined) {
227+
MathJax.Hub.processSectionDelay = originalProcessSectionDelay;
228+
}
229+
return MathJax.Hub.Config(originalConfig);
186230
});
187231
}
188232

src/plot_api/edit_types.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var isPlainObject = Lib.isPlainObject;
1515
var traceOpts = {
1616
valType: 'flaglist',
1717
extras: ['none'],
18-
flags: ['calc', 'clearAxisTypes', 'plot', 'style', 'colorbars'],
18+
flags: ['calc', 'clearAxisTypes', 'plot', 'style', 'markerSize', 'colorbars'],
1919
description: [
2020
'trace attributes should include an `editType` string matching this flaglist.',
2121
'*calc* is the most extensive: a full `Plotly.plot` starting by clearing `gd.calcdata`',
@@ -24,7 +24,8 @@ var traceOpts = {
2424
'cause the automatic axis type detection to change. Log type will not be cleared, as that',
2525
'is never automatically chosen so must have been user-specified.',
2626
'*plot* calls `Plotly.plot` but without first clearing `gd.calcdata`.',
27-
'*style* only calls `module.style` for all trace modules and redraws the legend.',
27+
'*style* only calls `module.style` (or module.editStyle) for all trace modules and redraws the legend.',
28+
'*markerSize* is like *style*, but propagate axis-range changes due to scatter `marker.size`',
2829
'*colorbars* only redraws colorbars.'
2930
].join(' ')
3031
};

src/plot_api/helpers.js

+13
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,19 @@ exports.cleanData = function(data) {
386386
// sanitize rgb(fractions) and rgba(fractions) that old tinycolor
387387
// supported, but new tinycolor does not because they're not valid css
388388
Color.clean(trace);
389+
390+
// remove obsolete autobin(x|y) attributes, but only if true
391+
// if false, this needs to happen in Histogram.calc because it
392+
// can be a one-time autobin so we need to know the results before
393+
// we can push them back into the trace.
394+
if(trace.autobinx) {
395+
delete trace.autobinx;
396+
delete trace.xbins;
397+
}
398+
if(trace.autobiny) {
399+
delete trace.autobiny;
400+
delete trace.ybins;
401+
}
389402
}
390403
};
391404

0 commit comments

Comments
 (0)