Skip to content

Commit fbdcee8

Browse files
committed
Merge branch 'master' into gl3d-annotations
2 parents b7ab656 + 1ffb102 commit fbdcee8

File tree

114 files changed

+8030
-7833
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

+8030
-7833
lines changed

src/components/annotations/draw.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ function drawRaw(gd, options, index, xa, ya) {
131131
gd.emit('plotly_clickannotation', {
132132
index: index,
133133
annotation: options._input,
134-
fullAnnotation: options
134+
fullAnnotation: options,
135+
event: d3.event
135136
});
136137
});
137138

src/components/drawing/index.js

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
var d3 = require('d3');
1313
var isNumeric = require('fast-isnumeric');
14+
var tinycolor = require('tinycolor2');
1415

1516
var Registry = require('../../registry');
1617
var Color = require('../color');
@@ -202,7 +203,7 @@ drawing.symbolNumber = function(v) {
202203
return Math.floor(Math.max(v, 0));
203204
};
204205

205-
function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerLine) {
206+
function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerLine, gd) {
206207
// only scatter & box plots get marker path and opacity
207208
// bars, histograms don't
208209
if(Registry.traceIs(trace, 'symbols')) {
@@ -237,6 +238,8 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
237238
});
238239
}
239240

241+
var perPointGradient = false;
242+
240243
// 'so' is suspected outliers, for box plots
241244
var fillColor,
242245
lineColor,
@@ -256,8 +259,12 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
256259
else if(Array.isArray(markerLine.color)) lineColor = Color.defaultLine;
257260
else lineColor = markerLine.color;
258261

262+
if(Array.isArray(marker.color)) {
263+
fillColor = Color.defaultLine;
264+
perPointGradient = true;
265+
}
266+
259267
if('mc' in d) fillColor = d.mcc = markerScale(d.mc);
260-
else if(Array.isArray(marker.color)) fillColor = Color.defaultLine;
261268
else fillColor = marker.color || 'rgba(0,0,0,0)';
262269
}
263270

@@ -271,24 +278,93 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
271278
});
272279
}
273280
else {
274-
sel.style('stroke-width', lineWidth + 'px')
275-
.call(Color.fill, fillColor);
281+
sel.style('stroke-width', lineWidth + 'px');
282+
283+
var markerGradient = marker.gradient;
284+
285+
var gradientType = d.mgt;
286+
if(gradientType) perPointGradient = true;
287+
else gradientType = markerGradient && markerGradient.type;
288+
289+
if(gradientType && gradientType !== 'none') {
290+
var gradientColor = d.mgc;
291+
if(gradientColor) perPointGradient = true;
292+
else gradientColor = markerGradient.color;
293+
294+
var gradientID = 'g' + gd._fullLayout._uid + '-' + trace.uid;
295+
if(perPointGradient) gradientID += '-' + d.i;
296+
297+
sel.call(drawing.gradient, gd, gradientID, gradientType, fillColor, gradientColor);
298+
}
299+
else {
300+
sel.call(Color.fill, fillColor);
301+
}
302+
276303
if(lineWidth) {
277304
sel.call(Color.stroke, lineColor);
278305
}
279306
}
280307
}
281308

282-
drawing.singlePointStyle = function(d, sel, trace) {
283-
var marker = trace.marker,
284-
markerLine = marker.line;
309+
var HORZGRADIENT = {x1: 1, x2: 0, y1: 0, y2: 0};
310+
var VERTGRADIENT = {x1: 0, x2: 0, y1: 1, y2: 0};
285311

286-
// allow array marker and marker line colors to be
287-
// scaled by given max and min to colorscales
288-
var markerScale = drawing.tryColorscale(marker, ''),
289-
lineScale = drawing.tryColorscale(marker, 'line');
312+
drawing.gradient = function(sel, gd, gradientID, type, color1, color2) {
313+
var gradient = gd._fullLayout._defs.select('.gradients')
314+
.selectAll('#' + gradientID)
315+
.data([type + color1 + color2], Lib.identity);
316+
317+
gradient.exit().remove();
290318

291-
singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerLine);
319+
gradient.enter()
320+
.append(type === 'radial' ? 'radialGradient' : 'linearGradient')
321+
.each(function() {
322+
var el = d3.select(this);
323+
if(type === 'horizontal') el.attr(HORZGRADIENT);
324+
else if(type === 'vertical') el.attr(VERTGRADIENT);
325+
326+
el.attr('id', gradientID);
327+
328+
var tc1 = tinycolor(color1);
329+
var tc2 = tinycolor(color2);
330+
331+
el.append('stop').attr({
332+
offset: '0%',
333+
'stop-color': Color.tinyRGB(tc2),
334+
'stop-opacity': tc2.getAlpha()
335+
});
336+
337+
el.append('stop').attr({
338+
offset: '100%',
339+
'stop-color': Color.tinyRGB(tc1),
340+
'stop-opacity': tc1.getAlpha()
341+
});
342+
});
343+
344+
sel.style({
345+
fill: 'url(#' + gradientID + ')',
346+
'fill-opacity': null
347+
});
348+
};
349+
350+
/*
351+
* Make the gradients container and clear out any previous gradients.
352+
* We never collect all the gradients we need in one place,
353+
* so we can't ever remove gradients that have stopped being useful,
354+
* except all at once before a full redraw.
355+
* The upside of this is arbitrary points can share gradient defs
356+
*/
357+
drawing.initGradients = function(gd) {
358+
var gradientsGroup = gd._fullLayout._defs.selectAll('.gradients').data([0]);
359+
gradientsGroup.enter().append('g').classed('gradients', true);
360+
361+
gradientsGroup.selectAll('linearGradient,radialGradient').remove();
362+
};
363+
364+
drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
365+
var marker = trace.marker;
366+
367+
singlePointStyle(d, sel, trace, markerScale, lineScale, marker, marker.line, gd);
292368

293369
};
294370

@@ -298,11 +374,12 @@ drawing.pointStyle = function(s, trace) {
298374
// allow array marker and marker line colors to be
299375
// scaled by given max and min to colorscales
300376
var marker = trace.marker;
301-
var markerScale = drawing.tryColorscale(marker, ''),
302-
lineScale = drawing.tryColorscale(marker, 'line');
377+
var markerScale = drawing.tryColorscale(marker, '');
378+
var lineScale = drawing.tryColorscale(marker, 'line');
379+
var gd = Lib.getPlotDiv(s.node());
303380

304381
s.each(function(d) {
305-
drawing.singlePointStyle(d, d3.select(this), trace, markerScale, lineScale);
382+
drawing.singlePointStyle(d, d3.select(this), trace, markerScale, lineScale, gd);
306383
});
307384
};
308385

@@ -512,6 +589,7 @@ drawing.makeTester = function(gd) {
512589
// always returns a copy of the bbox, so the caller can modify it safely
513590
var savedBBoxes = [],
514591
maxSavedBBoxes = 10000;
592+
515593
drawing.bBox = function(node) {
516594
// cache elements we've already measured so we don't have to
517595
// remeasure the same thing many times
@@ -520,32 +598,36 @@ drawing.bBox = function(node) {
520598
return Lib.extendFlat({}, savedBBoxes[saveNum.value]);
521599
}
522600

523-
var test3 = d3.select('#js-plotly-tester'),
524-
tester = test3.node();
601+
if(!drawing.test3) {
602+
drawing.test3 = d3.select('#js-plotly-tester');
603+
drawing.tester = drawing.test3.node();
604+
}
525605

526606
// copy the node to test into the tester
527607
var testNode = node.cloneNode(true);
528-
tester.appendChild(testNode);
608+
drawing.tester.appendChild(testNode);
529609
// standardize its position... do we really want to do this?
530610
d3.select(testNode).attr({
531611
x: 0,
532612
y: 0,
533613
transform: ''
534614
});
535615

536-
var testRect = testNode.getBoundingClientRect(),
537-
refRect = test3.select('.js-reference-point')
616+
var testRect = testNode.getBoundingClientRect();
617+
if(!drawing.refRect) {
618+
drawing.refRect = drawing.test3.select('.js-reference-point')
538619
.node().getBoundingClientRect();
620+
}
539621

540-
tester.removeChild(testNode);
622+
drawing.tester.removeChild(testNode);
541623

542624
var bb = {
543625
height: testRect.height,
544626
width: testRect.width,
545-
left: testRect.left - refRect.left,
546-
top: testRect.top - refRect.top,
547-
right: testRect.right - refRect.left,
548-
bottom: testRect.bottom - refRect.top
627+
left: testRect.left - drawing.refRect.left,
628+
top: testRect.top - drawing.refRect.top,
629+
right: testRect.right - drawing.refRect.left,
630+
bottom: testRect.bottom - drawing.refRect.top
549631
};
550632

551633
// make sure we don't have too many saved boxes,

src/lib/svg_text_utils.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ var stringMappings = require('../constants/string_mappings');
1919

2020
// Append SVG
2121

22+
var parser = new DOMParser();
23+
2224
d3.selection.prototype.appendSVG = function(_svgString) {
2325
var skeleton = [
2426
'<svg xmlns="', xmlnsNamespaces.svg, '" ',
@@ -27,7 +29,7 @@ d3.selection.prototype.appendSVG = function(_svgString) {
2729
'</svg>'
2830
].join('');
2931

30-
var dom = new DOMParser().parseFromString(skeleton, 'application/xml'),
32+
var dom = parser.parseFromString(skeleton, 'application/xml'),
3133
childNode = dom.documentElement.firstChild;
3234

3335
while(childNode) {

src/plot_api/manage_arrays.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var nestedProperty = require('../lib/nested_property');
1313
var isPlainObject = require('../lib/is_plain_object');
1414
var noop = require('../lib/noop');
1515
var Loggers = require('../lib/loggers');
16+
var sorterAsc = require('../lib/search').sorterAsc;
1617
var Registry = require('../registry');
1718

1819

@@ -101,7 +102,7 @@ exports.applyContainerArrayChanges = function applyContainerArrayChanges(gd, np,
101102
return true;
102103
}
103104

104-
var componentNums = Object.keys(edits).map(Number).sort(),
105+
var componentNums = Object.keys(edits).map(Number).sort(sorterAsc),
105106
componentArrayIn = np.get(),
106107
componentArray = componentArrayIn || [],
107108
// componentArrayFull is used just to keep splices in line between

src/plot_api/plot_api.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ Plotly.plot = function(gd, data, layout, config) {
153153
makePlotFramework(gd);
154154
}
155155

156+
// clear gradient defs on each .plot call, because we know we'll loop through all traces
157+
Drawing.initGradients(gd);
158+
156159
// save initial show spikes once per graph
157160
if(graphWasEmpty) Plotly.Axes.saveShowSpikeInitial(gd);
158161

@@ -285,7 +288,8 @@ Plotly.plot = function(gd, data, layout, config) {
285288
// Now plot the data
286289
function drawData() {
287290
var calcdata = gd.calcdata,
288-
i;
291+
i,
292+
rangesliderContainers = fullLayout._infolayer.selectAll('g.rangeslider-container');
289293

290294
// in case of traces that were heatmaps or contour maps
291295
// previously, remove them and their colorbars explicitly
@@ -305,7 +309,7 @@ Plotly.plot = function(gd, data, layout, config) {
305309
.selectAll(query)
306310
.remove();
307311

308-
fullLayout._infolayer.selectAll('g.rangeslider-container')
312+
rangesliderContainers
309313
.selectAll(query)
310314
.remove();
311315
}

src/traces/parcoords/attributes.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var colorAttributes = require('../../components/colorscale/color_attributes');
1212
var colorbarAttrs = require('../../components/colorbar/attributes');
1313
var colorscales = require('../../components/colorscale/scales');
1414
var axesAttrs = require('../../plots/cartesian/layout_attributes');
15+
var fontAttrs = require('../../plots/font_attributes');
1516

1617
var extendDeep = require('../../lib/extend').extendDeep;
1718
var extendFlat = require('../../lib/extend').extendFlat;
@@ -47,6 +48,16 @@ module.exports = {
4748
}
4849
},
4950

51+
labelfont: extendFlat({}, fontAttrs, {
52+
description: 'Sets the font for the `dimension` labels.'
53+
}),
54+
tickfont: extendFlat({}, fontAttrs, {
55+
description: 'Sets the font for the `dimension` tick values.'
56+
}),
57+
rangefont: extendFlat({}, fontAttrs, {
58+
description: 'Sets the font for the `dimension` range values.'
59+
}),
60+
5061
dimensions: {
5162
_isLinkedToArray: 'dimension',
5263
label: {

src/traces/parcoords/defaults.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ function dimensionsDefaults(traceIn, traceOut) {
8181
return dimensionsOut;
8282
}
8383

84-
8584
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
8685
function coerce(attr, dflt) {
8786
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
@@ -97,4 +96,16 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
9796
if(!Array.isArray(dimensions) || !dimensions.length) {
9897
traceOut.visible = false;
9998
}
99+
100+
// make default font size 10px,
101+
// scale linearly with global font size
102+
var fontDflt = {
103+
family: layout.font.family,
104+
size: Math.round(layout.font.size * (10 / 12)),
105+
color: layout.font.color
106+
};
107+
108+
Lib.coerceFont(coerce, 'labelfont', fontDflt);
109+
Lib.coerceFont(coerce, 'tickfont', fontDflt);
110+
Lib.coerceFont(coerce, 'rangefont', fontDflt);
100111
};

0 commit comments

Comments
 (0)