Built with blockbuilder.org
forked from fall16mis's block: SessionTimeLog
license: mit |
Built with blockbuilder.org
forked from fall16mis's block: SessionTimeLog
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
.tooltip { | |
opacity: 0; | |
background-color: #ffe047; | |
position: absolute; | |
} | |
.grid line { | |
stroke: lightgrey; | |
shape-rendering: crispEdges; | |
} | |
.ticks { | |
font-size: 11px; | |
} | |
.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; | |
} | |
.bar:hover{ | |
fill:#0f9fff; | |
} | |
.legend{ | |
color:#005ebc; | |
z-index:0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="slider"></div> | |
<script> | |
var json_data = "id,date,start_time,end_time\n\ | |
54042,2017/09/06,5.50,7.1\n\ | |
54042,2017/09/06,7.55,9.19\n\ | |
54042,2017/09/16,11.12,12.28\n\ | |
54042,2017/09/23,13.56,15.03\n\ | |
54042,2017/09/07,16.29,17.33\n\ | |
54042,2017/09/06,19.56,20.53\n\ | |
54042,2017/09/20,21.3,22.14\n\ | |
98765,2017/09/06,5.1,6.51\n\ | |
98765,2017/09/06,11.4,11.53\n\ | |
98765,2017/09/06,12.2,12.42\n\ | |
98765,2017/09/06,12.55,14.2\n\ | |
98765,2017/09/16,21.42,21.59\n\ | |
98765,2017/09/16,22.01,23.13\n\ | |
98765,2017/09/16,23.16,23.51\n\ | |
98765,2017/09/23,13.41,14.03\n\ | |
65299,2017/09/06,7.23,8.21\n\ | |
65299,2017/09/06,9.37,10.23\n\ | |
65299,2017/09/06,11.46,13.29\n\ | |
65299,2017/09/06,18.07,19.57\n\ | |
65299,2017/09/17,14.41,16.22\n\ | |
65299,2017/09/17,21.39,23.39\n\ | |
79408,2017/09/06,9.37,10.17\n\ | |
79408,2017/09/06,11.03,12.08\n\ | |
79408,2017/09/06,13.14,15.53\n\ | |
79408,2017/09/06,16.05,17.48\n\ | |
79408,2017/09/06,19.47,20.23\n\ | |
38338,2017/09/06,8.22,9.28\n\ | |
38338,2017/09/06,11.34,12.17\n\ | |
38338,2017/09/07,12.43,13.35\n\ | |
38338,2017/09/07,14.12,15.48\n\ | |
38338,2017/09/07,16.09,17.23\n\ | |
38338,2017/09/07,18.31,19.19\n\ | |
38338,2017/09/07,21.49,23.26\n\ | |
81757,2017/09/06,6.31,7.41\n\ | |
81757,2017/09/06,8.18,9.39\n\ | |
81757,2017/09/06,10.18,11.23\n\ | |
81757,2017/09/06,13.02,14.04\n\ | |
81757,2017/09/07,15.22,17.23\n\ | |
81757,2017/09/07,20.32,22.01\n\ | |
68077,2017/09/06,11.1,12.45\n\ | |
68077,2017/09/06,15.23,16.54\n\ | |
68077,2017/09/06,17.31,19.05\n\ | |
68077,2017/09/06,20.39,21.3\n\ | |
68077,2017/09/06,21.41,22.37\n\ | |
58381,2017/09/06,16.51,17.55\n\ | |
58381,2017/09/06,19.34,20.55\n\ | |
58381,2017/09/06,21.33,22.51\n\ | |
58381,2017/09/07,14.46,16.15\n\ | |
37500,2017/09/06,8.2,10.18\n\ | |
37500,2017/09/06,11.37,13.34\n\ | |
37500,2017/09/06,19.22,20.16\n\ | |
37500,2017/09/06,21.55,22.09\n\ | |
37500,2017/09/16,14.16,16.26\n\ | |
37500,2017/09/16,16.58,17.48\n\ | |
39146,2017/09/06,19.47,20.21\n\ | |
39146,2017/09/06,20.35,21.29\n\ | |
39146,2017/09/06,22.01,23.25\n\ | |
39146,2017/09/16,8.03,9.56\n\ | |
39146,2017/09/16,10.23,12.52\n\ | |
39146,2017/09/16,13.25,14.28"; | |
window.data = d3.csvParse(json_data, function(d){ return { | |
id:d.id, | |
date:d.date, | |
start_time:+d.start_time, | |
end_time:+d.end_time}; }); | |
window.minDate = d3.min(window.data,function(d){ return d.date; }); | |
window.maxDate = d3.max(window.data,function(d){ return d.date; }); | |
window.names = window.data.map(function(d){ | |
return d.id; }); | |
var parseDate = d3.timeParse("%Y/%m/%d"); | |
var displayDate = d3.timeFormat("%m/%d"); | |
var forChartDate = d3.timeFormat("%Y/%m/%d"); | |
var height = 500; | |
var width = 800; | |
var margin = {left: 50, right: 20, bottom: 0, top: 70}; | |
var tooltip = d3.select("body").append("div").attr("class", "tooltip") | |
var svg = d3.select("body").append("svg").attr("height","1000px").attr("width","100%"); | |
var chartGroup = svg.append("g").attr("transform","translate("+margin.left+","+(margin.top+10)+")"); | |
var legend = svg.append("g").attr("transform","translate("+margin.left+","+(margin.top+10)+")"); | |
var chartDate = window.minDate; | |
var displaySlider = function(data){ | |
window.x = d3.scaleLinear() | |
.domain([0, 24]) | |
.range([0, width]); | |
window.y = d3.scaleBand() | |
.domain(window.names) | |
.rangeRound([height, 0]) | |
.paddingInner(0.3); | |
function make_y_gridlines() { | |
return d3.axisLeft(y) | |
}; | |
function make_x_gridlines() { | |
return d3.axisBottom(x) | |
}; | |
chartGroup.append("g") | |
.attr("class","axis y") | |
.call(d3.axisLeft(y)) | |
chartGroup.append("g") | |
.attr("class","axis x") | |
.call(d3.axisBottom(x)) | |
.attr("transform","translate(0,"+height+")") | |
.call(d3.axisBottom(x) | |
.ticks(24)); | |
chartGroup.append("g") | |
.attr("class", "grid") | |
.call(make_y_gridlines() | |
.tickSize(-width) | |
.tickFormat("") | |
); | |
chartGroup.append("g") | |
.attr("class", "grid") | |
.call(make_x_gridlines() | |
.tickSize(height) | |
.tickFormat("") | |
) | |
var newData = data.filter(function(d){ | |
return d.date==chartDate; | |
}) | |
displayBar(newData); | |
var x1 = d3.scaleTime() | |
.range([0, width]) | |
.domain([parseDate(minDate), parseDate(maxDate)]) | |
.clamp(true); | |
var slider = svg.append("g") | |
.attr("class", "slider") | |
.attr("transform", "translate(" + margin.left + ",30)"); | |
slider.append("line") | |
.attr("class", "track") | |
.attr("x1", x1.range()[0]) | |
.attr("x2", x1.range()[1]) | |
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); }) | |
.attr("class", "track-inset") | |
.select(function() { return this.parentNode.appendChild(this.cloneNode(true)); }) | |
.attr("class", "track-overlay") | |
.call(d3.drag() | |
.on("start.interrupt", function() { slider.interrupt(); }) | |
.on("drag end", function() { sliderFunc(x1.invert(d3.event.x)); })); | |
slider.insert("g", ".track-overlay") | |
.attr("class", "ticks") | |
.attr("transform", "translate(0," + 10 + ")") | |
.selectAll("text") | |
.data(x1.ticks(15)) | |
.enter() | |
.append("text") | |
.attr("x", x1) | |
.attr("y", 10) | |
.attr("text-anchor", "middle") | |
.text(function(d) { return displayDate(d); }); | |
var label = slider.append("text") | |
.attr("class", "label") | |
.attr("text-anchor", "middle") | |
.text(minDate) | |
.attr("transform", "translate(0," + (-10) + ")"); | |
var handle = slider.insert("circle", ".track-overlay") | |
.attr("class", "handle") | |
.attr("r", 7); | |
function sliderFunc(h) { | |
handle.attr("cx", x1(h)); | |
label.attr("x", x1(h)) | |
.text(displayDate(h)); | |
chartDate = forChartDate(h); | |
console.log(chartDate); | |
newData = data.filter(function(d){ | |
return d.date==chartDate; | |
}) | |
//displayText(newData); | |
displayBar(newData); | |
} | |
}; | |
var displayBar = function(data){ | |
var bars = chartGroup.selectAll(".bar") | |
.data(data, function(d){ | |
return d.id; | |
}); | |
bars.exit().remove(); | |
bar_enter = bars.enter().append("rect") | |
bar_enter.attr("class", "bar") | |
.attr("x", function(d) { | |
console.log(d.start_time); | |
return window.x(d.start_time); }) | |
.attr("y", function(d) { return window.y(d.id); }) | |
.attr("height", window.y.bandwidth()) | |
.attr("fill", "green") | |
.transition() | |
.duration(600) | |
.attr("width", function(d) { return window.x(d.end_time-d.start_time); }); | |
bar_enter.on('mousemove', function(d,i){ | |
tooltip.style("opacity","1") | |
.style("left",(d3.event.pageX+10)+"px") | |
.style("top",d3.event.pageY+"px"); | |
tooltip.html(" Start Time:"+d.start_time+" End Time:"+d.end_time); | |
}) | |
bar_enter.on('mouseout', function(){ | |
tooltip.style("opacity","0") | |
}); | |
}; | |
// var displayText = function(data){ | |
// legend.selectAll("text") | |
// .transition() | |
// .duration(50) | |
// .remove() | |
// data.forEach(function(d){ | |
// dataById = d3.nest() | |
// .key(function(d){ return d.id; }) | |
// .rollup((function(d){ | |
// return { | |
// highDate: d3.max(d,function(d){ | |
// return d.date; }), | |
// highPoints: d3.max(d,function(d){ | |
// return d.points; }), | |
// highPercent: d3.max(d, function(d){ | |
// return d.percent; | |
// })}; | |
// })) | |
// .entries(data) | |
// }); | |
// dataById.forEach(function(d){ | |
// console.log(d.value.highPoints) | |
// legend.append("text") | |
// .attr("x", window.x(d.key)+3.52) | |
// .attr("y", window.y(d.value.highPoints)-5) | |
// .style("fill", "steelblue") | |
// .attr("class", "legend") | |
// .text(d.value.highPercent); | |
// }) | |
// } | |
displaySlider(window.data); | |
</script> | |
</body> |