Skip to content

Instantly share code, notes, and snippets.

@febret
Created May 14, 2018 15:46
Show Gist options
  • Save febret/d0723770071dac8282b834c61c6a382e to your computer and use it in GitHub Desktop.
Save febret/d0723770071dac8282b834c61c6a382e to your computer and use it in GitHub Desktop.
D3 conditional line coloring
// Draw a line out of multiple paths crossing upper and lower bounds.
// The path definitions ensure there are no gaps between segments.
const makeLine = (data, style) => {
let cx = this.xs(fastMoment(data[0][seriesxMet]));
let cv = data[0][seriesyMet];
let coords = [{x: cx, y: this.ys(cv), s: Math.sign(cv)}];
for (let i = 1; i < data.length; i++) {
let nx = this.xs(fastMoment(data[i][seriesxMet]));
let nv = data[i][seriesyMet];
// Add bound-crossing points.
if (seriesUBMet in data[i] && seriesLBMet in data[i]) {
const ub = data[i][seriesUBMet];
const lb = data[i][seriesLBMet];
const db = (ub - lb) * 0.1;
const ub10 = ub - db;
const lb10 = lb + db;
const hx = cx + (nx - cx) * 0.5;
if ((nv - ub) * (cv - ub) <= 0) {
coords.push({ x: hx, y: this.ys(ub), s: -2 });
}
if ((nv - lb) * (cv - lb) <= 0) {
coords.push({ x: hx, y: this.ys(lb), s: -2 });
}
if ((nv - ub10) * (cv - ub10) <= 0) {
coords.push({ x: hx, y: this.ys(ub10), s: 0 });
}
if ((nv - lb10) * (cv - lb10) <= 0) {
coords.push({ x: hx, y: this.ys(lb10), s: 0 });
}
let s = 1;
if (nv > ub10 || nv < lb10) {
s = (nv > ub || nv < lb) ? -3 : -1;
}
coords.push({ x: nx, y: this.ys(nv), s });
} else {
coords.push({ x: nx, y: this.ys(nv), s: 1 });
}
cx = nx;
cv = nv;
}
const pos = d3.line()
.x((d) => d.x)
.y((d) => d.y);
//.defined((d) => d.s >= 0);
const neg = d3.line()
.x((d) => d.x)
.y((d) => d.y)
.defined((d) => d.s <= 0);
const warn = d3.line()
.x((d) => d.x)
.y((d) => d.y)
.defined((d) => d.s <= 0 && d.s >= -2);
trend.append('path')
.style('stroke', lightBlueC5)
.attr('fill-opacity', 0)
.attr('d', pos(coords))
.call(style);
trend.append('path')
.style('stroke', lightBlueC5)
.attr('fill-opacity', 0)
.attr('d', neg(coords))
.call(style);
trend.append('path')
.style('stroke', lightBlueC5)
.attr('fill-opacity', 0)
.attr('d', warn(coords))
.call(style);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment