var parseDate = d3.time.format("%d-%b-%y").parse; var data=[ {"step": "responseStart", "from": "1-Jan-17", "to": "15-Jan-17", "progress":100}, {"step": "Task 1", "from": "13-Jan-17", "to": "1-Feb-17", "progress":60}, {"step": "Task 1", "from": "1-Feb-17", "to": "15-Feb-17", "progress":70}, {"step": "Task 1", "from": "10-Feb-17", "to": "1-Mar-17", "progress":10}, {"step": "Task 1", "from": "1-Mar-17", "to": "12-Mar-17", "progress":90} ] var types_of_statuses = ["Completed","Remaining"]; var statuses_color = ["#2ecc71","#e74c3c"]; data.forEach(function(d) { d.from = parseDate(d.from); d.to = parseDate(d.to); }); var margin = {top: 50, right: 50, bottom: 50, left: 100}, width = 900 - margin.left - margin.right, height = 200 - margin.top - margin.bottom; var y = d3.scale.ordinal() .rangeRoundBands([0, height], .2); var x = d3.time.scale().range([0, width]); y.domain(data.map(function(d) { return 'd.category'; })); x.domain([d3.min(data,function(d){return d.from;}), d3.max(data,function(d){return d.to;})]); var xAxis = d3.svg.axis().tickValues([]); // .scale(x) // .orient("bottom") // .ticks(15) // .tickFormat(d3.time.format("%d%b")); var yAxis = d3.svg.axis().tickValues([]); // .scale(y) // .orient("left"); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // svg.append("g") // .attr("class", "x axis") // .attr("transform", "translate(0," + height + ")") // .call(xAxis) // .append("text") // .attr("x", width-margin.right) // .attr("dx", ".71em") // .attr("dy", "-0.2em") // .text("Date"); // svg.append("g") // .attr("class", "y axis") // .call(yAxis); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("y", function(d) { return y('d.category'); }) .attr("height", y.rangeBand()) .attr("x", function(d) { return x(d.from); }) .attr("width", function(d) { return x(d.to) - x(d.from)}); svg.selectAll(".pending") .data(data) .enter().append("rect") .attr("class", "pending") .attr("y", function(d) { return y('d.category'); }) .attr("height", y.rangeBand()) .attr("x", function(d) { return x(d.from) + (x(d.to) - x(d.from))*d.progress/100 }) .attr("width", function(d) { return (x(d.to) - x(d.from))*(1-(d.progress/100))}); // add legend var legend = svg.append("g") .attr("class", "legend") legend.selectAll(".swatch") .data(types_of_statuses) .enter() .append("rect") .attr("x", width-margin.left-margin.right-25) .attr("y", function(d, i){ return -margin.top/2 + i*20;}) .attr("width", 10) .attr("height", 10) .style("fill", function(d,i) { return statuses_color[i]; }) legend.selectAll(".labels") .data(types_of_statuses) .enter() .append("text") .attr("x", width-margin.left-margin.right) .attr("y", function(d, i){ return -margin.top/2 + i*20 + 10;}) .text(function(d,i){return types_of_statuses[i]}); var tooltip = d3.select("body") .append('div') .attr('class', 'tooltip'); tooltip.append('div').attr('class', 'category'); tooltip.append('div').attr('class', 'tempRange'); tooltip.append('div').attr('class', 'progress'); svg.selectAll(".bar,.pending") .on('mouseover', function(d) { tooltip.select('.category').html("" + d.step + ""); tooltip.select('.tempRange').html(d.from.toDateString() + " to " + d.to.toDateString()); tooltip.select('.progress').html(d.progress + "% completed"); tooltip.style('display', 'block'); tooltip.style('opacity',2); }) .on('mousemove', function(d) { tooltip.style('top', (d3.event.layerY + 10) + 'px') .style('left', (d3.event.layerX - 25) + 'px'); }) .on('mouseout', function() { tooltip.style('display', 'none'); tooltip.style('opacity',0); });