-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
scatter marker color gradients #1620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
541460a
ff6c910
105ce9b
a074259
1b0a6bb
d1c6b51
e3af5eb
ec4d9ee
21650c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -203,7 +203,7 @@ drawing.symbolNumber = function(v) { | |
return Math.floor(Math.max(v, 0)); | ||
}; | ||
|
||
function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerLine, gd) { | ||
function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerLine, gd, i) { | ||
// only scatter & box plots get marker path and opacity | ||
// bars, histograms don't | ||
if(Registry.traceIs(trace, 'symbols')) { | ||
|
@@ -238,6 +238,8 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL | |
}); | ||
} | ||
|
||
var perPointGradient = false; | ||
|
||
// 'so' is suspected outliers, for box plots | ||
var fillColor, | ||
lineColor, | ||
|
@@ -257,8 +259,12 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL | |
else if(Array.isArray(markerLine.color)) lineColor = Color.defaultLine; | ||
else lineColor = markerLine.color; | ||
|
||
if(Array.isArray(marker.color)) { | ||
fillColor = Color.defaultLine; | ||
perPointGradient = true; | ||
} | ||
|
||
if('mc' in d) fillColor = d.mcc = markerScale(d.mc); | ||
else if(Array.isArray(marker.color)) fillColor = Color.defaultLine; | ||
else fillColor = marker.color || 'rgba(0,0,0,0)'; | ||
} | ||
|
||
|
@@ -275,10 +281,20 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL | |
sel.style('stroke-width', lineWidth + 'px'); | ||
|
||
var markerGradient = marker.gradient; | ||
var gradientColor = markerGradient && (d.mgc || markerGradient.color); | ||
var gradientType = markerGradient && (d.mgt || markerGradient.type); | ||
|
||
var gradientType = d.mgt; | ||
if(gradientType) perPointGradient = true; | ||
else gradientType = markerGradient && markerGradient.type; | ||
|
||
if(gradientType && gradientType !== 'none') { | ||
sel.call(drawing.gradient, gd, gradientType, fillColor, gradientColor); | ||
var gradientColor = d.mgc; | ||
if(gradientColor) perPointGradient = true; | ||
else gradientColor = markerGradient.color; | ||
|
||
var gradientID = 'g' + gd._fullLayout._uid + '-' + trace.uid; | ||
if(perPointGradient) gradientID += '-' + i; | ||
|
||
sel.call(drawing.gradient, gd, gradientID, gradientType, fillColor, gradientColor); | ||
} | ||
else { | ||
sel.call(Color.fill, fillColor); | ||
|
@@ -293,12 +309,12 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL | |
var HORZGRADIENT = {x1: 1, x2: 0, y1: 0, y2: 0}; | ||
var VERTGRADIENT = {x1: 0, x2: 0, y1: 1, y2: 0}; | ||
|
||
drawing.gradient = function(sel, gd, type, color1, color2) { | ||
var fullLayout = gd._fullLayout; | ||
var gradientID = ( | ||
type + fullLayout._uid + '-' + color1 + '-' + color2 | ||
).replace(/[^\w\-]+/g, '_'); | ||
var gradient = fullLayout._defs.select('.gradients').selectAll('#' + gradientID).data([0]); | ||
drawing.gradient = function(sel, gd, gradientID, type, color1, color2) { | ||
var gradient = gd._fullLayout._defs.select('.gradients') | ||
.selectAll('#' + gradientID) | ||
.data([type + color1 + color2], Lib.identity); | ||
|
||
gradient.exit().remove(); | ||
|
||
gradient.enter() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suspect this algo would work for adding gradients to bar traces? Would be a cool feature 😏 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, would be cool to add bar gradients... for another PR |
||
.append(type === 'radial' ? 'radialGradient' : 'linearGradient') | ||
|
@@ -345,10 +361,10 @@ drawing.initGradients = function(gd) { | |
gradientsGroup.selectAll('linearGradient,radialGradient').remove(); | ||
}; | ||
|
||
drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) { | ||
drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd, i) { | ||
var marker = trace.marker; | ||
|
||
singlePointStyle(d, sel, trace, markerScale, lineScale, marker, marker.line, gd); | ||
singlePointStyle(d, sel, trace, markerScale, lineScale, marker, marker.line, gd, i); | ||
|
||
}; | ||
|
||
|
@@ -362,8 +378,8 @@ drawing.pointStyle = function(s, trace) { | |
var lineScale = drawing.tryColorscale(marker, 'line'); | ||
var gd = Lib.getPlotDiv(s.node()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if it might be better to add a ref to those gradient defs in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll leave it for now - I agree this is suboptimal but neither of these alternatives seems particularly simpler to me. If I had to pick one I'd probably go for the first actually... stashing the |
||
|
||
s.each(function(d) { | ||
drawing.singlePointStyle(d, d3.select(this), trace, markerScale, lineScale, gd); | ||
s.each(function(d, i) { | ||
drawing.singlePointStyle(d, d3.select(this), trace, markerScale, lineScale, gd, i); | ||
}); | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we're making either one gradient for the whole trace (if we can) or one per point (if any of the attributes varies per point) and it will update if the attributes change. This means that several traces (or several points in one trace with array attributes) will no longer be able to share a gradient def, but I don't think there are any cases where this can blow up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds right 👍