|
d3.patternGetNextClass = function(svg) { |
|
|
|
function increment() { |
|
var selection = svg.select("#d3Pattern-"+i) |
|
if (!selection.empty()) { |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
var i = 0; |
|
while (!increment(i)) { |
|
i++; |
|
if ( i > 1000) break; // upper limit of patterns |
|
} |
|
|
|
return "d3Pattern-"+i; |
|
} |
|
|
|
|
|
|
|
d3.patternStripes = function(p,_) { |
|
var colors = ["olive","white"]; |
|
var stripeWidth = 10; |
|
var angle = 45; |
|
var opacity = 1; |
|
|
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
|
|
|
|
|
|
|
|
function patternStripes() { |
|
|
|
} |
|
|
|
patternStripes.width = function(_) { |
|
if(!_) return stripeWidth; |
|
stripeWidth = _; this.add(); return patternStripes; |
|
} |
|
|
|
patternStripes.colors = function(_) { |
|
if(!_) return colors; |
|
colors = _; this.add(); return patternStripes; |
|
} |
|
|
|
patternStripes.opacity = function(_) { |
|
if(!_) return opacity; |
|
opacity = _; this.add(); return patternStripes; |
|
} |
|
|
|
patternStripes.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternStripes; |
|
} |
|
|
|
patternStripes.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; this.add(); return patternStripes; |
|
} |
|
|
|
patternStripes.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
// set width to an array if not already: |
|
if (!Array.isArray(stripeWidth)) stripeWidth = [stripeWidth]; |
|
|
|
// set opacity to an array if not already: |
|
if (!Array.isArray(opacity)) opacity = [opacity]; |
|
|
|
var totalWidth = 0; |
|
var currentX = 0; |
|
|
|
colors.forEach(function(d,i) { |
|
totalWidth += stripeWidth[i%stripeWidth.length]; |
|
}) |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", totalWidth) |
|
.attr("height", 20) // arbitrary. |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
var rects = pattern.selectAll("rect") |
|
.data(colors); |
|
|
|
rects.exit().remove(); |
|
|
|
var enter = rects.enter() |
|
.append("rect"); |
|
|
|
enter.merge(rects) |
|
.attr("width", function(d,i) { return stripeWidth[i%stripeWidth.length]; }) |
|
.attr("height", 20) |
|
.attr("x", function(d,i) { currentX += stripeWidth[i%stripeWidth.length]; return currentX - stripeWidth[i%stripeWidth.length]; }) |
|
.attr("y",0) |
|
.attr("fill",function(d,i) { return colors[i]; }) |
|
.attr("opacity",function(d,i) { return opacity[i%opacity.length]; }) |
|
|
|
|
|
|
|
return patternStripes; |
|
} |
|
|
|
patternStripes.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternStripes.add(); |
|
return patternStripes; |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Plaid Pattern |
|
///////////////////////////////////////////////////////////////////// |
|
d3.patternPlaid = function(p,_) { |
|
var colorsX = ["steelblue","white"]; |
|
var colorsY = ["darkblue","lightsteelblue"]; |
|
var widthX = 10; |
|
var widthY = 10; |
|
var opacityX = [0.3,0.7]; |
|
var opacityY = [0.3,0.7]; |
|
var angle = 45; |
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
function patternPlaid() { |
|
|
|
} |
|
|
|
patternPlaid.widthX = function(_) { |
|
if(!_) return widthX; |
|
widthX = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.widthY = function(_) { |
|
if(!_) return widthY; |
|
widthY = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.colorsX = function(_) { |
|
if(!_) return colorsX; |
|
colorsX = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.colorsY = function(_) { |
|
if(!_) return colorsY; |
|
colorsY = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.opacityX = function(_) { |
|
if(!_) return opacityX; |
|
opacityX = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.opacityY = function(_) { |
|
if(!_) return opacityY; |
|
opacityY = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.colorsY = function(_) { |
|
if(!_) return colorsY; |
|
colorsY = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; this.add(); return patternPlaid; |
|
} |
|
|
|
patternPlaid.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
// set width to an array if not already: |
|
if (!Array.isArray(widthX)) widthX = [widthX]; |
|
if (!Array.isArray(widthY)) widthY = [widthY]; |
|
|
|
// set opacity to an array if not already: |
|
if (!Array.isArray(opacityX)) opacityX = [opacityX]; |
|
if (!Array.isArray(opacityY)) opacityY = [opacityY]; |
|
|
|
var totalX = 0; |
|
var currentX = 0; |
|
var totalY = 0; |
|
var currentY = 0; |
|
|
|
colorsX.forEach(function(d,i) { |
|
totalX += widthX[i%widthX.length]; |
|
}) |
|
colorsY.forEach(function(d,i) { |
|
totalY += widthY[i%widthY.length]; |
|
}) |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", totalX) |
|
.attr("height", totalY) |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
/////////// X |
|
var rectsX = pattern.selectAll("rectX") |
|
.data(colorsX); |
|
|
|
rectsX.exit().remove(); |
|
|
|
var enter = rectsX.enter() |
|
.append("rect") |
|
.attr("class","rectX"); |
|
|
|
enter.merge(rectsX) |
|
.attr("width", function(d,i) { return widthX[i%widthX.length]; }) |
|
.attr("height", 20) |
|
.attr("x", function(d,i) { currentX += widthX[i%widthX.length]; return currentX - widthX[i%widthX.length]; }) |
|
.attr("y",0) |
|
.attr("fill",function(d,i) { return colorsX[i]; }) |
|
.attr("opacity",function(d,i) { return opacityX[i%opacityX.length]; }) |
|
|
|
//////// Y |
|
var rectsY = pattern.selectAll("rectY") |
|
.data(colorsY); |
|
|
|
rectsY.exit().remove(); |
|
|
|
var enter = rectsY.enter() |
|
.append("rect") |
|
.attr("class","rectY"); |
|
|
|
enter.merge(rectsY) |
|
.attr("height", function(d,i) { return widthY[i%widthY.length]; }) |
|
.attr("width", 20) |
|
.attr("y", function(d,i) { currentY += widthY[i%widthY.length]; return currentY - widthY[i%widthY.length]; }) |
|
.attr("x",0) |
|
.attr("fill",function(d,i) { return colorsY[i]; }) |
|
.attr("opacity",function(d,i) { return opacityY[i%opacityY.length]; }) |
|
|
|
return patternPlaid; |
|
} |
|
|
|
patternPlaid.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternPlaid.add(); |
|
return patternPlaid; |
|
} |
|
|
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Checker Pattern |
|
///////////////////////////////////////////////////////////////////// |
|
d3.patternCheckers = function(p,_) { |
|
var colors = ["orange","white"] |
|
|
|
var width = 10; |
|
var angle = 0; |
|
|
|
var opacity = 1; |
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
function patternCheckers() { |
|
|
|
} |
|
|
|
patternCheckers.width = function(_) { |
|
if(!_) return width; |
|
width = _; this.add(); return patternCheckers; |
|
} |
|
|
|
patternCheckers.colors = function(_) { |
|
if(!_) return colors; |
|
colors = _; this.add(); return patternCheckers; |
|
} |
|
|
|
patternCheckers.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternCheckers; |
|
} |
|
|
|
patternCheckers.opacity = function(_) { |
|
if(!_) return opacity; |
|
opacity = _; this.add(); return patternCheckers; |
|
} |
|
|
|
patternCheckers.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; this.add(); return patternCheckers; |
|
} |
|
|
|
patternCheckers.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
// set opacity to an array if not already: |
|
if (!Array.isArray(opacity)) opacity = [opacity]; |
|
|
|
var totalWidth = width * 2; |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", totalWidth) |
|
.attr("height", totalWidth) |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
pattern.selectAll("rect").remove(); |
|
|
|
var rects = pattern.selectAll("rect") |
|
.data(d3.range(4)) |
|
.enter() |
|
.append("rect") |
|
.attr("width", width ) |
|
.attr("height", width ) |
|
.attr("x", function(d,i) { return i%2 * width; }) |
|
.attr("y", function(d,i) { return Math.floor(i/2) * width; }) |
|
.attr("fill",function(d,i) { return (i == 0 || i == 3) ? colors[0] : colors[1]; } ) |
|
.attr("opacity", function(d,i) { return (i == 0 || i == 3) ? opacity[0] : opacity[1%opacity.length]; } ) |
|
|
|
return patternCheckers; |
|
} |
|
|
|
patternCheckers.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternCheckers.add(); |
|
return patternCheckers; |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Dots Pattern |
|
///////////////////////////////////////////////////////////////////// |
|
d3.patternDots = function(p,_) { |
|
var color = "steelblue"; |
|
var spacing = 5; |
|
var radius = 1; |
|
var angle = 0; |
|
var opacity = 1; |
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
function patternDots() { |
|
|
|
} |
|
|
|
patternDots.spacing = function(_) { |
|
if(!_) return spacing; |
|
spacing = _; this.add(); return patternDots; |
|
} |
|
|
|
patternDots.color = function(_) { |
|
if(!_) return color; |
|
color = _; this.add(); return patternDots; |
|
} |
|
|
|
patternDots.radius = function(_) { |
|
if(!_) return radius; |
|
radius = _; this.add(); return patternDots; |
|
} |
|
|
|
patternDots.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternDots; |
|
} |
|
|
|
patternDots.opacity = function(_) { |
|
if(!_) return opacity; |
|
opacity = _; this.add(); return patternDots; |
|
} |
|
|
|
|
|
patternDots.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; return patternDots; |
|
} |
|
|
|
patternDots.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", spacing) |
|
.attr("height", spacing) |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
var circle = pattern.select("circle"); |
|
|
|
if(circle.empty()) circle = pattern.append("circle"); |
|
|
|
circle |
|
.attr("cx", spacing/2 ) |
|
.attr("cy", spacing/2 ) |
|
.attr("r", radius) |
|
.attr("fill", color); |
|
|
|
return patternDots; |
|
} |
|
|
|
patternDots.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternDots.add(); |
|
return patternDots; |
|
} |
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// symbol |
|
///////////////////////////////////////////////////////////////////// |
|
d3.patternSymbols = function(p,_) { |
|
var color = "crimson"; |
|
var stroke = "none"; |
|
var spacing = 16; |
|
var angle = 0; |
|
|
|
var path = d3.symbol().type(d3.symbolStar); |
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
function patternSymbols() { |
|
|
|
} |
|
|
|
patternSymbols.spacing = function(_) { |
|
if(!_) return spacing; |
|
spacing = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.color = function(_) { |
|
if(!_) return color; |
|
color = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.stroke = function(_) { |
|
if(!_) return stroke; |
|
stroke = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.symbol = function(_) { |
|
if(!_) return path; |
|
path = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; this.add(); return patternSymbols; |
|
} |
|
|
|
patternSymbols.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", spacing) |
|
.attr("height", spacing) |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
var symbol = pattern.select("path"); |
|
|
|
if(symbol.empty()) symbol = pattern.append("path"); |
|
|
|
symbol |
|
.attr("transform","translate("+[spacing/2,spacing/2]+ ")") |
|
.attr("d", path ) |
|
.attr("stroke", stroke) |
|
.attr("fill", color); |
|
|
|
return patternSymbols; |
|
} |
|
|
|
patternSymbols.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternSymbols.add(); |
|
return patternSymbols; |
|
} |
|
|
|
////////////////////////////////////////////////////////////////////// |
|
// Squares Pattern |
|
///////////////////////////////////////////////////////////////////// |
|
d3.patternSquares = function(p,_) { |
|
var color = "steelblue"; |
|
var spacing = 10; |
|
var length = 5; |
|
var angle = 0; |
|
|
|
var id = null; |
|
|
|
var svg = d3.select("svg"); |
|
if(p) svg = p; |
|
|
|
if(_) id = _; |
|
else id = d3.patternGetNextClass(svg); |
|
|
|
function patternSquares() { |
|
|
|
} |
|
|
|
patternSquares.spacing = function(_) { |
|
if(!_) return spacing; |
|
spacing = _; this.add(); return patternSquares; |
|
} |
|
|
|
patternSquares.color = function(_) { |
|
if(!_) return color; |
|
color = _; this.add(); return patternSquares; |
|
} |
|
|
|
patternSquares.edgeLength = function(_) { |
|
if(!_) return length; |
|
length = _; this.add(); return patternSquares; |
|
} |
|
|
|
patternSquares.angle = function(_) { |
|
if(!_) return angle; |
|
angle = _; this.add(); return patternSquares; |
|
} |
|
|
|
patternSquares.svg = function(_) { |
|
if(!_) return svg; |
|
svg = _; this.add(); return patternSquares; |
|
} |
|
|
|
patternSquares.add = function() { |
|
var defs = svg.select("defs"); |
|
|
|
// add defs if not present |
|
if(defs.empty()) defs = svg.append("defs"); |
|
|
|
var pattern = svg.select("#"+id); |
|
// append pattern if needed: |
|
if (pattern.empty()) pattern = defs.append("pattern") |
|
|
|
pattern |
|
.attr("width", spacing) |
|
.attr("height", spacing) |
|
.attr("patternUnits","userSpaceOnUse") |
|
.attr("patternTransform","rotate("+angle+")") |
|
.attr("id",id); |
|
|
|
var rect = pattern.select("rect"); |
|
|
|
if(rect.empty()) rect = pattern.append("rect"); |
|
|
|
rect |
|
.attr("x", spacing/2 - length/2) |
|
.attr("y", spacing/2 - length/2) |
|
.attr("width", length) |
|
.attr("height", length) |
|
.attr("fill", color); |
|
|
|
return patternSquares; |
|
} |
|
|
|
patternSquares.use = function() { |
|
return "url(#"+id+")"; |
|
} |
|
|
|
patternSquares.add(); |
|
return patternSquares; |
|
} |