Skip to content

Commit e83c216

Browse files
authored
Merge pull request #1694 from plotly/fix-tosvg-for-marker-gradients
Fix toImage for marker gradient
2 parents d12d417 + a51fc05 commit e83c216

File tree

2 files changed

+68
-6
lines changed

2 files changed

+68
-6
lines changed

src/snapshot/tosvg.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ var Drawing = require('../components/drawing');
1616
var Color = require('../components/color');
1717

1818
var xmlnsNamespaces = require('../constants/xmlns_namespaces');
19+
var DOUBLEQUOTE_REGEX = /"/g;
20+
var DUMMY_SUB = 'TOBESTRIPPED';
21+
var DUMMY_REGEX = new RegExp('("' + DUMMY_SUB + ')|(' + DUMMY_SUB + '")', 'g');
1922

2023

2124
module.exports = function toSVG(gd, format) {
@@ -90,10 +93,21 @@ module.exports = function toSVG(gd, format) {
9093
// to a string (browsers convert singles back)
9194
var ff = txt.style('font-family');
9295
if(ff && ff.indexOf('"') !== -1) {
93-
txt.style('font-family', ff.replace(/"/g, 'TOBESTRIPPED'));
96+
txt.style('font-family', ff.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));
9497
}
9598
});
9699

100+
svg.selectAll('.point').each(function() {
101+
var pt = d3.select(this);
102+
var fill = pt.style('fill');
103+
104+
// similar to font family styles above,
105+
// we must remove " after the SVG DOM has been serialized
106+
if(fill && fill.indexOf('url(') !== -1) {
107+
pt.style('fill', fill.replace(DOUBLEQUOTE_REGEX, DUMMY_SUB));
108+
}
109+
});
110+
97111
if(format === 'pdf' || format === 'eps') {
98112
// these formats make the extra line MathJax adds around symbols look super thick in some cases
99113
// it looks better if this is removed entirely.
@@ -110,8 +124,8 @@ module.exports = function toSVG(gd, format) {
110124
s = svgTextUtils.html_entity_decode(s);
111125
s = svgTextUtils.xml_entity_encode(s);
112126

113-
// Fix quotations around font strings
114-
s = s.replace(/("TOBESTRIPPED)|(TOBESTRIPPED")/g, '\'');
127+
// Fix quotations around font strings and gradient URLs
128+
s = s.replace(DUMMY_REGEX, '\'');
115129

116130
return s;
117131
};

test/jasmine/tests/snapshot_test.js

+51-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var Plotly = require('@lib/index');
33
var d3 = require('d3');
44
var createGraphDiv = require('../assets/create_graph_div');
55
var destroyGraphDiv = require('../assets/destroy_graph_div');
6+
var fail = require('../assets/fail_test');
67

78
var subplotMock = require('../../image/mocks/multiple_subplots.json');
89
var annotationMock = require('../../image/mocks/annotations.json');
@@ -191,16 +192,15 @@ describe('Plotly.Snapshot', function() {
191192
});
192193

193194
describe('toSVG', function() {
194-
var parser = new DOMParser(),
195-
gd;
195+
var parser = new DOMParser();
196+
var gd;
196197

197198
beforeEach(function() {
198199
gd = createGraphDiv();
199200
});
200201

201202
afterEach(destroyGraphDiv);
202203

203-
204204
it('should not return any nested svg tags of plots', function(done) {
205205
Plotly.plot(gd, subplotMock.data, subplotMock.layout).then(function() {
206206
return Plotly.Snapshot.toSVG(gd);
@@ -245,5 +245,53 @@ describe('Plotly.Snapshot', function() {
245245
done();
246246
});
247247
});
248+
249+
it('should handle quoted style properties', function(done) {
250+
Plotly.plot(gd, [{
251+
y: [1, 2, 1],
252+
marker: {
253+
gradient: {
254+
type: 'radial',
255+
color: '#fff'
256+
},
257+
color: ['red', 'blue', 'green']
258+
}
259+
}], {
260+
font: { family: 'Times New Roman' }
261+
})
262+
.then(function() {
263+
d3.selectAll('text').each(function() {
264+
var tx = d3.select(this);
265+
expect(tx.style('font-family')).toEqual('\"Times New Roman\"');
266+
});
267+
268+
d3.selectAll('.point').each(function() {
269+
var pt = d3.select(this);
270+
expect(pt.style('fill').substr(0, 6)).toEqual('url(\"#');
271+
});
272+
273+
return Plotly.Snapshot.toSVG(gd);
274+
})
275+
.then(function(svg) {
276+
var svgDOM = parser.parseFromString(svg, 'image/svg+xml');
277+
var i;
278+
279+
var textElements = svgDOM.getElementsByTagName('text');
280+
expect(textElements.length).toEqual(11);
281+
282+
for(i = 0; i < textElements.length; i++) {
283+
expect(textElements[i].style['font-family']).toEqual('\"Times New Roman\"');
284+
}
285+
286+
var pointElements = svgDOM.getElementsByClassName('point');
287+
expect(pointElements.length).toEqual(3);
288+
289+
for(i = 0; i < pointElements.length; i++) {
290+
expect(pointElements[i].style.fill.substr(0, 6)).toEqual('url(\"#');
291+
}
292+
})
293+
.catch(fail)
294+
.then(done);
295+
});
248296
});
249297
});

0 commit comments

Comments
 (0)