Skip to content

Instantly share code, notes, and snippets.

@diggetybo
Last active June 29, 2016 09:47
Show Gist options
  • Save diggetybo/83188e161c39f2d0f7025087598ec075 to your computer and use it in GitHub Desktop.
Save diggetybo/83188e161c39f2d0f7025087598ec075 to your computer and use it in GitHub Desktop.
CSS Button Events + D3.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=11">
</head>
<style>
#canvas {
}
#canvas-svg {
margin: auto;
padding-top: 40px;
position: relative;
width: 1000px;
}
table{
width:60%;
margin-left:auto;
margin-right:auto;
}
td{width:50%;}
.bulleT { font: 10px 'Play',sans-serif; margin-left:auto;margin-right:auto;}
.bulleT .marker { stroke: #4D4D4D; stroke-width: 2px;}
.bulleT .marker.s0 { fill-opacity:0; stroke: #999999; stroke-width: 2px; }
.bulleT .marker.s1 { fill-opacity:0; stroke: #000; stroke-width: 2px; }
.bulleT .tick line { stroke: #666; stroke-width: .5px; }
.bulleT .range.s0 { fill: #386c9b; }
.bulleT .range.s1 { fill: #568bc2; }
.bulleT .range.s2 { fill: #90b2db; }
.bulleT .range.s3 { fill: #568bc2; }
.bulleT .range.s4 { fill: #386c9b; }
.bulleT .measure.s0 { fill: #4D4D4D; }
.bulleT .measure.s1 { fill: #999999; }
.bulleT .measure.s2 { fill: #eeeeee; }
.bulleT .measure.s3 { fill: #999999; }
.bulleT .measure.s4 { fill: #4D4D4D; }
.bulleT .title { font-size: 12px; font-weight: bold; }
.bulleT .subtitle.s04 { fill: #999999; font-size: 10px;}
.bulleT .subtitle.s13 { fill: #999999; font-size: 10px;}
.bulleT .subtitle.s2 { fill: #999999; font-size: 10px;}
.option {
font-family: Play;
color: #ffffff;
font-size: 12px;
width: 6%;
background: #303030;
padding: 10px 20px 10px 20px;
}
.option:hover {
background: #4c4d4d;
}
div#option2{
position:relative;
top: 10px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="canvas-svg">
<div id="canvas-svg">
<table>
<tr>
<td>
<div id="BulleT_horizontal"></div>
</td>
</tr>
</table>
</div>
<div id="option1" class="option"> Outcome 1</div>
<div id="option2" class="option"> Outcome 2</div>
<p>The Bullet Chart is here.</p>
<script>
(function() {
// Simple modification based on mbostock's Bullet Charts.
d3.bulleT = function() {
var orient = "left",
reverse = false,
vertical = false,
terjedelem = bulleTTerjedelem,
ranges = bulleTRanges,
markers = bulleTMarkers,
measures = bulleTMeasures,
width = 380,
height = 30,
tickFormat = null;
// For each small multiple
function bulleT(g) {
g.each(function(d, i) {
var terjedelemz = terjedelem.call(this, d, i),
rangez = ranges.call(this, d, i).slice().sort(d3.descending),
markerz = markers.call(this, d, i),
measurez = measures.call(this, d, i).slice().sort(d3.descending),
g = d3.select(this);
var wrap = g.select("g.wrap");
if (wrap.empty()) wrap = g.append("g").attr("class", "wrap");
// Compute the x-scale.
var x0 = d3.scale.linear()
.domain([terjedelemz[0], terjedelemz[1]])
.range(reverse ? [width, 0] : [0, width]);
// Stash the new scale.
this.__chart__ = x0;
// Derive width-scales from the x-scales.
var w = bulleTWidth(x0,terjedelemz[0]);
// Update the range rects.
rangez.unshift(terjedelemz[1]);
var range = wrap.selectAll("rect.range")
.data(rangez);
range.enter().append("rect")
.filter( function(d, i){ if(i != 3){ return d} })
.attr("class", function(d, i) { return "range s" + i; })
.attr("width", w)
.attr("y", 0)
.attr("height",height)
.attr("x", reverse ? x0 : 0);
range.enter().append("line")
.filter( function(d, i){ if(i == 3){ return d} })
.attr("class", "marker")
.attr("x1", x0)
.attr("x2", x0)
.attr("y1", 0)
.attr("y2", height);
// Append the measure rects.
measurez.unshift(terjedelemz[1]);
var measure = wrap.selectAll("rect.measure")
.data(measurez);
measure.enter().append("rect")
.attr("class", function(d, i) { return "measure s" + i; })
.attr("width", w)
.attr("height", height / 2)
.attr("x", reverse ? x0 : 0)
.attr("y", height / 4);
// Append rect and line marker.
var marker = wrap.selectAll("rect.marker")
.data(markerz);
marker.enter().append("rect")
.filter( function(d, i){ if(i == 1){ return d} })
.attr("class", "marker s1")
.attr("width", 6)
.attr("y", -(height/10))
.attr("height",function(d) {return height+(height/5);})
.attr("x", x0)
.attr("transform", "translate(-3,0)");
var option1 = d3.select("#option1");
option1.on('click.outcome1', outcome1);
option1.on('click.val1', markerz = [105.6, 154.78, 122.8, 156.8]);
var option2 = d3.select("#option2");
option2.on('click.outcome2', outcome2);
option2.on('click.val2', markerz2 = [221.49, 190.12, 229.04, 171.2]);
function outcome1(markerz2) {
d3.selectAll('rect.marker').data(markerz)
.transition()
.duration(3000)
.attr("x", function(d) {return d})
};
function outcome2(markerz3) {
d3.selectAll('rect.marker').data(markerz2)
.transition()
.duration(3000)
.attr("x", function(d) {return d})
};
marker.enter().append("line")
.filter( function(d, i){ if(i == 0){ return d} })
.attr("class", "marker s0")
.attr("x1", x0)
.attr("x2", x0)
.attr("y1", height / 4)
.attr("y2", height-(height / 4) );
// Compute the tick format.
var format = tickFormat || x0.tickFormat(8);
// Update the tick groups.
var tick = g.selectAll("tick")
.data(x0.ticks(8), function(d) {
return this.textContent || format(d);
});
// Initialize the ticks with the old scale, x0.
var tickEnter = tick.enter().append("g")
.attr("class", "tick")
.attr("transform", bulleTTranslate(x0))
.style("opacity", 1);
tickEnter.append("line")
.attr("y1", height)
.attr("y2", height * 7 / 6);
tickEnter.append("text")
.attr("text-anchor", "middle")
.attr("transform", function(d){
if (vertical) {
return "rotate(90)";
}
})
.attr("dy", function(d){
if(vertical){return width/60; }else{ return height+15 }
})
.attr("dx", function(d){
if(vertical){return height+15 ;}
})
.text(format);
});
}
// left, right, top, bottom
bulleT.orient = function(x) {
if (!arguments.length) return orient;
orient = x;
reverse = orient == "right" || orient == "bottom";
return bulleT;
};
// terjedelem
bulleT.terjedelem = function(x) {
if (!arguments.length) return terjedelem;
terjedelem = x;
return bulleT;
};
// ranges (bad, satisfactory, good)
bulleT.ranges = function(x) {
if (!arguments.length) return ranges;
ranges = x;
return bulleT;
};
//*
// markers (previous, goal)
bulleT.markers = function(x) {
if (!arguments.length) return markers;
markers = x;
return bulleT;
};
// measures (actual, forecast)
bulleT.measures = function(x) {
if (!arguments.length) return measures;
measures = x;
return bulleT;
};
//*/
bulleT.vertical = function(x) {
if (!arguments.length) return vertical;
vertical = x;
return bulleT;
};
bulleT.width = function(x) {
if (!arguments.length) return width;
width = x;
return bulleT;
};
bulleT.height = function(x) {
if (!arguments.length) return height;
height = x;
return bulleT;
};
bulleT.tickFormat = function(x) {
if (!arguments.length) return tickFormat;
tickFormat = x;
return bulleT;
};
return bulleT;
};
function bulleTTerjedelem(d) {
return d.terjedelem;
}
function bulleTRanges(d) {
return d.ranges;
}
function bulleTMarkers(d) {
return d.markers;
}
function bulleTMeasures(d) {
return d.measures;
}
function bulleTTranslate(x) {
return function(d) {
return "translate(" + x(d) + ",0)";
};
}
function bulleTWidth(x,y) {
var x0 = x(0);
return function(d) {
return Math.abs(x(d-y) - x0);
};
}
})();
var Tscore_Man_Height = 1153;
var Tscore_Woman_Height = 1506;
var Tscore_Man_Weight = 8.63;
var Tscore_Woman_Weight = 5.86
var Tscore2 = 1300
// terjedelem is the hungarian translation of the statistical term of range
var data = [
{"title":"Exper","dimension":"(diff)","subtitle":Tscore_Man_Height,"terjedelem":[-3000,3000],"ranges":[ -2000, -1000, 0, 1000, 2000],"measures":[-1366,-676,605,1108.81],"markers":[-23,Tscore_Man_Height]},
{"title":"Gold","dimension":"(diff)","subtitle":Tscore_Woman_Height,"terjedelem":[-8000,8000],"ranges":[-5250,-2750,0,2750,5250],"measures":[-901,110,845.5,2107.5],"markers":[412,Tscore_Woman_Height]},
{"title":"Tech","dimension":"(diff)","subtitle":Tscore_Man_Weight,"terjedelem":[-20,20],"ranges":[-13.33,-6.66,0,6.66,13.33],"measures":[-8.7,-.9,4.9,10.7],"markers":[1,Tscore_Man_Weight]},
{"title":"Units","dimension":"(diff)","subtitle":Tscore_Woman_Weight,"terjedelem":[-80,80],"ranges":[-53.33,-26.66,0,26.66,53.33],"measures":[-18,-7.8,3.8,23],"markers":[-3,Tscore_Woman_Weight]}
]
var Width = 400, Height = 50;
var margin = {top: 5, right: 20, bottom: 20, left: 60},
width = Width - margin.left - margin.right,
height = Height - margin.top - margin.bottom;
var chart = d3.bulleT()
.width(width)
.height(height);
function bulleT(whichData,whereToPut,direction) {
var a=Width, b=Height;
if( direction == "vertical"){
Height=a;Width=b+30;
vertical = true;
}else{
Height=a-20;Width=b;
vertical = false;
}
var svg = d3.select(whereToPut).selectAll("svg")
.data(whichData)
.enter().append("svg")
.attr("class", "bulleT")
.attr("width", Width)
.attr("height", Height)
.append("g")
.attr("transform", function(){
if( direction == "vertical"){
return "rotate(-90)translate("+ -(Height-margin.left) +",10)";
}else{
return "translate("+ margin.left +","+ margin.top +")";
}
})
.call(chart.vertical(vertical));
var title = svg.append("g")
.style("text-anchor", function(){
if( direction == "vertical"){
return "middle";
}else{
return "end";
}
})
.attr("transform", function(){
if( direction == "vertical"){
return "rotate(90)translate("+ Width/4 +",20)";
}else{
return "translate(-16," + height / 3 + ")";
}
});
title.append("text")
.attr("class", "title")
.text(function(d) { return d.title; });
title.append("text")
.attr("dy", "1.2em")
.text(function(d) { return d.dimension; });
title.append("text")
.attr("class",function(d) {
switch (true)
{
case ( (d.markers[1] < 30) || (70 < d.markers[1]) ):
return "subtitle s04";
break;
break;
case ( (30 <= d.markers[1]) && (d.markers[1] < 40) ):
return "subtitle s13";
break;
case ( (40 <= d.markers[1]) && (d.markers[1] <= 60) ):
return "subtitle s2";
break;
case ( (60 < d.markers[1]) && (d.markers[1] <= 70) ):
return "subtitle s13";
break;
}
}
)
.attr("dy", function(){
return "2.4em";
})
.text(function(d) { return d.subtitle; });
};
bulleT(data,"#BulleT_vertical","vertical"); // "horizontal" or "vertical"
bulleT(data,"#BulleT_horizontal","horizontal");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment