Skip to content

Instantly share code, notes, and snippets.

@ArvinH
Last active October 15, 2016 09:40
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 ArvinH/7c676f582f06b64ab89d1c55fcc25efd to your computer and use it in GitHub Desktop.
Save ArvinH/7c676f582f06b64ab89d1c55fcc25efd to your computer and use it in GitHub Desktop.

Time timer by d3.js v4

simply input minutes and you can see how many time remains through visual block

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="time.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
</head>
<body>
<div class="container">
<div class='chart'></div>
<label for="fname">Time (minutes)</label>
<input type="number" id="time" name="time">
</div>
<script src="timer.js"></script>
</body>
</html>
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
input[type=number] {
border: 2px solid red;
border-radius: 4px;
margin-top: 10px;
}
.chart {
width: 100%;
height:100%;
text-align: center;
}
// Data setting
const timeData = (time, sec) => {
let second = sec;
return [
{
"unit": "seconds",
"numeric": second
}, {
"unit": "minutes",
"numeric": time
}
];
};
// value setting
let width = 300;
let height = 200;
let offSetX = 150;
let offSetY = 100;
let pi = Math.PI;
let scaleSecs = d3.scaleLinear().domain([0, 59 + 999/1000]).range([0, 2 * pi]);
let scaleMins = d3.scaleLinear().domain([0, 59 + 59/60]).range([0, 2 * pi]);
let vis = d3.selectAll(".chart")
.append("svg:svg")
.attr("width", width)
.attr("height", height);
let clockGroup = vis.append("svg:g")
.attr("transform", "translate(" + offSetX + "," + offSetY + ")");
clockGroup.append("svg:circle")
.attr("r", 80).attr("fill", "none")
.attr("class", "clock outercircle")
.attr("stroke", "black")
.attr("stroke-width", 2);
clockGroup.append("svg:circle")
.attr("r", 4)
.attr("fill", "black")
.attr("class", "clock innercircle");
// render clock
const render = (data) => {
let minuteArc, secondArc;
clockGroup.selectAll(".clockhand").remove();
secondArc = d3.arc()
.innerRadius(0)
.outerRadius(70)
.startAngle((d) => {
return scaleSecs(d.numeric);
})
.endAngle((d) => {
return scaleSecs(d.numeric);
});
minuteArc = d3.arc()
.innerRadius(0)
.outerRadius(80)
.startAngle((d) => {
return 0;
})
.endAngle((d) => {
return scaleMins(d.numeric);
});
clockGroup.selectAll(".clockhand")
.data(data)
.enter()
.append("svg:path")
.attr("d", (d) => {
if (d.unit === "seconds") {
return secondArc(d);
} else if (d.unit === "minutes") {
return minuteArc(d);
}
})
.attr("class", "clockhand")
.attr("stroke", "black")
.attr("stroke-width", function(d) {
if (d.unit === "seconds") {
return 2;
} else if (d.unit === "minutes") {
return 3;
}
})
.attr("fill", "red")
.attr("opacity", "0.8");
};
let timer;
const startTimer = (e) => {
// Main program
clearInterval(timer);
let data;
let timeAsSec = e.target.valueAsNumber * 60;
let sec = 0;
timer = setInterval(() => {
sec = sec + 1;
timeAsSec = timeAsSec - 1;
data = timeData(timeAsSec / 60, sec);
render(data);
if (timeAsSec === 0) {
clearInterval(timer);
}
}, 1000);
};
let timeInput = document.querySelector('#time');
timeInput.addEventListener("change", startTimer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment