Skip to content

Instantly share code, notes, and snippets.

@goude
Last active June 3, 2016 13:19
Show Gist options
  • Save goude/a71dbb47995c1ae768bdfb963d1cbcf9 to your computer and use it in GitHub Desktop.
Save goude/a71dbb47995c1ae768bdfb963d1cbcf9 to your computer and use it in GitHub Desktop.
D3 Variable Width Lines (copy of http://bl.ocks.org/larskotthoff/1642835, currently not working)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="line-variable.js"></script>
</head>
<body>
<div id="linevar"></div>
<script type="text/javascript">
(function () {
var dat = [{x: 20, y: 20, w: 0},
{x: 20, y: 150, w: 30},
{x: 80, y: 100, w: 20},
{x: 200, y: 100, w: 10},
{x: 300, y: 100, w: 20},
{x: 380, y: 100, w: 0}],
svg = d3.select("#linevar")
.append("svg:svg")
.attr("height", 200)
.attr("width", 400);
var linevar = d3.svg.line.variable()
.interpolate("basis")
.w(function(d) { return d.w; })
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
svg.selectAll("path").data([dat]).enter()
.append("svg:path")
.attr("d", linevar);
})();
</script>
</body>
</html>
d3.svg.line.variable = function() {
return d3_svg_lineVariable();
}
function d3_svg_lineVariable() {
var x = function(d) { return d[0]; },
y = function(d) { return d[1]; },
w = 5,
intpol = "linear",
t = .7;
function lineVariable(d) {
return d.length < 1 ? null :
d3_svg_lineVariablePoints(this, d, x, y, w, intpol, t) + "Z";
}
lineVariable.x = function(v) {
if(!arguments.length) return x;
x = v;
return lineVariable;
};
lineVariable.y = function(v) {
if(!arguments.length) return y;
y = v;
return lineVariable;
};
lineVariable.w = function(v) {
if(!arguments.length) return w;
w = v;
return lineVariable;
};
lineVariable.interpolate = function(v) {
if (!arguments.length) return intpol;
intpol = v;
return lineVariable;
};
lineVariable.tension = function(v) {
if (!arguments.length) return t;
t = v;
return lineVariable;
};
return lineVariable;
};
function d3_svg_lineVariablePoints(self, d, x, y, w, intpol, t) {
var spinePoints = [],
points = [],
tmpStack = [],
i = -1,
n = d.length,
fx = typeof x === "function",
fy = typeof y === "function",
fw = typeof w === "function",
line = d3.svg.line().interpolate(intpol).tension(t),
value;
if(fx && fy) {
while(++i < n) spinePoints.push([
x.call(self, value = d[i], i),
y.call(self, value, i)
]);
} else if(fx) {
while(++i < n) spinePoints.push([x.call(self, d[i], i), y]);
} else if(fy) {
while(++i < n) spinePoints.push([x, y.call(self, d[i], i)]);
} else {
while(++i < n) spinePoints.push([x, y]);
}
for(i = 0; i < n; i++) {
var thisx = spinePoints[i][0],
thisy = spinePoints[i][1],
width = fw ? w.call(self, d[i], i) : w,
aleft = Math.PI, aright = 0;
if(i > 0) {
var dx = thisx - spinePoints[i-1][0],
dy = thisy - spinePoints[i-1][1];
aleft = Math.PI - Math.atan2(dy, dx);
}
if(i < n-1) {
var dx = spinePoints[i+1][0] - thisx,
dy = thisy - spinePoints[i+1][1];
aright = Math.atan2(dy, dx);
}
var gamma = aleft - aright,
diff = width/2 / Math.sin(gamma/2),
aup = aright + gamma/2,
adown = aup - Math.PI,
dxup = diff * Math.cos(aup),
dyup = diff * Math.sin(aup),
dxdown = diff * Math.cos(adown),
dydown = diff * Math.sin(adown);
points.push([thisx + dxup, thisy - dyup]);
tmpStack.push([thisx + dxdown, thisy - dydown]);
}
var line0 = line(points),
// change moveto to lineto as we are continuing the line
line1 = line(tmpStack.reverse()).replace("M", "L");
return line0 + line1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment