|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> |
|
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.js"></script> |
|
<link rel="stylesheet" type="text/css" href="SSTIcostsFlareDummy.css" /> |
|
</head> |
|
<body> |
|
<div id="header">Student IT Maintenance/Operations</div> |
|
<div id="mini-pie"> |
|
<script type="text/javascript"> |
|
|
|
var r = Math.min(80, 80) * .15, |
|
donut = d3.layout.pie().sort(null), |
|
arc = d3.svg.arc().innerRadius(r / 1.75).outerRadius(r), |
|
mode = 'numClasses'; |
|
|
|
var pieData = [ |
|
{name:"Maintenance/Operations", "tco":9.0, "class":"greenPie"}, |
|
{name:"Overhead / Other", "tco":1.0, "class":"clearPie"}, |
|
] |
|
|
|
var pie = d3.select("body").append("svg:svg") |
|
.attr("width", 80 ) |
|
.attr("height", 80) |
|
.data([pieData]); |
|
|
|
var arcs = pie.selectAll("g") |
|
.data(donut.value(function(d) { return d.tco })) |
|
.enter().append("svg:g") |
|
.attr("transform", "translate(" + 50 + "," + 68 + ")") |
|
.append("svg:path") |
|
.attr("d", arc) |
|
.each(function(d) { this._current = d; }) |
|
.attr("class", function(d) { return d.data.class ;}); |
|
|
|
// Computes the angle of an arc, converting from radians to degrees. Thanks to Frank Guerino.) |
|
function angle(d) { |
|
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90; |
|
return a > 90 ? a - 180 : a; |
|
} |
|
|
|
// Store the currently-displayed angles in this._current. |
|
// Then, interpolate from this._current to the new angles. |
|
function arcTween(a) { |
|
var i = d3.interpolate(this._current, a); |
|
this._current = i(0); |
|
return function(t) { |
|
return arc(i(t)); |
|
}; |
|
} |
|
|
|
</script> |
|
</div> |
|
<div id="sub-header">A breakdown of the 90% totaling $79.6MM*</div> |
|
<div id="button-div"> |
|
<text id="button-label" class="start">START</text> |
|
<svg |
|
xmlns:dc="http://purl.org/dc/elements/1.1/" |
|
xmlns:cc="http://creativecommons.org/ns#" |
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|
xmlns:svg="http://www.w3.org/2000/svg" |
|
xmlns="http://www.w3.org/2000/svg" |
|
xmlns:xlink="http://www.w3.org/1999/xlink" |
|
version="1.1" |
|
width="64.193283" |
|
height="63.523876" |
|
viewBox="0 0 51.354626 50.819101" |
|
id="button" |
|
class="start"> |
|
<metadata |
|
id="metadata527389"> |
|
<dc:date>2012-11-25 05:03Z</dc:date> |
|
<!-- Produced by OmniGraffle Professional 5.4.2 --> |
|
<rdf:RDF> |
|
<cc:Work |
|
rdf:about=""> |
|
<dc:format>image/svg+xml</dc:format> |
|
<dc:type |
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
|
<dc:title></dc:title> |
|
</cc:Work> |
|
</rdf:RDF> |
|
</metadata> |
|
<defs |
|
id="defs527391"> |
|
<linearGradient |
|
id="linearGradient541386"> |
|
<stop |
|
id="stop541388" |
|
style="stop-color:#ffcc00;stop-opacity:1" |
|
offset="0" /> |
|
<stop |
|
id="stop541390" |
|
style="stop-color:#ff2a2a;stop-opacity:0" |
|
offset="1" /> |
|
</linearGradient> |
|
<linearGradient |
|
id="linearGradient535288"> |
|
<stop |
|
id="stop535290" |
|
style="stop-color:#d7e3f4;stop-opacity:1" |
|
offset="0" /> |
|
<stop |
|
id="stop535292" |
|
style="stop-color:#535d6c;stop-opacity:1" |
|
offset="1" /> |
|
</linearGradient> |
|
<linearGradient |
|
id="linearGradient533400"> |
|
<stop |
|
id="stop533402" |
|
style="stop-color:#ffffff;stop-opacity:1" |
|
offset="0" /> |
|
<stop |
|
id="stop533404" |
|
style="stop-color:#373e48;stop-opacity:1" |
|
offset="1" /> |
|
</linearGradient> |
|
<linearGradient |
|
id="linearGradient531414"> |
|
<stop |
|
id="stop531416" |
|
style="stop-color:#ffcc00;stop-opacity:1" |
|
offset="0" /> |
|
<stop |
|
id="stop531418" |
|
style="stop-color:#ffcc00;stop-opacity:0" |
|
offset="1" /> |
|
</linearGradient> |
|
<linearGradient |
|
id="linearGradient528354"> |
|
<stop |
|
id="stop528356" |
|
style="stop-color:#ff6600;stop-opacity:1" |
|
offset="0" /> |
|
<stop |
|
id="stop528374" |
|
style="stop-color:#ffcc00;stop-opacity:1" |
|
offset="1" /> |
|
</linearGradient> |
|
<filter |
|
filterUnits="userSpaceOnUse" |
|
color-interpolation-filters="sRGB" |
|
id="Shadow"> |
|
<feGaussianBlur |
|
id="feGaussianBlur527394" |
|
stdDeviation="3.488" |
|
result="blur" |
|
in="SourceAlpha" /> |
|
<feOffset |
|
id="feOffset527396" |
|
dy="4" |
|
dx="0" |
|
result="offset" |
|
in="blur" /> |
|
<feFlood |
|
id="feFlood527398" |
|
result="flood" |
|
flood-opacity=".75" |
|
flood-color="black" /> |
|
<feComposite |
|
in2="offset" |
|
operator="in" |
|
in="flood" |
|
id="feComposite527400" /> |
|
</filter> |
|
<radialGradient |
|
cx="227.65974" |
|
cy="90.694878" |
|
r="30.940439" |
|
fx="227.65974" |
|
fy="90.694878" |
|
id="radialGradient533390" |
|
xlink:href="#linearGradient531414" |
|
gradientUnits="userSpaceOnUse" |
|
gradientTransform="matrix(-0.12422631,-0.377448,0.3891499,-0.09040866,231.51592,200.34014)" /> |
|
<linearGradient |
|
x1="228.59381" |
|
y1="121.61312" |
|
x2="234.2569" |
|
y2="105.58002" |
|
id="linearGradient533980" |
|
xlink:href="#linearGradient533400" |
|
gradientUnits="userSpaceOnUse" /> |
|
<linearGradient |
|
x1="220.85742" |
|
y1="109.04664" |
|
x2="228.58353" |
|
y2="99.513435" |
|
id="linearGradient537186" |
|
xlink:href="#linearGradient535288" |
|
gradientUnits="userSpaceOnUse" /> |
|
<linearGradient |
|
x1="228.59381" |
|
y1="121.61312" |
|
x2="234.2569" |
|
y2="105.58002" |
|
id="linearGradient537198" |
|
xlink:href="#linearGradient533400" |
|
gradientUnits="userSpaceOnUse" /> |
|
<linearGradient |
|
x1="220.85742" |
|
y1="109.04664" |
|
x2="228.58353" |
|
y2="99.513435" |
|
id="linearGradient537200" |
|
xlink:href="#linearGradient535288" |
|
gradientUnits="userSpaceOnUse" /> |
|
<radialGradient |
|
cx="312.42923" |
|
cy="84.296028" |
|
r="30.940439" |
|
fx="312.42923" |
|
fy="84.296028" |
|
id="radialGradient543762" |
|
xlink:href="#linearGradient541386" |
|
gradientUnits="userSpaceOnUse" |
|
gradientTransform="matrix(-1.1325633,-1.1757427,1.1480104,-0.7806073,487.79422,520.88536)" /> |
|
<linearGradient |
|
x1="228.59381" |
|
y1="121.61312" |
|
x2="234.2569" |
|
y2="105.58002" |
|
id="linearGradient543789" |
|
xlink:href="#linearGradient533400" |
|
gradientUnits="userSpaceOnUse" /> |
|
<linearGradient |
|
x1="220.85742" |
|
y1="109.04664" |
|
x2="228.58353" |
|
y2="99.513435" |
|
id="linearGradient543791" |
|
xlink:href="#linearGradient535288" |
|
gradientUnits="userSpaceOnUse" /> |
|
<radialGradient |
|
cx="312.42923" |
|
cy="84.296028" |
|
r="30.940439" |
|
fx="312.42923" |
|
fy="84.296028" |
|
id="radialGradient543793" |
|
xlink:href="#linearGradient541386" |
|
gradientUnits="userSpaceOnUse" |
|
gradientTransform="matrix(-1.1325633,-1.1757427,1.1480104,-0.7806073,487.79422,520.88536)" /> |
|
</defs> |
|
<g |
|
transform="translate(-111.69879,-51.677118)" |
|
id="g527402" |
|
style="fill:none;stroke:none"> |
|
<title |
|
id="title527404">Canvas 1</title> |
|
<g |
|
id="g527406"> |
|
<title |
|
id="title527408">Show me the viz</title> |
|
<g |
|
id="g527410"> |
|
<use |
|
id="use527412" |
|
style="filter:url(#Shadow)" |
|
x="0" |
|
y="0" |
|
width="576" |
|
height="733" |
|
xlink:href="#id11_Graphic" /> |
|
<use |
|
id="use527414" |
|
style="filter:url(#Shadow)" |
|
x="0" |
|
y="0" |
|
width="576" |
|
height="733" |
|
xlink:href="#id10_Graphic" /> |
|
</g> |
|
<g |
|
id="id11_Graphic"> |
|
<path |
|
d="m 184,277.3 0,-69.6 c 0,-4.8024 43.008,-8.7 96,-8.7 52.992,0 96,3.8976 96,8.7 l 0,69.6 c 0,4.8024 -43.008,8.7 -96,8.7 -52.992,0 -96,-3.8976 -96,-8.7" |
|
id="path527417" |
|
style="fill:#ffffff" /> |
|
<path |
|
d="m 184,277.3 0,-69.6 c 0,-4.8024 43.008,-8.7 96,-8.7 52.992,0 96,3.8976 96,8.7 l 0,69.6 c 0,4.8024 -43.008,8.7 -96,8.7 -52.992,0 -96,-3.8976 -96,-8.7 m 0,-69.6 c 0,4.8024 43.008,8.7 96,8.7 52.992,0 96,-3.8976 96,-8.7" |
|
id="path527419" |
|
style="stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round" /> |
|
</g> |
|
<g |
|
id="id10_Graphic"> |
|
<g |
|
transform="translate(-47.442006,-3.2413793)" |
|
id="g543764"> |
|
<path |
|
d="m 272.93887,100.3801 a 30.940439,22.83699 0 1 1 -61.88088,0 30.940439,22.83699 0 1 1 61.88088,0 z" |
|
transform="matrix(0.5713336,0,0,0.68001955,46.556279,13.947572)" |
|
id="path533396" |
|
style="fill:url(#linearGradient543789);fill-opacity:1;fill-rule:nonzero;stroke:none" /> |
|
<path |
|
d="m 272.93887,100.3801 a 30.940439,22.83699 0 1 1 -61.88088,0 30.940439,22.83699 0 1 1 61.88088,0 z" |
|
transform="matrix(0.5713336,0,0,0.68001955,46.556279,11.547572)" |
|
id="path533398" |
|
style="fill:url(#linearGradient543791);fill-opacity:1;fill-rule:nonzero;stroke:none" /> |
|
<path |
|
d="m 272.93887,100.3801 a 30.940439,22.83699 0 1 1 -61.88088,0 30.940439,22.83699 0 1 1 61.88088,0 z" |
|
transform="matrix(0.50952381,0,0,0.60645161,61.601991,19.092356)" |
|
id="path533394" |
|
style="fill:#d40000;fill-opacity:1;fill-rule:nonzero;stroke:none" /> |
|
<path |
|
d="m 272.93887,100.3801 a 30.940439,22.83699 0 1 1 -61.88088,0 30.940439,22.83699 0 1 1 61.88088,0 z" |
|
transform="matrix(0.50952381,0,0,0.60645161,61.601991,15.892356)" |
|
id="path527430" |
|
style="fill:#ff2a2a;fill-opacity:1;fill-rule:nonzero;stroke:none" /> |
|
<path |
|
d="m 272.93887,100.3801 a 30.940439,22.83699 0 1 1 -61.88088,0 30.940439,22.83699 0 1 1 61.88088,0 z" |
|
transform="matrix(0.50952381,0,0,0.60645161,61.601991,15.892356)" |
|
id="path541384" |
|
style="fill:url(#radialGradient543793);fill-opacity:1;fill-rule:nonzero;stroke:none" /> |
|
</g> |
|
</g> |
|
</g> |
|
</g> |
|
</svg></div> |
|
<div id="chart"> |
|
<script type="text/javascript"> |
|
|
|
var m = [60, 160, 20, 220], // top right bottom left |
|
w = 1280 - m[1] - m[3], // width |
|
h = 500 - m[0] - m[2], // height |
|
x = d3.scale.linear().range([0, w]), |
|
y = 35, // bar height |
|
z = d3.scale.ordinal().range(["#525252", "#aaa"]); // bar color |
|
|
|
var hierarchy = d3.layout.partition() |
|
.value(function(d) { return d.size; }); |
|
|
|
var xAxis = d3.svg.axis() |
|
.scale(x) |
|
.orient("top"); |
|
|
|
var svg = d3.select("body").append("svg:svg") |
|
.attr("width", w + m[1] + m[3]) |
|
.attr("height", h + m[0] + m[2]) |
|
.append("svg:g") |
|
.attr("transform", "translate(" + m[3] + "," + m[0] + ")"); |
|
|
|
svg.append("svg:rect") |
|
.attr("class", "background") |
|
.attr("width", w) |
|
.attr("height", h) |
|
.on("click", up); |
|
|
|
svg.append("svg:g") |
|
.attr("class", "x axis"); |
|
|
|
svg.append("svg:g") |
|
.attr("class", "y axis") |
|
.append("svg:line") |
|
.attr("y1", "100%"); |
|
|
|
|
|
d3.selectAll(".start").on("click", function() { |
|
|
|
d3.select("#path527430") |
|
.style("fill", "#CB181D") |
|
.transition().duration(750) |
|
.style("fill", "#ff2a2a"); |
|
|
|
d3.selectAll("#button") |
|
.transition().delay(750) |
|
.attr("opacity", 0); |
|
|
|
d3.select("#button-label") |
|
.transition().delay(750) |
|
.style("opacity", 0); |
|
|
|
d3.json("SSTIcostsFlareDummy.json", function(root) { |
|
hierarchy.nodes(root); |
|
x.domain([0, root.value]).nice(); |
|
down(root, 0); |
|
}); |
|
|
|
|
|
}); |
|
|
|
function down(d, i) { |
|
if (!d.children || this.__transition__) return; |
|
var duration = d3.event && d3.event.altKey ? 7500 : 750, |
|
delay = duration / d.children.length; |
|
|
|
// Mark any currently-displayed bars as exiting. |
|
var exit = svg.selectAll(".enter").attr("class", "exit"); |
|
|
|
// Entering nodes immediately obscure the clicked-on bar, so hide it. |
|
exit.selectAll("rect").filter(function(p) { return p === d; }) |
|
.style("fill-opacity", 1e-6); |
|
|
|
// Enter the new bars for the clicked-on data. |
|
// Per above, entering bars are immediately visible. |
|
var enter = bar(d) |
|
.attr("transform", stack(i)) |
|
.style("opacity", 1); |
|
|
|
// Have the text fade-in, even though the bars are visible. |
|
// Color the bars as parents; they will fade to children if appropriate. |
|
enter.select("text").style("fill-opacity", 1e-6); |
|
enter.select("rect").attr("class", function(d) { return d.name; }); |
|
//enter.select("rect").style("fill", z(true)); |
|
|
|
// Update the x-scale domain. |
|
x.domain([0, d3.max(d.children, function(d) { return d.value; })]).nice(); |
|
|
|
// Update the x-axis. |
|
svg.selectAll(".x.axis").transition() |
|
.duration(duration) |
|
.call(xAxis); |
|
|
|
// Transition entering bars to their new position. |
|
var enterTransition = enter.transition() |
|
.duration(duration) |
|
.delay(function(d, i) { return i * delay; }) |
|
.attr("transform", function(d, i) { return "translate(0," + y * i * 1.2 + ")"; }); |
|
|
|
// Transition entering text. |
|
enterTransition.select("text").style("fill-opacity", 1); |
|
|
|
// Transition entering rects to the new x-scale. |
|
enterTransition.select("rect") |
|
.attr("width", function(d) { return x(d.value); }); |
|
//.style("fill", function(d) { return z(!!d.children); }); |
|
|
|
// Transition exiting bars to fade out. |
|
var exitTransition = exit.transition() |
|
.duration(duration) |
|
.style("opacity", 1e-6) |
|
.remove(); |
|
|
|
// Transition exiting bars to the new x-scale. |
|
exitTransition.selectAll("rect").attr("width", function(d) { return x(d.value); }); |
|
|
|
// Rebind the current node to the background. |
|
svg.select(".background").data([d]).transition().duration(duration * 2); d.index = i; |
|
} |
|
|
|
function up(d) { |
|
if (!d.parent || this.__transition__) return; |
|
var duration = d3.event && d3.event.altKey ? 7500 : 750, |
|
delay = duration / d.children.length; |
|
|
|
// Mark any currently-displayed bars as exiting. |
|
var exit = svg.selectAll(".enter").attr("class", "exit"); |
|
|
|
// Enter the new bars for the clicked-on data's parent. |
|
var enter = bar(d.parent) |
|
.attr("transform", function(d, i) { return "translate(0," + y * i * 1.2 + ")"; }) |
|
.style("opacity", 1e-6); |
|
|
|
// Color the bars as appropriate. |
|
// Exiting nodes will obscure the parent bar, so hide it. |
|
enter.select("rect") |
|
//.style("fill", function(d) { return z(!!d.children); }) |
|
.attr("class", function(d) { return d.name; }) |
|
.filter(function(p) { return p === d; }) |
|
.style("fill-opacity", 1e-6); |
|
|
|
// Update the x-scale domain. |
|
x.domain([0, d3.max(d.parent.children, function(d) { return d.value; })]).nice(); |
|
|
|
// Update the x-axis. |
|
svg.selectAll(".x.axis").transition() |
|
.duration(duration * 2) |
|
.call(xAxis); |
|
|
|
// Transition entering bars to fade in over the full duration. |
|
var enterTransition = enter.transition() |
|
.duration(duration * 2) |
|
.style("opacity", 1); |
|
|
|
// Transition entering rects to the new x-scale. |
|
// When the entering parent rect is done, make it visible! |
|
enterTransition.select("rect") |
|
.attr("width", function(d) { return x(d.value); }) |
|
.each("end", function(p) { if (p === d) d3.select(this).style("fill-opacity", null); }); |
|
|
|
// Transition exiting bars to the parent's position. |
|
var exitTransition = exit.selectAll("g").transition() |
|
.duration(duration) |
|
.delay(function(d, i) { return i * delay; }) |
|
.attr("transform", stack(d.index)); |
|
|
|
// Transition exiting text to fade out. |
|
exitTransition.select("text") |
|
.style("fill-opacity", 1e-6); |
|
|
|
// Transition exiting rects to the new scale and fade to parent color. |
|
exitTransition.select("rect") |
|
.attr("width", function(d) { return x(d.value); }) |
|
.attr("class", function(d) { return d.parent.name; }); |
|
//.style("fill", z(true)); |
|
|
|
// Remove exiting nodes when the last child has finished transitioning. |
|
exit.transition().duration(duration * 2).remove(); |
|
|
|
// Rebind the current parent to the background. |
|
svg.select(".background").data([d.parent]).transition().duration(duration * 2); |
|
} |
|
|
|
// Creates a set of bars for the given data node, at the specified index. |
|
function bar(d) { |
|
var bar = svg.insert("svg:g", ".y.axis") |
|
.attr("class", "enter") |
|
.attr("transform", "translate(0,5)") |
|
.selectAll("g") |
|
.data(d.children) |
|
.enter().append("svg:g") |
|
.style("cursor", function(d) { return !d.children ? null : "pointer"; }) |
|
.on("click", down); |
|
|
|
/* |
|
bar.append("svg:text") |
|
.attr("x", function(d, i) { return (x(d.value) * 2.65 + i ); }) |
|
.attr("y", y / 2) |
|
.attr("dy", ".35em") |
|
.attr("text-anchor", "start") |
|
.attr("class", function(d) { return d.name; }) |
|
.text(function(d) { return d.value; }); |
|
*/ |
|
|
|
bar.append("svg:text") |
|
.attr("x", -6) |
|
.attr("y", y / 2) |
|
.attr("dy", ".35em") |
|
.attr("text-anchor", "end") |
|
.attr("class", function(d) { return d.name ; }) |
|
.text(function(d) { return d.name; }); |
|
|
|
bar.append("svg:rect") |
|
.attr("width", function(d) { return x(d.value); }) |
|
.attr("height", y) |
|
.attr("class", function(d) { return d.name; }); |
|
|
|
|
|
|
|
return bar; |
|
} |
|
|
|
// A stateful closure for stacking bars horizontally. |
|
function stack(i) { |
|
var x0 = 0; |
|
return function(d) { |
|
var tx = "translate(" + x0 + "," + y * i * 1.2 + ")"; |
|
x0 += x(d.value); |
|
return tx; |
|
}; |
|
} |
|
|
|
</script> |
|
</div> |
|
<div id="FTE-calc-note">* This data is for the purposes of an example, and is not real data |
|
<P> |
|
<B>HINT:</B> Click in the white space of the graph to drill back up |
|
<div id="author">BY SARA QUIGLEY</div> |
|
</div> |
|
</body> |
|
</html> |