View this code at http://livecoding.io/3506528
-
-
Save organisciak/3506528 to your computer and use it in GitHub Desktop.
created by http://livecoding.io/3506528
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"libraries": [ | |
"d3" | |
], | |
"mode": "json", | |
"layout": "fullscreen mode (horizontal)" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font-family: Georgia, serif; | |
font-size: 12pt; | |
} | |
.slip, .dialog { | |
position: relative; | |
border-bottom: solid 1px lightgray; | |
border-top: solid 1px lightgray; | |
margin: 10px auto 10px auto; | |
padding: 10px 0; | |
} | |
.note { | |
color: darkGray; | |
margin: 5px 0; | |
} | |
h2 { | |
font-size: 14pt; | |
margin: 0; | |
} | |
h3 { | |
font-size: 12pt; | |
} | |
.choose-type h3 { | |
margin: 5px; | |
} | |
.choose-type { | |
text-align: center; | |
margin: 10px; | |
} | |
.choose-type input { | |
margin: 0 5px 0 25px; | |
} | |
.bar-outline { | |
fill: whitesmoke; | |
} | |
input[type=date] { | |
width: 100px; | |
} | |
text { | |
font-size: 10pt; | |
text-anchor: middle; | |
} | |
.bar { | |
//background:gray; | |
} | |
.overlay { | |
position: absolute; | |
left: 0; | |
top: 0; | |
background: white; | |
width: 100%; | |
height: 100%; | |
opacity: 0.9; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="container"></div> | |
<input id="output" /> | |
<input id="add" type="button" value="Add bar" /> | |
<input id="set" type="button" value="Set Interval" /> | |
<input id="clear" type="button" value="Clear Interval" /> | |
<input id="reset" type="button" value="Reset Vars" /> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
To do: | |
Updating for other browsers with Modernizr and jQuery Datepicker | |
--http://updates.html5rocks.com/2012/08/Quick-FAQs-on-input-type-date-in-Google-Chrome | |
*/ | |
//PROGRESS CLASS | |
var progress = (function() { | |
//PRIVATE VARIABLES | |
var input = livecoding.json, | |
pageWidth = document.width<=1200 ? document.width : 1200, | |
pageMargin = 100, | |
containerWidth = pageWidth-pageMargin*2, | |
containerMargin = 20, | |
barWidth = containerWidth-containerMargin*2, | |
//PRIVATE FUNCTIONS | |
format = function(value, type) { | |
//Format text based on the bar type | |
if (type==="manual") { | |
return value; | |
} else if (type==="date") { | |
date = new Date(value); | |
return date.toLocaleTimeString(); | |
} else if (type==="timer") { | |
milliseconds = value; | |
hours = Math.floor(value / (1000*60*60))%24; | |
minutes = Math.floor(value / (1000*60))%60; | |
seconds = Math.floor(value / (1000))%60; | |
function leadingZero(int){ return (int >9 ? int : "0"+int); } | |
return hours+":"+leadingZero(minutes)+":"+leadingZero(seconds); | |
} else { | |
throw "No valid bar type"; | |
} | |
}, | |
progressLocation = function(data, fullWidth) { | |
var current = (function(){ | |
if (data.type==="timer" && data.progress.start){ | |
return data.current+data.progress.current-data.progress.start; | |
} else { | |
return data.current; | |
} | |
})(); | |
var percentage = (current-data.start)/(data.end-data.start); | |
var location = percentage <= 1 ? percentage * fullWidth : fullWidth; | |
return location; | |
}, | |
startTimer = function(selection) { | |
index = input.bars.indexOf(selection); | |
if (input.bars[index].type==="timer" && !input.bars[index].progress.start) { | |
input.bars[index].progress.start = new Date().getTime(); | |
} | |
}, | |
pauseTimer = function(selection) { | |
index = input.bars.indexOf(selection); | |
if (input.bars[index].type==="timer" && input.bars[index].progress.start) { | |
//Upon disengaging the timer, save the temporary | |
//Date() timer progress into the 'current' var | |
input.bars[index].current = input.bars[index].current + (new Date().getTime()-input.bars[index].progress.start); | |
delete input.bars[index].progress.start; | |
} | |
}, | |
toggleTimer = function(selection) { | |
index = input.bars.indexOf(selection); | |
if (input.bars[index].progress.start) { | |
pauseTimer(selection); | |
} else { | |
startTimer(selection); | |
} | |
}, | |
addSlip = function(key) { | |
input.bars.push( | |
{ | |
"key": String(key), | |
"type": "manual", | |
"name": "First Test", | |
"note": null, | |
"start": 0, | |
"end": 30, | |
"current": 20} | |
) | |
progress.draw(); | |
}, | |
update = function(selection) { | |
var currentTime = (new Date()).getTime(); | |
var progress = d3.selectAll(".progress") | |
.data(input.bars); | |
progress.transition() | |
.duration(300) | |
.attr("width", function(d) { | |
if (d.type==="date") { | |
d.current = currentTime; | |
} else if (d.type==="timer" && d.progress.start) { | |
d.progress.current = currentTime; | |
} | |
return progressLocation(d, barWidth); | |
}); | |
d3.selectAll(".current") | |
.transition() | |
.duration(300) | |
.text(function(d){ | |
var c = d.current; | |
if (d.type==="date") { | |
c = currentTime; | |
} else if (d.type==="timer" && d.progress.start) { | |
c = d.current+(currentTime-d.progress.start); | |
} | |
return format((c <= d.end ? c : d.end),d.type) | |
}) | |
.attr("x", function(d){return progressLocation(d, barWidth)+20}); | |
}, | |
generateKey = function() { | |
return Math.floor( | |
Math.random() * 0x1000000 | |
).toString(16); | |
}, | |
enter = function(selection) | |
{ | |
//START DEBUG | |
selection | |
.append("button") | |
.text("Delete").style("float", "right") | |
.on("click", slipDelete); | |
selection.append("button") | |
.text("Edit").style("float", "right") | |
.on("click", function(d,i){}); | |
selection.filter(function(d, i) { return d.type == "manual" }) | |
.append("button") | |
.text("Add 1").style("float", "right") | |
.on("click", updateData); | |
selection.filter(function(d, i) { return d.type == "timer" }) | |
.append("button") | |
.attr("class", "timer-toggle") | |
//.text(function(d){ if(d.progress.start){return "Pause"} else return {"Start"}}) | |
.text("Start/Pause") | |
.style("float", "right") | |
.on("click", toggleTimer); | |
// END DEBUG | |
selection.append("h2").text(function(d){ return d.name }); | |
selection.append("p") | |
.attr("class", "note") | |
.text(function(d){ return d.note }); | |
var bar = selection.append("svg") | |
.attr("width", containerWidth) | |
.attr("height", 60) | |
.attr("class", "bar") | |
.append("g") | |
.attr("transform", "translate("+0+","+(60-20)/2+")"); | |
//Start text | |
bar.append("text") | |
.text(function(d){return format(d.start, d.type)}) | |
.attr("x", function(d){ | |
a = format(d.start, d.type).length; | |
if (a>5){return 20+(20/a)*2} else { return 20} | |
}) | |
.attr("y", 31); | |
//progress text | |
bar.append("text") | |
.attr("class", "current") | |
.style("font-size", 12+"pt") | |
//.text(function(d){return (d.current <= d.end ? d.current : d.end)}) | |
//.attr("x", function(d){return progressLocation(d, barWidth)+20}) | |
.attr("y", -5); | |
//End text | |
bar.append("text") | |
.text(function(d){return format(d.end, d.type)}) | |
.attr("x", function(d){ | |
a = format(d.start, d.type).length; | |
if (a>5){return barWidth+20-(20/a)*2} else { return barWidth+20} | |
}) | |
.attr("y", 31); | |
bar.append("rect") | |
.attr("class", "bar-outline") | |
.attr("width", barWidth) | |
.attr("height", 20) | |
.attr("x", 20); | |
var progress = bar.append("rect") | |
.attr("class", "progress") | |
//.attr("width", function(d){return progressLocation(d, barWidth)}) | |
.attr("height", 20) | |
.attr("x", 20); | |
}, | |
slipAdd = function(key, type, name, note, start, end, current) { | |
var newBar = { | |
"key": key, | |
"type": type, | |
"name": name, | |
"note": note, | |
"start": start, | |
"end": end, | |
"current": current | |
}; | |
if(type==="timer") { | |
newBar["progress"] = {"start":null, "current":null} | |
} | |
input.bars.push(newBar); | |
progress.draw(); | |
}, | |
slipDelete = function(selection){ | |
index = input.bars.indexOf(selection); | |
input.bars.splice(index, 1); | |
progress.draw(); | |
console.log(input.bars); | |
}, | |
slipEdit = function(selection){ | |
index = input.bars.indexOf(selection); | |
selection.append("div") | |
.attr("class", "overlay") | |
.text("hello"); | |
}, | |
updateData = function(selection) { | |
index = input.bars.indexOf(selection); | |
input.bars[index].current += 1; | |
progress.draw(); | |
} | |
; | |
return { | |
draw : function() | |
{ | |
var container = d3.select("#container").style("width", containerWidth); | |
var slips = container.selectAll(".slip") | |
.data(input.bars, function(d) { return d.key; }) | |
//ENTER | |
slips.enter().append("div") | |
.attr("class", "slip") | |
//.style("background", "blue") | |
.style("padding", 4+"px "+containerMargin+"px") | |
.style("width", containerWidth+"px") | |
.call(enter); | |
//UPDATE | |
slips.call(update); | |
//EXIT | |
slips.exit().transition() | |
.duration(1000) | |
.style("overflow", "hidden") | |
.style("padding", 0+"px 0") | |
.style("height", 0+"px") | |
.remove(); | |
}, | |
add : function() { | |
var container = d3.select("#container"); | |
var dialog = container.append("div") | |
.attr("class", "dialog") | |
.style("background", "whitesmoke") | |
.style("padding", 4+"px "+containerMargin+"px") | |
.style("width", containerWidth+"px"); | |
var key = generateKey(); | |
dialog.append("h2").text("Add a new progress bar."); | |
//Choose bar type | |
dialog.append("div") | |
.attr("class", "choose-type") | |
.html("<h3>Choose progress bar type</h3>" | |
+"<input type='radio' name='bar-type-uniqueid' value='Counter' checked>Counter" | |
+"<input type='radio' name='bar-type-uniqueid' value='Timer'>Timer" | |
+"<input type='radio' name='bar-type-uniqueid' value='Clock'>Clock" | |
); | |
//Choose start time | |
dialog.append("div") | |
.attr("class", "choose-timer") | |
.html("<h3>Choose start time</h3>" | |
+"Date <input type='date' name='start-date-uniqueid' value='2012-10-10'>" | |
+" Time <input type='time' name='start-time-uniqueid' value='22:10'>" | |
); | |
//Choose end time | |
dialog.append("div") | |
.attr("class", "choose-timer") | |
.html("<h3>Choose end time</h3>" | |
+"Date <input type='date' name='end-date-uniqueid' value='2012-10-10'>" | |
+" Time <input type='time' name='end-time-uniqueid' value='22:10'>" | |
); | |
dialog.append("br"); | |
//Example Time picker | |
dialog.append("input").attr("type", "number").style("width", "3em") | |
.attr("name", "hours") | |
.attr("min", "0") | |
.attr("value", "0"); | |
dialog.append("input").attr("type", "number").style("width", "2em") | |
.attr("max", "59").attr("min", "0") | |
.attr("name", "minutes") | |
.attr("value", "1"); | |
dialog.append("input").attr("type", "number").style("width", "2em") | |
.attr("max", "59").attr("min", "0") | |
.attr("name", "seconds") | |
.attr("value", "0"); | |
dialog.append("br"); | |
//Example generic counter | |
dialog.append("input").attr("type", "number").style("width", "3em") | |
.attr("name", "start") | |
.attr("min", "0") | |
.attr("value", "0"); | |
dialog.append("input").attr("type", "number").style("width", "3em") | |
.attr("name", "end") | |
.attr("min", "0") | |
.attr("value", "0"); | |
dialog.append("br"); | |
dialog.append("button") | |
.text("OK") | |
.on("click", function() { | |
//dialog.remove(); | |
//slipAdd(key, "manual", "First Test"+key, null, 0, 1000, 0); | |
console.log(d3.select("name['bar-type-uniqueid']")) | |
}); | |
dialog.append("button") | |
.text("Cancel") | |
.on("click", function() { | |
dialog.remove(); | |
}); | |
} | |
}; | |
})(); | |
progress.draw(); | |
progress.add(); | |
//DEBUGGING | |
var timer; | |
$("#add").on("click", progress.add); | |
$("#set").on("click", function(){timer=window.setInterval(function(){progress.draw();}, 1000)} ); | |
$("#clear").on("click", function(){clearInterval(timer)}); | |
$("#reset").on("click", function(){for (i in input.bars){input.bars[i].current=input.bars[i].start};}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"barWidth" : 500, | |
"bars":[ | |
{ | |
"type": "manual", | |
"name": "Field Exam Reading", | |
"key": "sdffbs3", | |
"note": "Progress on Field Exam readings. One point for each paper/chapter.", | |
"start": 0, | |
"end": 51, | |
"current": 27 | |
}, | |
{ | |
"type": "manual", | |
"name": "Field Exam Notes", | |
"key": "dsadf", | |
"note": null, | |
"start": 0, | |
"end": 42, | |
"current": 11 | |
}, | |
{ | |
"type": "date", | |
"name": "Date", | |
"key": "dfasgydf", | |
"note": null, | |
"start": 1346475600000, | |
"end": 1351659600000, | |
"current": null | |
}, | |
{ | |
"type": "timer", | |
"name": "Timer", | |
"key": "hu54i58", | |
"note": null, | |
"start": 0, | |
"end": 1000000, | |
"current": 0, | |
"progress" : {"start":null, "current":null} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment