Skip to content

Revert "Add pattern fill for histogram, bar and barpolar traces" #5539

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

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 1 addition & 214 deletions src/components/drawing/index.js
Original file line number Diff line number Diff line change
@@ -354,185 +354,6 @@ drawing.gradient = function(sel, gd, gradientID, type, colorscale, prop) {
fullLayout._gradientUrlQueryParts[k] = 1;
};

/**
* pattern: create and apply a pattern fill
*
* @param {object} sel: d3 selection to apply this pattern to
* You can use `selection.call(Drawing.pattern, ...)`
* @param {DOM element} gd: the graph div `sel` is part of
* @param {string} patternID: a unique (within this plot) identifier
* for this pattern, so that we don't create unnecessary definitions
* @param {string} bgcolor: background color for this pattern
* @param {string} fgcolor: foreground color for this pattern
* @param {number} size: size of unit squares for repetition of this pattern
* @param {number} solidity: how solid lines of this pattern are
* @param {string} prop: the property to apply to, 'fill' or 'stroke'
*/
drawing.pattern = function(sel, gd, patternID, shape, bgcolor, fgcolor, size, solidity, prop) {
var fullLayout = gd._fullLayout;
var fullID = 'p' + fullLayout._uid + '-' + patternID;
var width, height;

// linear interpolation
var linearFn = function(x, x0, x1, y0, y1) {
return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
};

var path, linewidth, radius;
var patternTag;
var patternAttrs = {};
switch(shape) {
case '/':
width = size * Math.sqrt(2);
height = size * Math.sqrt(2);
path = 'M-' + (width / 4) + ',' + (height / 4) + 'l' + (width / 2) + ',-' + (height / 2) +
'M0,' + height + 'L' + width + ',0' +
'M' + (width / 4 * 3) + ',' + (height / 4 * 5) + 'l' + (width / 2) + ',-' + (height / 2);
linewidth = solidity * size;
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case '\\':
width = size * Math.sqrt(2);
height = size * Math.sqrt(2);
path = 'M' + (width / 4 * 3) + ',-' + (height / 4) + 'l' + (width / 2) + ',' + (height / 2) +
'M0,0L' + width + ',' + height +
'M-' + (width / 4) + ',' + (height / 4 * 3) + 'l' + (width / 2) + ',' + (height / 2);
linewidth = solidity * size;
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case 'x':
width = size * Math.sqrt(2);
height = size * Math.sqrt(2);
path = 'M-' + (width / 4) + ',' + (height / 4) + 'l' + (width / 2) + ',-' + (height / 2) +
'M0,' + height + 'L' + width + ',0' +
'M' + (width / 4 * 3) + ',' + (height / 4 * 5) + 'l' + (width / 2) + ',-' + (height / 2) +
'M' + (width / 4 * 3) + ',-' + (height / 4) + 'l' + (width / 2) + ',' + (height / 2) +
'M0,0L' + width + ',' + height +
'M-' + (width / 4) + ',' + (height / 4 * 3) + 'l' + (width / 2) + ',' + (height / 2);
linewidth = size - size * Math.sqrt(1.0 - solidity);
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case '|':
width = size;
height = size;
patternTag = 'path';
path = 'M' + (width / 2) + ',0L' + (width / 2) + ',' + height;
linewidth = solidity * size;
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case '-':
width = size;
height = size;
patternTag = 'path';
path = 'M0,' + (height / 2) + 'L' + width + ',' + (height / 2);
linewidth = solidity * size;
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case '+':
width = size;
height = size;
patternTag = 'path';
path = 'M' + (width / 2) + ',0L' + (width / 2) + ',' + height +
'M0,' + (height / 2) + 'L' + width + ',' + (height / 2);
linewidth = size - size * Math.sqrt(1.0 - solidity);
patternTag = 'path';
patternAttrs = {
'd': path,
'stroke': fgcolor,
'stroke-width': linewidth + 'px'
};
break;
case '.':
width = size;
height = size;
if(solidity < Math.PI / 4) {
radius = Math.sqrt(solidity * size * size / Math.PI);
} else {
radius = linearFn(solidity, Math.PI / 4, 1.0, size / 2, size / Math.sqrt(2));
}
patternTag = 'circle';
patternAttrs = {
'cx': width / 2,
'cy': height / 2,
'r': radius,
'fill': fgcolor
};
break;
}

var pattern = fullLayout._defs.select('.patterns')
.selectAll('#' + fullID)
.data([shape + ';' + bgcolor + ';' + fgcolor + ';' + size + ';' + solidity], Lib.identity);

pattern.exit().remove();

pattern.enter()
.append('pattern')
.each(function() {
var el = d3.select(this);

el.attr({
'id': fullID,
'width': width + 'px',
'height': height + 'px',
'patternUnits': 'userSpaceOnUse'
});

if(bgcolor) {
var rects = el.selectAll('rect').data([0]);
rects.exit().remove();
rects.enter()
.append('rect')
.attr({
'width': width + 'px',
'height': height + 'px',
'fill': bgcolor
});
}

var patterns = el.selectAll(patternTag).data([0]);
patterns.exit().remove();
patterns.enter()
.append(patternTag)
.attr(patternAttrs);
});

sel.style(prop, getFullUrl(fullID, gd))
.style(prop + '-opacity', null);

sel.classed('pattern_filled', true);
var className2query = function(s) {
return '.' + s.attr('class').replace(/\s/g, '.');
};
var k = className2query(d3.select(sel.node().parentNode)) + '>.pattern_filled';
fullLayout._patternUrlQueryParts[k] = 1;
};

/*
* Make the gradients container and clear out any previous gradients.
* We never collect all the gradients we need in one place,
@@ -551,23 +372,6 @@ drawing.initGradients = function(gd) {
fullLayout._gradientUrlQueryParts = {};
};

drawing.initPatterns = function(gd) {
var fullLayout = gd._fullLayout;

var patternsGroup = Lib.ensureSingle(fullLayout._defs, 'g', 'patterns');
patternsGroup.selectAll('pattern').remove();

// initialize stash of query parts filled in Drawing.pattern,
// used to fix URL strings during image exports
fullLayout._patternUrlQueryParts = {};
};

drawing.getPatternAttr = function(mp, i, dflt) {
if(mp && Lib.isArrayOrTypedArray(mp)) {
return i < mp.length ? mp[i] : dflt;
}
return mp;
};

drawing.pointStyle = function(s, trace, gd) {
if(!s.size()) return;
@@ -673,14 +477,11 @@ drawing.singlePointStyle = function(d, sel, trace, fns, gd) {

// for legend - arrays will propagate through here, but we don't need
// to treat it as per-point.
if(Lib.isArrayOrTypedArray(gradientType)) {
if(Array.isArray(gradientType)) {
gradientType = gradientType[0];
if(!gradientInfo[gradientType]) gradientType = 0;
}

var markerPattern = marker.pattern;
var patternShape = markerPattern && drawing.getPatternAttr(markerPattern.shape, d.i, '');

if(gradientType && gradientType !== 'none') {
var gradientColor = d.mgc;
if(gradientColor) perPointGradient = true;
@@ -691,20 +492,6 @@ drawing.singlePointStyle = function(d, sel, trace, fns, gd) {

drawing.gradient(sel, gd, gradientID, gradientType,
[[0, gradientColor], [1, fillColor]], 'fill');
} else if(patternShape) {
var patternBGColor = drawing.getPatternAttr(markerPattern.bgcolor, d.i, null);
var patternSize = drawing.getPatternAttr(markerPattern.size, d.i, 8);
var patternSolidity = drawing.getPatternAttr(markerPattern.solidity, d.i, 0.3);
var perPointPattern = Lib.isArrayOrTypedArray(markerPattern.shape) ||
Lib.isArrayOrTypedArray(markerPattern.bgcolor) ||
Lib.isArrayOrTypedArray(markerPattern.size) ||
Lib.isArrayOrTypedArray(markerPattern.solidity);

var patternID = trace.uid;
if(perPointPattern) patternID += '-' + d.i;

drawing.pattern(sel, gd, patternID, patternShape, patternBGColor, fillColor,
patternSize, patternSolidity, 'fill');
} else {
Color.fill(sel, fillColor);
}
19 changes: 2 additions & 17 deletions src/components/legend/style.js
Original file line number Diff line number Diff line change
@@ -357,23 +357,8 @@ module.exports = function style(s, gd, legend) {
var d0 = d[0];
var w = boundLineWidth(d0.mlw, marker.line, MAX_MARKER_LINE_WIDTH, CST_MARKER_LINE_WIDTH);

p.style('stroke-width', w + 'px');

var fillColor = d0.mc || marker.color;

var markerPattern = marker.pattern;
var patternShape = markerPattern && Drawing.getPatternAttr(markerPattern.shape, 0, '');

if(patternShape) {
var patternBGColor = Drawing.getPatternAttr(markerPattern.bgcolor, 0, null);
var patternSize = Math.min(12, Drawing.getPatternAttr(markerPattern.size, 0, 8));
var patternSolidity = Drawing.getPatternAttr(markerPattern.solidity, 0, 0.3);
var patternID = 'legend-' + trace.uid;
p.call(Drawing.pattern, gd, patternID, patternShape, patternBGColor,
fillColor, patternSize, patternSolidity, 'fill');
} else {
p.call(Color.fill, fillColor);
}
p.style('stroke-width', w + 'px')
.call(Color.fill, d0.mc || marker.color);

if(w) Color.stroke(p, d0.mlc || markerLine.color);
});
3 changes: 1 addition & 2 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
@@ -144,9 +144,8 @@ function _doPlot(gd, data, layout, config) {
}
}

// clear gradient and pattern defs on each .plot call, because we know we'll loop through all traces
// clear gradient defs on each .plot call, because we know we'll loop through all traces
Drawing.initGradients(gd);
Drawing.initPatterns(gd);

// save initial show spikes once per graph
if(graphWasEmpty) Axes.saveShowSpikeInitial(gd);
47 changes: 22 additions & 25 deletions src/snapshot/tosvg.js
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ module.exports = function toSVG(gd, format, scale) {
var toppaper = fullLayout._toppaper;
var width = fullLayout.width;
var height = fullLayout.height;
var i, k;
var i;

// make background color a rect in the svg, then revert after scraping
// all other alterations have been dealt with by properly preparing the svg
@@ -106,31 +106,28 @@ module.exports = function toSVG(gd, format, scale) {
}
});

var queryParts = [];
if(fullLayout._gradientUrlQueryParts) {
for(k in fullLayout._gradientUrlQueryParts) queryParts.push(k);
}

if(fullLayout._patternUrlQueryParts) {
for(k in fullLayout._patternUrlQueryParts) queryParts.push(k);
}

if(queryParts.length) {
svg.selectAll(queryParts.join(',')).each(function() {
var pt = d3.select(this);

// 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(fullLayout._gradientUrlQueryParts) {
var queryParts = [];
for(var k in fullLayout._gradientUrlQueryParts) queryParts.push(k);

if(queryParts.length) {
svg.selectAll(queryParts.join(',')).each(function() {
var pt = d3.select(this);

// 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') {
Loading