Skip to content

Instantly share code, notes, and snippets.

@mph006
Last active March 3, 2016 18:25
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 mph006/20f76a764fd5ed2ff37f to your computer and use it in GitHub Desktop.
Save mph006/20f76a764fd5ed2ff37f to your computer and use it in GitHub Desktop.
Sparklines
<!DOCTYPE html>
<html>
<head>
<title>D3 Sparklines</title>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="sparklines.css"/>
</head>
<body>
<div id="sparkline-title">Basic Sparklines</div>
<div id="graph-container">
<div class="label-wrapper">
<div id="cost-label">Estimated Cost</div>
<div id="count-label">Count</div>
<div id="rating-label">Rating</div>
</div>
<div class="col-wrapper" id="a-info-wrapper">
<div class="title">Group A</div>
<div class="sparkline-wrapper" id="sparkline-a-cost"></div>
<div class="sparkline-wrapper" id="sparkline-a-meetings"></div>
<div class="sparkline-wrapper" id="sparkline-a-avgRating"></div>
</div>
<div class="col-wrapper" id="b-info-wrapper">
<div class="title">Group B</div>
<div class="sparkline-wrapper" id="sparkline-b-cost"></div>
<div class="sparkline-wrapper" id="sparkline-b-meetings"></div>
<div class="sparkline-wrapper" id="sparkline-b-avgRating"></div>
</div>
<div class="col-wrapper" id="c-info-wrapper">
<div class="title">Group C</div>
<div class="sparkline-wrapper" id="sparkline-c-cost"></div>
<div class="sparkline-wrapper" id="sparkline-c-meetings"></div>
<div class="sparkline-wrapper" id="sparkline-c-avgRating"></div>
</div>
</div>
</body>
<script type="text/javascript" src="sparklines.js"></script>
</html>
body{
font-family: Helvetica;
}
#graph-container{
position: relative;
display: inline-block;
width: 90%;
left: 5%;
height:175px;
}
#sparkline-title{
display: block;
position: relative;
width: 70%;
margin-left: 15%;
text-align: center;
border-bottom: thin solid black;
margin-top: 10px;
margin-bottom: 30px;
padding-bottom: 10px;
font-size: 20px;
}
.label-wrapper{
position: absolute;
width: 10%;
display: inline-block;
text-align: right;
top:35px;
}
#count-label, #rating-label{
margin-top: 40px;
}
.title{
margin-bottom: 10px;
}
#a-info-wrapper{
margin-left: 10%;
}
.col-wrapper{
position: relative;
display: inline-block;
width: 25%;
text-align: center;
}
.sparkline {
fill: none;
stroke: #000;
stroke-width: 0.5px;
}
.sparkcircle {
fill: red;
stroke: none;
}
.sparkline-wrapper{
position: relative;
display: inline-block;
height: 40px;
cursor:pointer;
width:70%;
color: black;
margin-bottom: 15px;
}
#insight-row-avgRating{
top:-12px;
}
.text-value{
position: absolute;
white-space: nowrap;
overflow: hidden;
}
.text-flip-number{
position: absolute;
color:steelblue;
font-size: 18px;
text-align: center;
left: 105%;
top:-2px;
}
.flip-descriptor-tag{
position: absolute;
font-size: 16px;
text-align: center;
left:10%;
top:8px;
}
var animDuration = 1000;
//http://stackoverflow.com/questions/1527803/generating-random-numbers-in-javascript-in-a-specific-range
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function generateExecSparklineData(min,max){
var returnArray=[];
var datePointer = new Date();
var i=0;
//off by 1 error here, not sure why
datePointer = new Date(datePointer.setDate(datePointer.getDate()+1));
while(i<30){
returnArray.push({
date:datePointer,
value:getRandomInt(min,max)
});
datePointer = new Date(datePointer.setDate(datePointer.getDate()-1));
i++;
}
return returnArray;
}
//http://www.tnoda.com/blog/2013-12-19
function sparkline(elemId, data) {
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function prettyPrint(id,value){
value = numberWithCommas(value);
if (id.indexOf("cost") > -1){
return "$"+value;
}
else{
return value;
}
}
data.forEach(function(d){
d.date = new Date(d.date);
})
function getSummation(){
var sum = 0;
for(var i=0; i<data.length; i++){
sum = sum+data[i].value;
}
return sum;
}
function clickEventHandler(){
var element = document.getElementById(elemId.replace("#",""));
var isFlipped = element.getAttribute("data-flipped");
console.log(element);
if(!(elemId.indexOf("avgRating") > -1)){
if(isFlipped === "false"){
d3.select("#"+"current-path-"+elemId.replace("#","")).transition().duration(animDuration/1.5).style("opacity",0)
d3.select("#this-spark-circle-"+elemId.replace("#","")).transition().duration(animDuration/1.5).style("opacity",0);
d3.select("#text-value-"+elemId.replace("#","")).transition().duration(animDuration/1.5).style("opacity",0);
d3.select(elemId+"-flip-number").transition().delay(animDuration/2).duration(animDuration/2).style("opacity",1);
d3.select(elemId+"-flip-number-label").transition().delay(animDuration/2).duration(animDuration/2).style("opacity",1);
d3.select(elemId).attr("data-flipped",true);
}
else{
d3.select("#"+"current-path-"+elemId.replace("#","")).transition().delay(animDuration/1.5).duration(animDuration/2).style("opacity",1)
d3.select("#this-spark-circle-"+elemId.replace("#","")).transition().delay(animDuration/1.5).duration(animDuration/2).style("opacity",1);
d3.select("#text-value-"+elemId.replace("#","")).transition().delay(animDuration/1.5).duration(animDuration/2).style("opacity",1);
d3.select(elemId+"-flip-number").transition().duration(animDuration/1.5).style("opacity",0);
d3.select(elemId+"-flip-number-label").transition().duration(animDuration/1.5).style("opacity",0);
d3.select(elemId).attr("data-flipped",false);
}
}
}
//leave room for the text value to the right
var width = $(elemId).width()-20;
var height = $(elemId).height();
var x = d3.scale.linear().range([width-10, 0]);
var y = d3.scale.linear().range([height-10, 0]);
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain(d3.extent(data, function(d) { return d.value; }));
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.value); });
var svg = d3.select(elemId)
.append('svg')
.attr('width', width)
.attr("class","sparkline-wrapper-svg")
.attr('height', height)
.append('g')
.attr('transform', 'translate(0, 2)');
svg.append('path')
.datum(data)
.attr('class', 'sparkline')
.attr("id","current-path-"+elemId.replace("#",""))
.attr('d', line);
svg.append('circle')
.attr('class', 'sparkcircle')
.attr("id","this-spark-circle-"+elemId.replace("#",""))
.attr('cx', x(data[data.length-1].date))
.attr('cy', y(data[data.length-1].value))
.style("opacity",0)
.attr('r', 2);
var totalLength = d3.select("#current-path-"+elemId.replace("#","")).node().getTotalLength();
d3.select("#current-path-"+elemId.replace("#",""))
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(animDuration)
.ease("linear")
.attr("stroke-dashoffset", 0);
d3.select(elemId).append("text")
.attr("class","text-value")
.style("opacity","0")
.attr("id","text-value-"+elemId.replace("#",""))
.text(prettyPrint(elemId,data[data.length-1].value));
d3.select("#this-spark-circle-"+elemId.replace("#","")).transition().delay(animDuration).duration(animDuration/1.5).style("opacity",1);
d3.select("#text-value-"+elemId.replace("#","")).transition().delay(animDuration).duration(animDuration/1.5).style("opacity",1);
d3.select(elemId).append("text")
.attr("class","flip-descriptor-tag")
.attr("id",elemId.replace("#","")+"-flip-number-label")
.style("opacity","0")
.text("Total:")
.append("text")
.attr("class","text-flip-number")
.attr("id",elemId.replace("#","")+"-flip-number")
.style("opacity","0")
.text(prettyPrint(elemId,getSummation()));
d3.select(elemId)
.attr("data-flipped",false)
.on("click",clickEventHandler);
}
$( document ).ready(function() {
sparkline('#sparkline-a-cost', generateExecSparklineData(1000,2000));
sparkline('#sparkline-a-meetings', generateExecSparklineData(10,60));
sparkline('#sparkline-a-avgRating', generateExecSparklineData(1,4));
sparkline('#sparkline-b-cost', generateExecSparklineData(1000,2000));
sparkline('#sparkline-b-meetings', generateExecSparklineData(10,60));
sparkline('#sparkline-b-avgRating', generateExecSparklineData(1,4));
sparkline('#sparkline-c-cost', generateExecSparklineData(10000,20000));
sparkline('#sparkline-c-meetings', generateExecSparklineData(100,600));
sparkline('#sparkline-c-avgRating', generateExecSparklineData(1,3));
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment