Published
Edited
Apr 30, 2019
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
function showYear(d) {
let selector = `.year_${d.year}`;
d3.selectAll('.yeargroup').classed('active', false).classed('faded',true);
d3.selectAll(selector).classed('active', true).classed('faded',false);
}
Insert cell
function showAll(d) {
let selector = `.year_${d.year}`;
d3.selectAll('.active').classed('active', false);
d3.selectAll('.faded').classed('faded', false);
}
Insert cell
formatDottedLine = function(selection, dash, gap) {
selection
.attr("stroke", d => colorScale(d.year) )
.attr("fill","none")
.attr("stroke-opacity", 0)
.attr('stroke-dasharray', dash + ',' + gap )
.transition().delay( (d,i) => { return i*2000; })
.ease(d3.easeLinear)
.on("start", d => lineTransition(d).attr("stroke-opacity", 0.6) );
}
Insert cell
function lineTransition(d) {
return d3.transition()
.duration( function(d) { return 500 - (120-d.length); })
}
Insert cell
function tweenDash() {
var l = this.getTotalLength(),
dashInvisible = "0," + 2*l,
dashVisible = l + "," + l,
i = d3.interpolateString(dashInvisible, dashVisible);
return function (t) { return i( Math.min(1, Math.max(0,t*1.5-0.5)) ); };
}
Insert cell
height = 500
Insert cell
margin = ({top: 10, right: 15, bottom: 50, left: 50})
Insert cell
colorScale = d3.scaleLinear()
.domain([2008,2018])
.range(['rgb(10,20,250)','rgb(250,0,155)'])

Insert cell
x = d3.scaleLinear()
.domain([0, d3.max(data, d => (d.consumption.length)) ])
.range([margin.left, width - margin.right])
Insert cell
y = d3.scaleLinear()
.domain([0, d3.max(data.map(d => d3.max(d.consumption.map(d => d[1]) ) ) ) ]).nice(5)
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(g => g.append("text")
.attr("text-anchor", "end")
.attr("font-weight", "bold")
.text("Months after connection") )
.call(d3.axisBottom(x).ticks(width / 80).tickSizeOuter(0))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(data.y))
Insert cell
area = d3.area()
// .curve(d3.curveStep)
.x(d => x(d[0]) )
.y0(d => y(d[3]))
.y1(d => y(d[1]))
Insert cell
medianLine = d3.line()
.x(d => x(d[0]))
.y(d => y(d[2]))
Insert cell
q1Line = d3.line()
.x(d => x(d[0]))
.y(d => y(d[3]))
Insert cell
q3Line = d3.line()
.x(d => x(d[0]))
.y(d => y(d[1]))
Insert cell
html`<style>
.axislabel {
fill: #777; font: 12px;
}


.keygroup {display: none; }
.keygroup.visible {display: block; cursor: pointer; font-size: 12px; }

.year.label, .legendlabel {
font: 600 14px;;
}
.year.label { font-size: 13px; }

.legendlabel { font-size: 12px; }

g.active .keygroup text { font-size: 14px; }
g.active .keygroup path { stroke-width: 2.5px; }

path.medianLine { fill: none; stroke-width: 2px;}

g.active path.medianLine { stroke-width: 3px; }

path.quartileArea { fill-opacity: 0.05; z-index: 0;}

g.active path.quartileArea { fill-opacity: 0.3;}


g.faded path.quartileArea { fill-opacity: 0.01;}
g.faded path.medianLine {stroke-width: 1; stroke-dasharray: 2;}
</style>`
Insert cell
d3 = require("d3@5")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more