Skip to content

Commit

Permalink
fix toSVG for contour legend items & <linearGradient> colorbars
Browse files Browse the repository at this point in the history
  • Loading branch information
etpinard committed Aug 16, 2018
1 parent 89fae05 commit b32aac0
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 44 deletions.
9 changes: 7 additions & 2 deletions src/snapshot/tosvg.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,20 @@ module.exports = function toSVG(gd, format, scale) {
}
});

svg.selectAll('.point,.scatterpts').each(function() {
svg.selectAll('.point, .scatterpts, .legendfill>path, .legendlines>path, .cbfill').each(function() {
var pt = d3.select(this);
var fill = this.style.fill;

// similar to font family styles above,
// we must remove " after the SVG DOM has been serialized
var fill = this.style.fill;
if(fill && fill.indexOf('url(') !== -1) {
pt.style('fill', fill.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));
}

var stroke = this.style.stroke;
if(stroke && stroke.indexOf('url(') !== -1) {
pt.style('stroke', stroke.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));
}
});

if(format === 'pdf' || format === 'eps') {
Expand Down
131 changes: 89 additions & 42 deletions test/jasmine/tests/snapshot_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var Plotly = require('@lib/index');
var Lib = require('@src/lib');

var d3 = require('d3');
var createGraphDiv = require('../assets/create_graph_div');
Expand Down Expand Up @@ -250,55 +251,101 @@ describe('Plotly.Snapshot', function() {
});
});

it('should handle quoted style properties', function(done) {
Plotly.plot(gd, [{
y: [1, 2, 1],
marker: {
gradient: {
type: 'radial',
color: '#fff'
},
color: ['red', 'blue', 'green']
}
}], {
font: { family: 'Times New Roman' },
showlegend: true
})
.then(function() {
d3.selectAll('text').each(function() {
expect(this.style.fontFamily).toEqual('\"Times New Roman\"');
});
describe('should handle quoted style properties', function() {
function checkURL(actual, msg) {
// which is enough tot check that toSVG did its job right
expect((actual || '').substr(0, 6)).toBe('url(\"#', msg);
}

d3.selectAll('.point,.scatterpts').each(function() {
expect(this.style.fill.substr(0, 6)).toEqual('url(\"#');
});
it('- marker-gradient case', function(done) {
Plotly.plot(gd, [{
y: [1, 2, 1],
marker: {
gradient: {
type: 'radial',
color: '#fff'
},
color: ['red', 'blue', 'green']
}
}], {
font: { family: 'Times New Roman' },
showlegend: true
})
.then(function() {
d3.selectAll('text').each(function() {
expect(this.style.fontFamily).toEqual('\"Times New Roman\"');
});

d3.selectAll('.point,.scatterpts').each(function() {
checkURL(this.style.fill);
});

return Plotly.Snapshot.toSVG(gd);
})
.then(function(svg) {
var svgDOM = parser.parseFromString(svg, 'image/svg+xml');
var i;

var textElements = svgDOM.getElementsByTagName('text');
expect(textElements.length).toEqual(12);

for(i = 0; i < textElements.length; i++) {
expect(textElements[i].style.fontFamily).toEqual('\"Times New Roman\"');
}

return Plotly.Snapshot.toSVG(gd);
})
.then(function(svg) {
var svgDOM = parser.parseFromString(svg, 'image/svg+xml');
var i;
var pointElements = svgDOM.getElementsByClassName('point');
expect(pointElements.length).toEqual(3);

for(i = 0; i < pointElements.length; i++) {
checkURL(pointElements[i].style.fill);
}

var textElements = svgDOM.getElementsByTagName('text');
expect(textElements.length).toEqual(12);
var legendPointElements = svgDOM.getElementsByClassName('scatterpts');
expect(legendPointElements.length).toEqual(1);
checkURL(legendPointElements[0].style.fill);
})
.catch(failTest)
.then(done);
});

for(i = 0; i < textElements.length; i++) {
expect(textElements[i].style.fontFamily).toEqual('\"Times New Roman\"');
}
it('- legend with contour items case', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/contour_legend.json'));
var fillItemIndices = [0, 4, 5];

var pointElements = svgDOM.getElementsByClassName('point');
expect(pointElements.length).toEqual(3);
Plotly.plot(gd, fig)
.then(function() { return Plotly.Snapshot.toSVG(gd); })
.then(function(svg) {
var svgDOM = parser.parseFromString(svg, 'image/svg+xml');

for(i = 0; i < pointElements.length; i++) {
expect(pointElements[i].style.fill.substr(0, 6)).toEqual('url(\"#');
}
var fillItems = svgDOM.getElementsByClassName('legendfill');
for(var i = 0; i < fillItemIndices.length; i++) {
checkURL(fillItems[fillItemIndices[i]].firstChild.style.fill, 'fill gradient ' + i);
}

var legendPointElements = svgDOM.getElementsByClassName('scatterpts');
expect(legendPointElements.length).toEqual(1);
expect(legendPointElements[0].style.fill.substr(0, 6)).toEqual('url(\"#');
})
.catch(failTest)
.then(done);
var lineItems = svgDOM.getElementsByClassName('legendlines');
checkURL(lineItems[1].firstChild.style.stroke, 'stroke gradient');
})
.catch(failTest)
.then(done);
});

it('- colorbar case', function(done) {
var fig = Lib.extendDeep({}, require('@mocks/16.json'));

Plotly.plot(gd, fig)
.then(function() { return Plotly.Snapshot.toSVG(gd); })
.then(function(svg) {
var svgDOM = parser.parseFromString(svg, 'image/svg+xml');

var fillItems = svgDOM.getElementsByClassName('cbfill');
expect(fillItems.length).toBe(1, '# of colorbars');
for(var i = 0; i < fillItems.length; i++) {
checkURL(fillItems[i].style.fill, 'fill gradient ' + i);
}
})
.catch(failTest)
.then(done);
});
});

it('should adapt *viewBox* attribute under *scale* option', function(done) {
Expand Down

0 comments on commit b32aac0

Please sign in to comment.