Date slider with Legend
HTML
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="data">
site,id,event,status,date
A,1,1,Complete,2017-05-02
A,1,2,Complete,2017-06-06
A,1,3,Unverified,2018-03-21
A,1,4,Incomplete,2019-02-24
A,1,5,Complete,2019-06-18
A,2,1,Complete,2019-01-23
A,2,2,Unverified,2019-03-10
A,2,3,Complete,2019-05-30
A,3,1,Incomplete,2017-07-07
A,3,2,Complete,2018-03-11
A,3,3,Complete,2019-02-21
A,3,4,Unverified,2019-04-05
A,4,1,Unverified,2019-05-13
A,4,2,Complete,2019-08-09
A,5,1,Complete,2017-11-23
A,5,2,Complete,2018-05-17
A,5,3,Complete,2018-05-26
A,5,4,Complete,2019-02-05
B,1,1,Complete,2017-04-16
B,1,2,Complete,2017-11-26
B,1,3,Unverified,2018-03-22
B,1,4,Complete,2018-07-15
B,1,5,Complete,2019-11-05
B,2,1,Complete,2018-09-11
B,2,2,Complete,2018-10-16
B,2,3,Complete,2019-03-08
B,2,3,Unverified,2019-06-22
B,2,4,Complete,2019-10-19
B,3,1,Complete,2017-10-16
B,3,2,Incomplete,2018-09-06
B,3,3,Complete,2019-07-27
B,3,4,Complete,2019-10-02
B,4,1,Unverified,2017-04-21
B,4,2,Complete,2017-11-21
B,4,3,Complete,2018-03-12
B,4,4,Complete,2018-04-04
B,5,1,Unverified,2017-09-23
B,5,2,Complete,2018-01-19
B,5,3,Complete,2018-02-11
B,5,4,Complete,2019-06-26
C,1,1,Complete,2017-04-12
C,1,2,Complete,2018-08-20
C,1,3,Complete,2018-10-02
C,1,4,Unverified,2018-11-16
C,1,5,Complete,2019-06-16
C,2,1,Complete,2018-07-22
C,2,2,Complete,2019-06-13
C,2,3,Complete,2019-11-10
C,2,4,Incomplete,2019-11-12
C,3,1,Complete,2017-03-20
C,3,2,Complete,2018-01-12
C,3,3,Complete,2018-03-08
C,3,4,Complete,2019-09-24
C,4,1,Complete,2017-03-09
C,4,2,Complete,2017-07-13
C,4,3,Complete,2019-10-30
C,5,1,Complete,2018-07-29
C,5,2,Complete,2018-09-20
C,5,3,Unverified,2018-12-25
C,5,4,Complete,2019-05-26
C,5,5,Incomplete,2019-11-17
</pre>
<div id="container" name="container"></div>
<div id="slider" name="slider"></div>
CSS
body,html{
margin: 0;
padding: 0;
font-family: "Arial", sans-serif;
font-size: 0.95em;
text-align: center;
background-color: white;
}
.legend{
stroke: black;
font-family: "Arial", sans-serif;
stroke-width: 2px;
fill: none;
}
pre {
display:none;
}
div{
margin-top:20px;
}
.ticks {
font-size: 10px;
}
.track,
.track-inset,
.track-overlay {
stroke-linecap: round;
}
.track {
stroke: #000;
stroke-opacity: 0.3;
stroke-width: 10px;
}
.track-inset {
stroke: #ddd;
stroke-width: 8px;
}
.track-overlay {
pointer-events: stroke;
stroke-width: 50px;
stroke: transparent;
cursor: crosshair;
}
.handle {
fill: #fff;
stroke: #000;
stroke-opacity: 0.5;
stroke-width: 1.25px;
}
JavaScript
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
var margin = {top: 20, right: 20, bottom: 20, left: 20};
var width = 500 - margin.left - margin.right;
var height = 150
var graphWidth = 200
var x = d3.scaleLinear().range([0, graphWidth]).domain([0.5,5.5]);
var y = d3.scaleLinear().range([height - 40, 0]).domain([0,6]);
var xAxis = d3.axisBottom(x).ticks(5);
var yAxis = d3.axisLeft(y).ticks(5);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var mydata = d3.csvParse(d3.select("pre#data").text());
var parseTime = d3.timeParse("%Y-%m-%d");
var formatDate = d3.timeFormat("%Y-%m-%d");
var startDate = parseTime("2017-01-01");
var endDate = parseTime("2019-12-30");
var xSlider = d3.scaleTime()
.domain([startDate, endDate])
.range([0, graphWidth])
.clamp(true);
mydata.forEach(function(d){
d.id = +d.id;
d.event = +d.event;
d.date = parseTime(d.date);
});
var panelData = d3.nest()
.key(function(d) { return d.site; })
.entries(mydata);
var legendData = d3.nest()
.key(function(d) { return d.status; })
.entries(mydata)
legendData = d3.values(legendData).map(function(d) {
return d.key; })
console.log(legendData);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
var createGraph = function(){
var mytitle = d3.select("#container").append("text")
.text("Participant Followup over Time")
.attr("transform", "translate(0," + 50 + ")");
var legendBox = d3.select("#container").append("svg")
.attr("transform", "translate("+ 20 + "," + 250 + ")")
.attr("class", "legend")
.attr("width", 130)
.attr("height", legendData.length*35);
legendBox.append("rect")
.attr("transform", "translate("+ 5 + "," + 5 + ")")
.attr("width", 120)
.attr("height",legendData.length*30);
...