-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Contour legend #2891
Contour legend #2891
Changes from 4 commits
44aa70e
597a845
7f0db7c
0f532f3
7843d83
e25b9ff
73f279b
74e7f84
1d05081
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 |
---|---|---|
|
@@ -61,25 +61,78 @@ module.exports = function style(s, gd) { | |
var showFill = trace.visible && trace.fill && trace.fill !== 'none'; | ||
var showLine = subTypes.hasLines(trace); | ||
var contours = trace.contours; | ||
var showGradientLine = false; | ||
var showGradientFill = false; | ||
|
||
if(contours && contours.type === 'constraint') { | ||
showLine = contours.showlines; | ||
showFill = contours._operation !== '='; | ||
if(contours) { | ||
var coloring = contours.coloring; | ||
|
||
if(coloring === 'lines') { | ||
showGradientLine = true; | ||
} | ||
else { | ||
showLine = coloring === 'none' || coloring === 'heatmap' || | ||
contours.showlines; | ||
} | ||
|
||
if(contours.type === 'constraint') { | ||
showFill = contours._operation !== '='; | ||
} | ||
else if(coloring === 'fill' || coloring === 'heatmap') { | ||
showGradientFill = true; | ||
} | ||
} | ||
|
||
var fill = d3.select(this).select('.legendfill').selectAll('path') | ||
.data(showFill ? [d] : []); | ||
// with fill and no markers or text, move the line and fill up a bit | ||
// so it's more centered | ||
var markersOrText = subTypes.hasMarkers(trace) || subTypes.hasText(trace); | ||
var anyFill = showFill || showGradientFill; | ||
var anyLine = showLine || showGradientLine; | ||
var pathStart = (markersOrText || !anyFill) ? 'M5,0' : | ||
// with a line leave it slightly below center, to leave room for the | ||
// line thickness and because the line is usually more prominent | ||
anyLine ? 'M5,-2' : 'M5,-3'; | ||
|
||
var this3 = d3.select(this); | ||
|
||
var fill = this3.select('.legendfill').selectAll('path') | ||
.data(showFill || showGradientFill ? [d] : []); | ||
fill.enter().append('path').classed('js-fill', true); | ||
fill.exit().remove(); | ||
fill.attr('d', 'M5,0h30v6h-30z') | ||
.call(Drawing.fillGroupStyle); | ||
fill.attr('d', pathStart + 'h30v6h-30z') | ||
.call(showFill ? Drawing.fillGroupStyle : fillGradient); | ||
|
||
var line = d3.select(this).select('.legendlines').selectAll('path') | ||
.data(showLine ? [d] : []); | ||
line.enter().append('path').classed('js-line', true) | ||
.attr('d', 'M5,0h30'); | ||
var line = this3.select('.legendlines').selectAll('path') | ||
.data(showLine || showGradientLine ? [d] : []); | ||
line.enter().append('path').classed('js-line', true); | ||
line.exit().remove(); | ||
line.call(Drawing.lineGroupStyle); | ||
|
||
// this is ugly... but you can't apply a gradient to a perfectly | ||
// horizontal or vertical line. Presumably because then | ||
// the system doesn't know how to scale vertical variation, even | ||
// though there *is* no vertical variation in this case. | ||
// so add an invisibly small angle to the line | ||
// This issue (and workaround) exist across (Mac) Chrome, FF, and Safari | ||
line.attr('d', pathStart + (showGradientLine ? 'l30,0.0001' : 'h30')) | ||
.call(showLine ? Drawing.lineGroupStyle : lineGradient); | ||
|
||
function fillGradient(s) { | ||
if(s.size()) { | ||
var gradientID = 'legendfill-' + trace.uid; | ||
Drawing.gradient(s, gd, gradientID, 'horizontalreversed', | ||
trace.colorscale, 'fill'); | ||
} | ||
} | ||
|
||
function lineGradient(s) { | ||
if(s.size()) { | ||
var gradientID = 'legendline-' + trace.uid; | ||
Drawing.lineGroupStyle(s); | ||
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. We should double-check that this works ok with 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. Good call, added to a mock in 73f279b |
||
Drawing.gradient(s, gd, gradientID, 'horizontalreversed', | ||
trace.colorscale, 'stroke'); | ||
} | ||
} | ||
|
||
} | ||
|
||
function stylePoints(d) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ var Drawing = require('../../components/drawing'); | |
var svgTextUtils = require('../../lib/svg_text_utils'); | ||
var Axes = require('../../plots/cartesian/axes'); | ||
var setConvert = require('../../plots/cartesian/set_convert'); | ||
var getUidsFromCalcData = require('../../plots/get_data').getUidsFromCalcData; | ||
|
||
var heatmapPlot = require('../heatmap/plot'); | ||
var makeCrossings = require('./make_crossings'); | ||
|
@@ -28,32 +27,40 @@ var constants = require('./constants'); | |
var costConstants = constants.LABELOPTIMIZER; | ||
|
||
exports.plot = function plot(gd, plotinfo, cdcontours, contourLayer) { | ||
var uidLookup = getUidsFromCalcData(cdcontours); | ||
plotWrapper(gd, plotinfo, cdcontours, contourLayer, plotOne); | ||
}; | ||
|
||
contourLayer.selectAll('g.contour').each(function(d) { | ||
if(!uidLookup[d.trace.uid]) { | ||
d3.select(this).remove(); | ||
} | ||
}); | ||
function plotWrapper(gd, plotinfo, cdcontours, contourLayer, plotOneFn) { | ||
var contours = contourLayer.selectAll('g.contour') | ||
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. 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. Good call -> #2907 |
||
.data( | ||
cdcontours.map(function(d) { return d[0]; }), | ||
function(cd) { return cd.trace.uid; } | ||
); | ||
|
||
for(var i = 0; i < cdcontours.length; i++) { | ||
plotOne(gd, plotinfo, cdcontours[i], contourLayer); | ||
} | ||
}; | ||
contours.exit().remove(); | ||
|
||
contours.enter().append('g') | ||
.classed('contour', true); | ||
|
||
function plotOne(gd, plotinfo, cd, contourLayer) { | ||
var trace = cd[0].trace; | ||
var x = cd[0].x; | ||
var y = cd[0].y; | ||
contours.each(function(cd) { | ||
plotOneFn(gd, plotinfo, cd, d3.select(this)); | ||
}) | ||
.order(); | ||
} | ||
exports.plotWrapper = plotWrapper; | ||
|
||
function plotOne(gd, plotinfo, cd, plotGroup) { | ||
var trace = cd.trace; | ||
var x = cd.x; | ||
var y = cd.y; | ||
var contours = trace.contours; | ||
var id = 'contour' + trace.uid; | ||
var xa = plotinfo.xaxis; | ||
var ya = plotinfo.yaxis; | ||
var fullLayout = gd._fullLayout; | ||
var pathinfo = emptyPathinfo(contours, plotinfo, cd[0]); | ||
var pathinfo = emptyPathinfo(contours, plotinfo, cd); | ||
|
||
// use a heatmap to fill - draw it behind the lines | ||
var heatmapColoringLayer = Lib.ensureSingle(contourLayer, 'g', 'heatmapcoloring'); | ||
var heatmapColoringLayer = Lib.ensureSingle(plotGroup, 'g', 'heatmapcoloring'); | ||
var cdheatmaps = []; | ||
if(contours.coloring === 'heatmap') { | ||
if(trace.zauto && (trace.autocontour === false)) { | ||
|
@@ -62,7 +69,7 @@ function plotOne(gd, plotinfo, cd, contourLayer) { | |
trace._input.zmax = trace.zmax = | ||
trace.zmin + pathinfo.length * contours.size; | ||
} | ||
cdheatmaps = [cd]; | ||
cdheatmaps = [[cd]]; | ||
} | ||
heatmapPlot(gd, plotinfo, cdheatmaps, heatmapColoringLayer); | ||
|
||
|
@@ -87,27 +94,12 @@ function plotOne(gd, plotinfo, cd, contourLayer) { | |
} | ||
|
||
// draw everything | ||
var plotGroup = exports.makeContourGroup(contourLayer, cd, id); | ||
makeBackground(plotGroup, perimeter, contours); | ||
makeFills(plotGroup, fillPathinfo, perimeter, contours); | ||
makeLinesAndLabels(plotGroup, pathinfo, gd, cd[0], contours, perimeter); | ||
clipGaps(plotGroup, plotinfo, fullLayout._clips, cd[0], perimeter); | ||
makeLinesAndLabels(plotGroup, pathinfo, gd, cd, contours, perimeter); | ||
clipGaps(plotGroup, plotinfo, fullLayout._clips, cd, perimeter); | ||
} | ||
|
||
exports.makeContourGroup = function(layer, cd, id) { | ||
var plotgroup = layer | ||
.selectAll('g.contour.' + id) | ||
.data(cd); | ||
|
||
plotgroup.enter().append('g') | ||
.classed('contour', true) | ||
.classed(id, true); | ||
|
||
plotgroup.exit().remove(); | ||
|
||
return plotgroup; | ||
}; | ||
|
||
function makeBackground(plotgroup, perimeter, contours) { | ||
var bggroup = Lib.ensureSingle(plotgroup, 'g', 'contourbg'); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,10 @@ module.exports = function handleStyleDefaults(traceIn, traceOut, coerce, layout, | |
} | ||
|
||
if(coloring !== 'none') { | ||
// plots/plots always coerces showlegend to true, but in this case | ||
// we default to false and (by default) show a colorbar instead | ||
if(traceIn.showlegend !== true) traceOut.showlegend = false; | ||
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. |
||
|
||
colorscaleDefaults( | ||
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'} | ||
); | ||
|
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.
nice touch!
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.