diff --git a/draftlogs/6445_fix.md b/draftlogs/6445_fix.md new file mode 100644 index 00000000000..96b19ecac29 --- /dev/null +++ b/draftlogs/6445_fix.md @@ -0,0 +1 @@ + - Fix scaling of exports e.g. the SVG format by not adding vector-effect CSS to static plots [[#6445](https://github.com/plotly/plotly.js/pull/6445)] diff --git a/src/components/errorbars/plot.js b/src/components/errorbars/plot.js index 3a940fa28e0..01803e3abb5 100644 --- a/src/components/errorbars/plot.js +++ b/src/components/errorbars/plot.js @@ -13,6 +13,7 @@ module.exports = function plot(gd, traces, plotinfo, transitionOpts) { var ya = plotinfo.yaxis; var hasAnimation = transitionOpts && transitionOpts.duration > 0; + var isStatic = gd._context.staticPlot; traces.each(function(d) { var trace = d[0].trace; @@ -84,7 +85,7 @@ module.exports = function plot(gd, traces, plotinfo, transitionOpts) { if(isNew) { yerror = errorbar.append('path') - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .classed('yerror', true); } else if(hasAnimation) { yerror = yerror @@ -112,7 +113,7 @@ module.exports = function plot(gd, traces, plotinfo, transitionOpts) { if(isNew) { xerror = errorbar.append('path') - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .classed('xerror', true); } else if(hasAnimation) { xerror = xerror diff --git a/src/traces/bar/plot.js b/src/traces/bar/plot.js index 8876dc3db21..087b9287bf1 100644 --- a/src/traces/bar/plot.js +++ b/src/traces/bar/plot.js @@ -79,6 +79,7 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback) var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; var fullLayout = gd._fullLayout; + var isStatic = gd._context.staticPlot; if(!opts) { opts = { @@ -233,7 +234,7 @@ function plot(gd, plotinfo, cdModule, traceLayer, opts, makeOnCompleteCallback) var sel = transition(Lib.ensureSingle(bar, 'path'), fullLayout, opts, makeOnCompleteCallback); sel - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .attr('d', (isNaN((x1 - x0) * (y1 - y0)) || (isBlank && gd._context.staticPlot)) ? 'M0,0Z' : 'M' + x0 + ',' + y0 + 'V' + y1 + 'H' + x1 + 'V' + y0 + 'Z') .call(Drawing.setClipUrl, plotinfo.layerClipId, gd); diff --git a/src/traces/barpolar/plot.js b/src/traces/barpolar/plot.js index 41015dc3c08..7f4f0f45cf5 100644 --- a/src/traces/barpolar/plot.js +++ b/src/traces/barpolar/plot.js @@ -8,6 +8,7 @@ var Drawing = require('../../components/drawing'); var helpers = require('../../plots/polar/helpers'); module.exports = function plot(gd, subplot, cdbar) { + var isStatic = gd._context.staticPlot; var xa = subplot.xaxis; var ya = subplot.yaxis; var radialAxis = subplot.radialAxis; @@ -21,7 +22,7 @@ module.exports = function plot(gd, subplot, cdbar) { var bars = pointGroup.selectAll('g.point').data(Lib.identity); bars.enter().append('g') - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .style('stroke-miterlimit', 2) .classed('point', true); diff --git a/src/traces/box/plot.js b/src/traces/box/plot.js index d62c00079f5..3fd80ce070e 100644 --- a/src/traces/box/plot.js +++ b/src/traces/box/plot.js @@ -10,6 +10,7 @@ var JITTERCOUNT = 5; // points either side of this to include var JITTERSPREAD = 0.01; // fraction of IQR to count as "dense" function plot(gd, plotinfo, cdbox, boxLayer) { + var isStatic = gd._context.staticPlot; var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; @@ -37,13 +38,13 @@ function plot(gd, plotinfo, cdbox, boxLayer) { valAxis = ya; } - plotBoxAndWhiskers(plotGroup, {pos: posAxis, val: valAxis}, trace, t); + plotBoxAndWhiskers(plotGroup, {pos: posAxis, val: valAxis}, trace, t, isStatic); plotPoints(plotGroup, {x: xa, y: ya}, trace, t); plotBoxMean(plotGroup, {pos: posAxis, val: valAxis}, trace, t); }); } -function plotBoxAndWhiskers(sel, axes, trace, t) { +function plotBoxAndWhiskers(sel, axes, trace, t, isStatic) { var isHorizontal = trace.orientation === 'h'; var valAxis = axes.val; var posAxis = axes.pos; @@ -73,7 +74,7 @@ function plotBoxAndWhiskers(sel, axes, trace, t) { ) ? Lib.identity : []); paths.enter().append('path') - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .attr('class', 'box'); paths.exit().remove(); diff --git a/src/traces/carpet/plot.js b/src/traces/carpet/plot.js index f8b944e7d66..75f2f9bf198 100644 --- a/src/traces/carpet/plot.js +++ b/src/traces/carpet/plot.js @@ -12,6 +12,7 @@ var strTranslate = Lib.strTranslate; var alignmentConstants = require('../../constants/alignment'); module.exports = function plot(gd, plotinfo, cdcarpet, carpetLayer) { + var isStatic = gd._context.staticPlot; var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; var fullLayout = gd._fullLayout; @@ -31,15 +32,15 @@ module.exports = function plot(gd, plotinfo, cdcarpet, carpetLayer) { axisLayer.style('opacity', trace.opacity); - drawGridLines(xa, ya, majorLayer, aax, 'a', aax._gridlines, true); - drawGridLines(xa, ya, majorLayer, bax, 'b', bax._gridlines, true); - drawGridLines(xa, ya, minorLayer, aax, 'a', aax._minorgridlines, true); - drawGridLines(xa, ya, minorLayer, bax, 'b', bax._minorgridlines, true); + drawGridLines(xa, ya, majorLayer, aax, 'a', aax._gridlines, true, isStatic); + drawGridLines(xa, ya, majorLayer, bax, 'b', bax._gridlines, true, isStatic); + drawGridLines(xa, ya, minorLayer, aax, 'a', aax._minorgridlines, true, isStatic); + drawGridLines(xa, ya, minorLayer, bax, 'b', bax._minorgridlines, true, isStatic); // NB: These are not omitted if the lines are not active. The joins must be executed // in order for them to get cleaned up without a full redraw - drawGridLines(xa, ya, boundaryLayer, aax, 'a-boundary', aax._boundarylines); - drawGridLines(xa, ya, boundaryLayer, bax, 'b-boundary', bax._boundarylines); + drawGridLines(xa, ya, boundaryLayer, aax, 'a-boundary', aax._boundarylines, isStatic); + drawGridLines(xa, ya, boundaryLayer, bax, 'b-boundary', bax._boundarylines, isStatic); var labelOrientationA = drawAxisLabels(gd, xa, ya, trace, cd0, labelLayer, aax._labels, 'a-label'); var labelOrientationB = drawAxisLabels(gd, xa, ya, trace, cd0, labelLayer, bax._labels, 'b-label'); @@ -79,13 +80,13 @@ function drawClipPath(trace, t, layer, xaxis, yaxis) { path.attr('d', clipPathData); } -function drawGridLines(xaxis, yaxis, layer, axis, axisLetter, gridlines) { +function drawGridLines(xaxis, yaxis, layer, axis, axisLetter, gridlines, isStatic) { var lineClass = 'const-' + axisLetter + '-lines'; var gridJoin = layer.selectAll('.' + lineClass).data(gridlines); gridJoin.enter().append('path') .classed(lineClass, true) - .style('vector-effect', 'non-scaling-stroke'); + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke'); gridJoin.each(function(d) { var gridline = d; diff --git a/src/traces/contour/plot.js b/src/traces/contour/plot.js index 76b4520fea9..e1728aca3c4 100644 --- a/src/traces/contour/plot.js +++ b/src/traces/contour/plot.js @@ -200,6 +200,7 @@ function joinAllPaths(pi, perimeter) { } function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours) { + var isStatic = gd._context.staticPlot; var lineContainer = Lib.ensureSingle(plotgroup, 'g', 'contourlines'); var showLines = contours.showlines !== false; var showLabels = contours.showlabels; @@ -209,7 +210,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours) { // if we're showing labels, because the fill paths include the perimeter // so can't be used to position the labels correctly. // In this case we'll remove the lines after making the labels. - var linegroup = exports.createLines(lineContainer, showLines || showLabels, pathinfo); + var linegroup = exports.createLines(lineContainer, showLines || showLabels, pathinfo, isStatic); var lineClip = exports.createLineClip(lineContainer, clipLinesForLabels, gd, cd0.trace.uid); @@ -318,7 +319,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours) { if(showLabels && !showLines) linegroup.remove(); } -exports.createLines = function(lineContainer, makeLines, pathinfo) { +exports.createLines = function(lineContainer, makeLines, pathinfo, isStatic) { var smoothing = pathinfo[0].smoothing; var linegroup = lineContainer.selectAll('g.contourlevel') @@ -343,7 +344,7 @@ exports.createLines = function(lineContainer, makeLines, pathinfo) { return Drawing.smoothopen(d, smoothing); }) .style('stroke-miterlimit', 1) - .style('vector-effect', 'non-scaling-stroke'); + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke'); var closedcontourlines = linegroup.selectAll('path.closedline') .data(function(d) { return d.ppaths || d.paths; }); @@ -357,7 +358,7 @@ exports.createLines = function(lineContainer, makeLines, pathinfo) { return Drawing.smoothclosed(d, smoothing); }) .style('stroke-miterlimit', 1) - .style('vector-effect', 'non-scaling-stroke'); + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke'); } return linegroup; diff --git a/src/traces/contourcarpet/plot.js b/src/traces/contourcarpet/plot.js index 2b2181c9a84..807b5c01402 100644 --- a/src/traces/contourcarpet/plot.js +++ b/src/traces/contourcarpet/plot.js @@ -134,6 +134,7 @@ function mapPathinfo(pathinfo, map) { } function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, plotinfo, carpet) { + var isStatic = gd._context.staticPlot; var lineContainer = Lib.ensureSingle(plotgroup, 'g', 'contourlines'); var showLines = contours.showlines !== false; var showLabels = contours.showlabels; @@ -143,7 +144,7 @@ function makeLinesAndLabels(plotgroup, pathinfo, gd, cd0, contours, plotinfo, ca // if we're showing labels, because the fill paths include the perimeter // so can't be used to position the labels correctly. // In this case we'll remove the lines after making the labels. - var linegroup = contourPlot.createLines(lineContainer, showLines || showLabels, pathinfo); + var linegroup = contourPlot.createLines(lineContainer, showLines || showLabels, pathinfo, isStatic); var lineClip = contourPlot.createLineClip(lineContainer, clipLinesForLabels, gd, cd0.trace.uid); diff --git a/src/traces/scatter/plot.js b/src/traces/scatter/plot.js index 6a3bc9ee0d3..eb2e3977943 100644 --- a/src/traces/scatter/plot.js +++ b/src/traces/scatter/plot.js @@ -105,6 +105,7 @@ function createFills(gd, traceJoin, plotinfo) { } function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transitionOpts) { + var isStatic = gd._context.staticPlot; var i; // Since this has been reorganized and we're executing this on individual traces, @@ -279,7 +280,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition lineJoin.enter().append('path') .classed('js-line', true) - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .call(Drawing.lineGroupStyle) .each(makeUpdate(true)); diff --git a/src/traces/violin/plot.js b/src/traces/violin/plot.js index b46292d319d..da5a8a837b7 100644 --- a/src/traces/violin/plot.js +++ b/src/traces/violin/plot.js @@ -9,6 +9,7 @@ var linePoints = require('../scatter/line_points'); var helpers = require('./helpers'); module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { + var isStatic = gd._context.staticPlot; var fullLayout = gd._fullLayout; var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; @@ -49,7 +50,7 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { var violins = plotGroup.selectAll('path.violin').data(Lib.identity); violins.enter().append('path') - .style('vector-effect', 'non-scaling-stroke') + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke') .attr('class', 'violin'); violins.exit().remove(); @@ -163,7 +164,7 @@ module.exports = function plot(gd, plotinfo, cdViolins, violinLayer) { meanPaths.enter().append('path') .attr('class', 'meanline') .style('fill', 'none') - .style('vector-effect', 'non-scaling-stroke'); + .style('vector-effect', isStatic ? 'none' : 'non-scaling-stroke'); meanPaths.exit().remove(); meanPaths.each(function(d) { var v = valAxis.c2p(d.mean, true); diff --git a/test/image/baselines/17.png b/test/image/baselines/17.png index 3b1d48b8e77..7ada2d9cc3e 100644 Binary files a/test/image/baselines/17.png and b/test/image/baselines/17.png differ diff --git a/test/image/baselines/28.png b/test/image/baselines/28.png index 6e2f8ac543a..0e12130bb3b 100644 Binary files a/test/image/baselines/28.png and b/test/image/baselines/28.png differ diff --git a/test/image/baselines/line_scatter.png b/test/image/baselines/line_scatter.png index 227f9fd3c91..95b08021ecf 100644 Binary files a/test/image/baselines/line_scatter.png and b/test/image/baselines/line_scatter.png differ