Skip to content

Instantly share code, notes, and snippets.

@organisciak
Forked from anonymous/options.json
Created August 29, 2012 03:31
Show Gist options
  • Save organisciak/3506528 to your computer and use it in GitHub Desktop.
Save organisciak/3506528 to your computer and use it in GitHub Desktop.
{
"libraries": [
"d3"
],
"mode": "json",
"layout": "fullscreen mode (horizontal)"
}
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;
}
<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" />
/*
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};});
{
"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