Skip to content

Instantly share code, notes, and snippets.

@mforando
Last active November 22, 2019 22:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mforando/308be9607e521431724f8920d3b44f3a to your computer and use it in GitHub Desktop.
Save mforando/308be9607e521431724f8920d3b44f3a to your computer and use it in GitHub Desktop.
Lean Time Ladder to Percent Value Added
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:50px;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
var width = 600;
var height = 200;
var pad = 50;
var steps = [{"type":"Lead Time", "time": 10, "label": "Step 1"},
{"type":"Work Time", "time": 6, "label": "Step 1"},
{"type":"Lead Time", "time": 20, "label": "Step 2"},
{"type":"Work Time", "time": 3, "label": "Step 2"},
{"type":"Lead Time", "time": 4, "label": "Step 3"},
{"type":"Work Time", "time": 1, "label": "Step 3"},
{"type":"Lead Time", "time": 10, "label": "Step 4"},
{"type":"Work Time", "time": 1, "label": "Step 4"},
{"type":"Lead Time", "time": 5, "label": "Step 5"},
{"type":"Work Time", "time": 20, "label": "Step 5"},
{"type":"Lead Time", "time": 2, "label": "Step 6"},
{"type":"Work Time", "time": 10, "label": "Step 6"}];
//calculate cumulative time.
var cumulativeTime = 0;
var cumulativeValueTime = 0;
steps.forEach(function(d, i){
d.origSort = i;
d.cumulativeTime = cumulativeTime;
cumulativeTime = cumulativeTime + d.time;
})
steps.sort(function(a,b){return d3.descending(a.type, b.type)})
var cumulativeTime = 0;
var cumulativeValueTime = 0;
steps.forEach(function(d, i){
d.sorted_cumulativeTime = cumulativeTime;
cumulativeTime = cumulativeTime + d.time;
})
steps.sort(function(a,b){return d3.ascending(a.origSort, b.origSort)})
console.log(steps);
var timeScale = d3.scaleLinear()
.range([pad, width-pad])
.domain([0, steps[steps.length-1].cumulativeTime + steps[steps.length-1].time])
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style('outline','1px solid gray');
var xScale = d3.scaleBand()
.range([pad,width-pad])
.domain(steps.map(function(d,i){return i}));
var rects = d3.select('svg').selectAll('rect')
.data(steps);
rects.enter()
.append('rect')
.attr('stroke','black ')
.attr('fill','black')
.attr('height',10)
.attr('width', function(d,i){return xScale.bandwidth()})
.attr('x', function(d,i){return xScale(i)})
.attr('y', function(d){
if(d.type=="Lead Time"){return height/2 - 10}
else{return height/2 + 10}
})
.style('fill',function(d){
if(d.type == "Lead Time"){return "orange"}
else{return "rgb(0,60,121)"}
})
var labels = d3.select('svg').selectAll('text')
.data(steps);
labels.enter()
.append('text')
.attr('stroke','none')
.attr('fill','black')
.style('dominant-baseline','ideographic')
.style('text-anchor','middle')
.style('font-size','12px')
.text(function(d,i){return d.time})
.attr('x', function(d,i){return xScale(i) + xScale.bandwidth()/2})
.attr('y', function(d){
if(d.type=="Lead Time"){return height/2 - 20}
else{return height/2 + 35}
})
var polyline = d3.select('svg')
.append('polyline')
.attr('points',function(d){
var coords = []
steps.forEach((d, i)=>{
var y;
if(d.type=="Lead Time"){y = height/2 - 10}
else{y = height/2 + 12};
coords.push([xScale(i), y]);
coords.push([xScale(i + 1), y])
})
return coords;
})
.style('fill','none')
.style('stroke','black')
;
setTimeout(function(){
d3.select('svg')
.select('polyline')
.transition()
.duration(1500)
.ease(d3.easeCubic)
.attr('points',function(d){
var coords = []
steps.forEach((d, i)=>{
var y;
if(d.type=="Lead Time"){y = height/2 - 10}
else{y = height/2 + 12};
coords.push([timeScale(d.cumulativeTime), y]);
coords.push([timeScale(d.cumulativeTime + d.time), y])
})
return coords;
})
d3.selectAll('svg').selectAll('rect')
.transition()
.duration(1500)
.ease(d3.easeCubic)
.attr('x',function(d,i){return timeScale(d.cumulativeTime);})
// .attr('y',height/2 - 50)
.attr('width', function(d,i){return timeScale(d.cumulativeTime + d.time) - timeScale(d.cumulativeTime);})
// .attr('height', 100)
.style('fill',function(d){
if(d.type == "Lead Time"){return "orange"}
else{return "rgb(0,60,121)"}
})
d3.selectAll('svg').selectAll('text')
.transition()
.duration(1500)
.ease(d3.easeCubic)
.attr('x',function(d,i){return timeScale(d.cumulativeTime + d.time/2);})
/* .attr('y',function(d){
if(d.type == "Lead Time"){
return height/2-55
}
else {return height/2+70}
})
*/
setTimeout(function(){
d3.select('svg')
.select('polyline')
.transition()
.style('opacity',0)
.on('end',function(){d3.select(this).remove();})
d3.selectAll('svg').selectAll('rect')
.transition()
.duration(2000)
.ease(d3.easeCubic)
.delay(function(d,i){return i*50})
.attr('x',function(d,i){return timeScale(d.sorted_cumulativeTime);})
.attr('y',height/2)
.attr('width', function(d,i){return timeScale(d.sorted_cumulativeTime + d.time) - timeScale(d.sorted_cumulativeTime);})
.attr('height', 10)
d3.selectAll('svg').selectAll('text')
.transition()
.duration(1500)
.ease(d3.easeCubic)
.delay(function(d,i){return i*50})
.attr('x',function(d,i){return timeScale(d.sorted_cumulativeTime + d.time/2);})
/* .attr('y',function(d){
if(d.type == "Lead Time"){
return height/2-55
}
else {return height/2+70}
})
*/
}, 3000)
}, 1000)
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment