Skip to content

Instantly share code, notes, and snippets.

@jgeryk
Last active January 13, 2017 18:29
Show Gist options
  • Select an option

  • Save jgeryk/5a50c30125a142650c4fa73950cc9701 to your computer and use it in GitHub Desktop.

Select an option

Save jgeryk/5a50c30125a142650c4fa73950cc9701 to your computer and use it in GitHub Desktop.
Date/Hours Prototype Spline w/ Balancing
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Volume Control</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.4.0/d3.min.js" charset="utf-8"></script>
<style>
body {
font: 13px sans-serif;
position: relative;
width: 960px;
height: 500px;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
</style>
</head>
<body>
<script>
var budgetedHours = 50;
var now = new Date
var future = new Date
future = future.setDate(future.getDate() + 7)
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 50, left: 70},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleTime()
.domain([now, future])
.nice()
.range([0, width])
var xAxis = d3.axisBottom(x).ticks(8)
var dates = xAxis.scale().ticks(xAxis.ticks()[0])
var data = dates.map(function(d, i){ return {date: d, hours: budgetedHours/dates.length, percent: 100/dates.length, index: i } });
var scaleMax = 12
console.log(data)
var dragged = null,
selected = null
d3.select(window)
.on("mousemove", mousemove)
.on("mouseup", mouseup)
.on("keydown", keydown);
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.hours); })
.curve(d3.curveCardinal);
// valueline.interpolate('cardinal-open')
var y = d3.scaleLinear().range([0, height]).domain([scaleMax, 0])
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("transform", "translate(0," + height + ")")
// .call(d3.axisLeft(y))
.call(xAxis)
svg.append("g")
.call(d3.axisLeft(y))
function redraw(){
var line = svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline)
.on("mousedown", function(d){ selected = dragged = d; });
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 10)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.hours); })
.on("mousedown", function(d){ selected = dragged = d; });
}
function mousedown() {
console.log('mousedown')
}
function mousemove() {
if(!dragged) return;
else {
var m = d3.mouse(svg.node());
// getDay(m[0])
day = dragged
oldPct = day.percent
day.hours = scaleHours(m[1])
day.percent = 100*day.hours/budgetedHours
balance(data, dragged.index, oldPct)
// dragged[1] = Math.max(0, Math.min(height, m[1]));
svg.select('.line').remove()
svg.selectAll('.dot').remove()
svg.selectAll('circle').remove()
redraw();
}
}
function mouseup() {
if(!dragged) return;
// mousemove();
dragged = null;
}
function keydown(){
console.log('keydown')
}
redraw()
function getDay(xPos){
dayLength = width / data.length
return data[Math.round((xPos/dayLength) - 0.8)]
}
function scaleHours(yPos){
var invertedPct = 1-(yPos / height)
var hours = invertedPct * scaleMax
return hours < 0 ? 0 : (hours > scaleMax ? scaleMax : hours)
}
function balance(array, index, oldPct){
var div = 1 - oldPct / 100
var balancedPct = array[index].percent
for(var i=0; i<array.length; i++){
if (i != index){
array[i].percent = 100 * (((1 - (balancedPct / 100)) * (array[i].percent / 100)) / div);
array[i].hours = budgetedHours * array[i].percent/100
}
}
return array
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment