Skip to content

Instantly share code, notes, and snippets.

@Saigesp Saigesp/.block
Last active Oct 19, 2018

Embed
What would you like to do?
D3v4 Warming stripes
eda813560c801474904004d6b6b1cc4c

Warming stripes

D3 implementation of warming stripes.

See the demo and more charts from d3graphs repository

Features:

  • Object oriented approach
  • Responsive

Requires:

  • D3 v4+

Default options:

{
    'margin': {'top': 30, 'right': 70, 'bottom': 36, 'left': 10},
    'key': 'key',
    'colorScale': d3.interpolateRdBu,
    'label': false,
    'label_x': 35,
    'label_y': 14,
    'units': 'ºC',
    'legendRanges': false, // [13,14,15,16]
    'title': false,
    'source': false,
}
class StripeLines{
constructor(selection, data, config = {}) {
let self = this;
this.selection = selection;
this.data = data;
// Graph configuration
this.cfg = {
'margin': {'top': 30, 'right': 70, 'bottom': 36, 'left': 10},
'key': 'key',
'colorScale': d3.interpolateRdBu,
'label': false,
'label_x': 35,
'label_y': 14,
'units': 'ºC',
'legendRanges': false, // [13,14,15,16]
'title': false,
'source': false,
};
Object.keys(config).forEach(function(key) {
if(config[key] instanceof Object && config[key] instanceof Array === false){
Object.keys(config[key]).forEach(function(sk) {
self.cfg[key][sk] = config[key][sk];
});
} else self.cfg[key] = config[key];
});
this.cfg.width = parseInt(this.selection.node().offsetWidth) - this.cfg.margin.left - this.cfg.margin.right,
this.cfg.height = parseInt(this.selection.node().offsetHeight)- this.cfg.margin.top - this.cfg.margin.bottom;
this.parseTime = d3.timeParse("%Y");
this.data.forEach(function(d) {
d.date = self.parseTime(d[self.cfg.label]);
});
this.xScale = d3.scaleLinear().rangeRound([0, self.cfg.width]);
this.cScale = d3.scaleSequential(this.cfg.colorScale);
this.initGraph();
}
initGraph() {
var self = this;
this.cScale.domain(d3.extent(this.data, function(d){ return +d[self.cfg.key]}).reverse())
if(self.cfg.label) this.xScale.domain(d3.extent(this.data, function(d){ return d.date }))
this.svg = this.selection.append('svg')
.attr("class", "chart barchar stackedbarchart")
.attr("viewBox", "0 0 "+(this.cfg.width + this.cfg.margin.left + this.cfg.margin.right)+" "+(this.cfg.height + this.cfg.margin.top + this.cfg.margin.bottom))
.attr("width", this.cfg.width + this.cfg.margin.left + this.cfg.margin.right)
.attr("height", this.cfg.height + this.cfg.margin.top + this.cfg.margin.bottom);
this.g = this.svg.append("g")
.attr("transform", "translate(" + (self.cfg.margin.left) + "," + (self.cfg.margin.top) + ")");
if(self.cfg.label){
this.g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + this.cfg.height + ")")
.call(d3.axisBottom(self.xScale)
.ticks(10)
.tickFormat(d3.timeFormat("%Y")));
}
this.itemg = this.g.selectAll('.itemgroup')
.data(this.data)
.enter().append('g')
.attr('class', 'itemgroup')
.attr('transform', function(d, i){
return 'translate('+ i*(self.cfg.width/self.data.length) +',0)';
})
this.bars = this.itemg.append('rect')
.attr('height', self.cfg.height)
.attr('width', (self.cfg.width/self.data.length) +1)
.attr('fill', function(d) {
return self.cScale(+d[self.cfg.key]);
})
// Title
if(self.cfg.title){
this.svg.append('text')
.attr('class', 'title label')
.attr('text-anchor', 'middle')
.attr('transform', 'translate('+ (self.cfg.width/2) +',20)')
.text(self.cfg.title)
}
// Source
if(self.cfg.source){
this.svg.append('text')
.attr('class', 'source label')
.attr('transform', 'translate('+ (self.cfg.margin.left) +','+(self.cfg.height + self.cfg.margin.top + self.cfg.margin.bottom - 5)+')')
.text(self.cfg.source)
}
// Label
if(self.cfg.label){
this.itemg.append('text')
.attr('class', 'label')
.attr('text-anchor', 'start')
.attr('transform', 'rotate(270)')
.attr('x', -this.cfg.height + this.cfg.label_x)
.attr('y', this.cfg.label_y)
.text(function(d){
return d[self.cfg.key] +' '+self.cfg.units+ ' - ' + d[self.cfg.label];
})
}
//Legend
if(self.cfg.legendRanges instanceof Array === true){
this.legend = this.g.append('g')
.attr('class', 'legend')
.attr('transform', 'translate('+ (self.cfg.width + 10) +',30)');
[16,15,14,13].forEach(function(d, i){
var tm = self.legend.append('g')
.attr('transform', 'translate(0,'+(i*((self.cfg.width/self.data.length)+6))+')')
tm.append('rect')
.attr('width', self.cfg.width/self.data.length)
.attr('height', self.cfg.width/self.data.length)
.attr('fill', self.cScale(d))
tm.append('text')
.attr('transform', 'translate('+((self.cfg.width/self.data.length)+4)+','+((self.cfg.width/self.data.length)-4)+')')
.attr('class', 'label')
.text(d + ' ' + self.cfg.units)
})
}
}
}
<html>
<head>
<meta charset="utf-8">
</head>
<style>
.itemgroup:hover rect {
opacity: 0;
}
.label {
font-family: sans-serif;
font-size: 12px;
cursor: default;
}
.source {
fill: #7a7a7a;
font-size: 10px;
}
.title {
font-weight: 700;
}
.itemgroup .label {
opacity: 0;
}
.itemgroup:hover .label {
opacity: 1;
}
.chart .domain,
.chart .tick line {
display: none;
}
</style>
<body>
<div id="yearly" style="width: 960px; height: 210px;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script src="d3.stripelines.js"></script>
<script>
var scsv = d3.dsvFormat(";");
d3.text('temps.scsv', function(data) {
var grafico = new StripeLines(d3.select('#yearly'), scsv.parse(data), {
'key': 'yearly',
'label': 'year',
'legendRanges': [16,15,14,13],
'title': 'Evolución de la temperatura media anual en España',
'source': 'Fuente: AEMET'
})
})
</script>
</body>
</html>
year;jan;feb;mar;apr;may;jun;jul;aug;sep;oct;nov;dec;yearly;spring;summer;autumn;winter
1965;6.3;5.8;10.7;12.9;17.9;21.4;22.2;22.9;17.8;15.8;10.3;8.3;14.3;13.8;22.1;14.6;9.2
1966;9.2;10.3;9.7;13.1;16.8;19.6;22.3;23;21.5;14.4;8.1;7.3;14.6;13.2;21.6;14.6;7.2
1967;6.2;8.2;11.7;11.7;14.9;18.8;24.1;22.9;19.7;17;10.7;5.8;14.3;12.8;21.9;15.8;7
1968;7.1;8.3;9.5;12.4;15.3;20.2;23.3;22.4;19.8;17.9;11.1;7.9;14.6;12.4;21.9;16.2;7.3
1969;7.8;6.2;9.8;12.2;15.4;18.5;23.7;22.8;17.5;15.8;9.5;6.4;13.8;12.5;21.7;14.3;7.6
1970;8.4;8;8.4;12.2;15.8;19.9;23.4;22.5;21.7;14.5;12.4;4.6;14.3;12.1;22;16.2;6.2
1971;5.7;8.2;7.3;12.2;14.2;18;22.8;22.3;20.3;17.1;8.3;7.4;13.6;11.2;21;15.2;6.9
1972;5.5;7.8;9.6;11.8;14.3;18.2;22.2;21.3;17.1;14;11.1;7.1;13.3;11.9;20.6;14.1;6.8
1973;6.3;7;8.8;11.7;16.1;19.5;22.3;24;20;14.5;10.6;6.3;13.9;12.2;21.9;15;7.3
1974;8.1;7.5;9.4;10.9;16.1;19.5;22.9;22.5;18.9;12.3;10.6;7.5;13.9;12.2;21.6;13.9;8.1
1975;7.9;8.9;8.3;11.7;14;19.1;23.6;23.1;18.6;15.7;10;5.9;13.9;11.4;21.9;14.8;6.8
1976;6;8.4;10;11;16.5;21.5;23.1;22.5;18.4;13.5;8.5;8.5;14;12.5;22.4;13.5;8.4
1977;7.1;9.6;11.1;12.9;14.4;17.5;20.3;20.4;20.3;15.9;10.2;9.6;14.1;12.8;19.4;15.5;8.4
1978;6.3;9.3;10.6;11.2;14.2;17.6;22.5;23;21.4;15.2;10.1;9.4;14.2;12;21;15.6;8.8
1979;8.2;8.7;9.5;11.3;15.9;20.5;23.2;22.8;20;14.8;9.9;8;14.4;12.2;22.2;14.9;8.1
1980;7;9.2;10.2;11.9;14.5;19.3;21.8;24.1;21.9;15.2;9.7;6;14.2;12.2;21.7;15.6;6.5
1981;6.6;7;12.4;12.1;15.2;21.3;22.5;23.1;20.6;16.3;12.4;9.4;14.9;13.2;22.3;16.4;9.1
1982;9;8.8;10.6;12.9;16.5;21.3;23.6;23;20.3;14.6;10.4;7.4;14.9;13.4;22.6;15.1;6.8
1983;6.7;6.5;11.5;12.1;14.5;21.1;23.6;22.2;22.1;16.8;13.2;8;14.9;12.7;22.3;17.4;7.4
1984;7.2;7;8.2;14.3;12.2;19.1;23.9;22.2;19.6;14.9;11.3;7.9;14;11.6;21.7;15.3;7.6
1985;4.9;10;9.1;13.4;14.5;20.5;24.2;23.2;22.6;17.2;9.9;7.7;14.8;12.4;22.6;16.6;7.4
1986;7;7.3;10.2;9.5;17.6;20.4;23.8;22.8;20.9;16.5;10.6;7.3;14.5;12.4;22.3;16;7.2
1987;6.1;8.1;11.4;14;16;20.4;23;24.3;22.9;14.9;10.5;9.3;15.1;13.8;22.6;16.1;8.8
1988;8.9;8.1;11;12.9;15.9;18.6;22.8;23.9;20.7;16.4;11.5;6.8;14.8;13.3;21.8;16.2;7.4
1989;6.4;8.9;12.2;11.2;17.6;21.2;25.3;24.7;19.9;16.9;12.6;10.9;15.7;13.7;23.7;16.5;9.8
1990;7.1;11.5;11.8;11.7;17.6;21.1;24.8;24.6;22.2;15.8;10.2;6.1;15.4;13.7;23.5;16.1;6.6
1991;6.5;7;11.2;11.6;15.2;21;24.2;25.4;21.8;13.5;10.1;7.9;14.6;12.7;23.5;15.1;6.9
1992;5;7.8;10.8;13.5;18;17.3;23.9;24.1;20.1;13.6;11.8;8.3;14.5;14.1;21.8;15.2;7.5
1993;6.4;7.7;10.7;12.3;15.6;20.5;23.3;23.7;18.4;13;9.6;8.3;14.1;12.9;22.5;13.7;8
1994;7.3;8.5;12.8;12.1;16.9;21.2;25.5;25;18.8;16;12.4;8.6;15.4;13.9;23.9;15.7;8.9
1995;8.1;10.1;11.3;13.8;18.2;20.9;24.7;24.2;18.6;18;12.8;9.4;15.8;14.4;23.3;16.4;8.7
1996;9.3;7.3;10.6;13.7;16;21.7;23.7;22.6;18.5;15.3;11;8.6;14.9;13.4;22.7;14.9;9
1997;7.8;10.7;13.5;15.2;17;19.4;22.3;23.7;21.5;17.8;11.6;8.6;15.8;15.2;21.8;17;9.1
1998;8.6;10.2;12.7;12;16.2;21.3;24.2;24.7;20.7;15;10.7;6.8;15.3;13.6;23.4;15.5;7.2
1999;7.1;7.8;11.1;13.8;18.1;21.2;24.6;24.3;20.5;16;8.9;7.7;15.1;14.3;23.4;15.1;7.9
2000;5.3;10.7;11.7;12;17.8;22;23.3;23.8;21;15.3;10.2;9.5;15.2;13.9;23;15.5;9.1
2001;8.7;9.1;13.3;13.6;16.9;22.4;23.2;24.6;20.2;17.5;9.2;5.5;15.4;14.6;23.4;15.6;7.8
2002;8.3;9.7;11.9;13.4;15.8;21.7;23.3;22.6;19.9;16.3;11.8;10;15.4;13.7;22.6;16;8.2
2003;7.1;7.5;12.3;13.6;17.8;24;24.6;26.2;21.2;15.1;11.5;8.1;15.7;14.5;24.9;15.9;8.4
2004;8.8;8.3;9.9;12.3;15.5;23.1;24.1;24;21.7;16.8;9.8;7.8;15.2;12.6;23.7;16.1;6.5
2005;5.8;5.8;10.9;13.9;18.3;23.5;24.8;24.1;20.2;16.6;9.9;6.8;15.1;14.4;24.2;15.6;6.7
2006;6.1;7.3;11.9;14.7;18.8;22.3;26;23.5;21.7;18;13.2;7.3;15.9;15.1;23.9;17.6;8.3
2007;7.4;10.3;10.6;13.6;17.1;20.6;23.7;23.3;20.7;15.9;10;7.5;15.1;13.8;22.5;15.5;8.9
2008;8.7;10.4;11;13.9;16.2;20.9;23.6;24.1;19.9;15.3;9.1;7;15;13.7;22.9;14.8;7.4
2009;6.6;8.5;11.7;12.5;18.3;22.6;24.6;25.3;20.9;17.9;12.6;8;15.8;14.2;24.2;17.1;7.6
2010;6.9;7.9;10.1;14.4;16.1;20.6;25.5;24.9;20.9;15.2;9.9;7.6;15;13.5;23.7;15.3;8.1
2011;7.5;9.1;10.8;16.3;18.8;21.5;23.3;24.7;22;17.5;12.2;8.3;16;15.3;23.2;17.3;7.2
2012;7.3;6;11.6;12.1;18.5;22.7;23.9;25.3;20.9;16.1;11;8.5;15.3;14.1;24;16;8.1
2013;8.1;7.6;10.6;12.9;14.7;19.8;25;24.5;21.5;17.5;10.2;7.3;15;12.7;23.1;16.4;8.3
2014;9;8.8;11.4;15.7;17.3;21.4;23.4;23.9;21.9;18.7;12.5;7.8;16;14.8;22.9;17.7;7.4
2015;6.9;7.4;11.6;14.7;19.1;22.6;26.6;24.5;19.8;16.4;12.4;10;16;15.1;24.5;16.2;9.6
2016;9.5;9.3;10;13;16.4;21.9;25.5;25.2;22.1;17.4;10.8;8.6;15.8;13.1;24.2;16.8;8.5
2017;6.7;10.2;12.2;14.9;19;24.1;24.9;24.9;20.6;18.5;11;7.6;16.2;15.4;24.7;16.7;7.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.