xxxxxxxxxx
<html>
<head>
<title>Technical Resource Costs by Application Function</title>
<script src='https://cdn.jsdelivr.net/npm/d3@2.10.3/d3.v2.js'></script>
<link rel="stylesheet" type="text/css" href="appCosts_stackDummy.css" />
</head>
<body>
<div id="header">Student IT Maintenance/Operations</div>
<div id="mini-pie">
<script type="text/javascript">
var h = 80,
w = 80,
r = Math.min(w, h) * .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", w )
.attr("height", h)
.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">The 90% all at once*</div>
<div id="button-div">
<text id="button-label" class="start">CONTINUE</text>
<svg
xmlns:dc="https://purl.org/dc/elements/1.1/"
xmlns:cc="https://creativecommons.org/ns#"
xmlns:rdf="https://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="https://www.w3.org/2000/svg"
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://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="https://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="FunctionPie">
<script type="text/javascript">
var w = 450,
h = 450,
r = Math.min(w, h) * .25,
labelr = r + 10, // radius for label anchor
donut = d3.layout.pie().sort(null),
arc = d3.svg.arc().innerRadius(r / 1.75).outerRadius(r)
mode = 'numClasses';
// .data([data])
var data = [{"name": "Admissions","tco": 4087603,"class": "Admissions", "percent": 13 },
{"name": "GroupMgmt","tco": 445964,"class": "GroupMgmt", "percent": 1 },
{"name": "Events","tco": 3381524,"class": "Events", "percent": 11 },
{"name": "Conduct","tco": 473696,"class": "Conduct", "percent": 1 },
{"name": "FinancialAid","tco": 11074147,"class": "FinancialAid", "percent": 35 },
{"name": "Financials","tco": 256803,"class": "Financials", "percent": 1 },
{"name": "Reg/Enrollment","tco": 11029674,"class": "RegEnrollment", "percent": 35 },
{"name": "Acad Planning","tco": 939370,"class": "AcadPlanning", "percent": 3 },
];
var qFormat = d3.format(",");
var vis = d3.select("body").append("svg:svg")
.attr("class", "FunctionPie")
.attr("width", w )
.attr("height", h)
.data([data]);
var arcs = vis.selectAll("g")
.data(donut.value(function(d) { return d.percent }))
.enter().append("svg:g")
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")")
.attr("class", function(d, i) { return data[i].class ;})
.append("svg:path")
.attr("d", arc)
.each(function(d) { this._current = d; });
var percentLabels = vis.selectAll("g")
.append("svg:text")
.attr("fill", "white")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.text(function(d, i) { return d.value + "%"; })
.attr("text-anchor", "middle")
.attr("display", function(d) { return d.value > 3 ? null : "none"; })
.attr("class", "percentLabel");
var labels = vis.selectAll("g")
.append("svg:text")
.attr("transform", function(d) {
var c = arc.centroid(d),
x = c[0],
y = c[1],
// pythagorean theorem for hypotenuse
h = Math.sqrt(x*x + y*y);
return "translate(" + (x/h * labelr ) + ',' +
(y/h * labelr) + ")rotate(" + angle(d) + ")" ;
})
.attr("dy", "1.5em")
.attr("text-anchor", function(d) {
// are we past the center?
return (d.endAngle + d.startAngle)/2 > Math.PI ?
"end" : "start";
})
.text(function(d, i) { return qFormat(d.data.tco); })
.attr("class", function(d, i) { return data[i].class ;});
vis.selectAll("g").append("svg:text")
.attr("transform", function(d) {
var c = arc.centroid(d),
x = c[0],
y = c[1],
// pythagorean theorem for hypotenuse
h = Math.sqrt(x*x + y*y);
return "translate(" + (x/h * labelr) + ',' +
(y/h * labelr) + ")rotate(" + angle(d) + ")" ;
})
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
// are we past the center?
return (d.endAngle + d.startAngle)/2 > Math.PI ?
"end" : "start";
})
.text(function(d, i) { return data[i].name; })
.attr("class", function(d, i) { return data[i].class ;});
//add the total amount in the center
vis.append("svg:text")
.attr("fill", "white")
.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.transition().delay(4000).duration(3000)
.attr("fill", "#525252")
.text("$" + qFormat(31.6) + "MM")
.attr("class", "totalLabel");
// 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="chart">
<script type="text/javascript">
var w = 500,
h = 680,
m = [0, 40, 70, 694], //margin top, right, bottom, left
z = d3.scale.ordinal().range(["", "projectCosts", "swCosts"]);
d3.json("appCostsDummy.json", function(data) {
var y = d3.scale.ordinal()
.domain([data.length])
.rangeBands([0, h]);
var x = d3.scale.linear()
.domain([0, d3.max(data.map(function(d) {return parseInt(d.tco);}))])
.range([0, w - m[1]]);
// Transpose the data into layers by cost.
stack = d3.layout.stack()(["resourceCosts", "projectCosts", "swCosts"].map(function(cost) {
return data.map(function(d, i) {
return {x: d.name, y: +d[cost], class: cost};
});
}));
var qFormat = d3.format(",");
// add the resource support costs
var chart = d3.select("body").append("svg")
.attr("class", "chart")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] +m[2]);
// Add a group for each app.
var costs = chart.selectAll("g.costs")
.data(stack)
.enter().append("svg:g")
.attr("class", function(d, i) { return z(i); });
d3.selectAll(".start").on("click", function() {
// hide the start button
d3.select("#path527430")
.style("fill", "#CB181D")
.transition().duration(750)
.style("fill", "#ff2a2a");
d3.selectAll("#button")
.transition().delay(1000)
.attr("opacity", 0);
d3.select("#button-label")
.transition().delay(250)
.style("opacity", 0);
// Add a rect for each member of the series.
var rect = costs.selectAll("rect")
.data(Object)
.enter().append("svg:rect")
.attr("opacity", 100)
.attr("x", m[3])
.attr("y", m[0])
.attr("height", (y.rangeBand()/data.length) -1)
.attr("transform", function (d, i) { return "translate(" + x(d.y0) + "," + (y.rangeBand() / data.length * i) + ")"; })
.attr("class", function (d, i) { return (d.class == "resourceCosts" ? data[i].class : "") ; })
.transition().delay(1000).duration(2000).attr("width", function (d) { return x(d.y); });
//add y-axis labels
chart.selectAll(".deptLabel")
.data(data)
.enter().append("svg:text")
.attr("x",0)
.attr("y", m[0])
.attr("class", function(d) { return d.class ;})
.attr("text-anchor", "end")
.attr("vertical-align", "top")
.attr("dy", ".5em")
.attr("transform", function(d,i) { return ("translate(" + (m[3] - 5) + "," + ((y.rangeBand() / data.length * i) + (y.rangeBand() / data.length / 2.5)) + ")");})
.transition().delay(1000)
.text(function(d) { return d.name ;});
// Add x-axis rules.
var xRule = chart.selectAll("g.rule")
.data(x.ticks(6))
.enter().append("svg:g")
.attr("class", "rule")
.attr("transform", function(d) { return "translate(" + (m[3] + x(d)) + ",0)"; });
xRule.append("svg:line")
.attr("y2", h + m[3])
.style("stroke", "#fff")
.style("stroke-opacity", function(d) { return d ? .7 : null; });
xRule.append("svg:text")
.attr("y", m[0] - 10)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text(d3.format(",d.tco"));
//add total cost labels
chart.selectAll(".enrollCountLabel")
.data(data)
.enter().append("svg:text")
.attr("x", m[3])
.attr("y", m[0])
.attr("class", function(d) { return d.class })
.attr("text-anchor", "start")
.attr("vertical-align", "middle")
.attr("dy", ".52em")
.attr("transform", function(d,i) { return ("translate(" + (x(d.tco + m[3]) + 10) + "," + ((y.rangeBand() / data.length * i) + (y.rangeBand() / data.length / 2.5)) + ")");})
.transition().delay(1000)
.text(function(d) { return qFormat(d.tco);});
//show the legend for the stacked bars
d3.select("#svg_leg")
.transition().delay(2000).duration(2000).attr("opacity", 100);
});
});
</script>
</div>
<div id="legendTitle">
<script type="text/javascript">
var w_leg = 400,
h_leg = 50,
p_leg = [5, 0, 0, 20],
data_leg = [{"x":0, "y":64, "y0":0, "name":"Operational Resources"}, {"x":0, "y":50, "y0":64, "name":"Project Resources"}, {"x":0, "y":46, "y0":114, "name":"SW Licensing**"}],
color_leg = ["#7570B3", "#525252", "#FFED6F"],
labelColor_leg = ["#FFFFFF", "#FFFFFF", "#525252"];
var x_leg = d3.scale.linear()
.domain([0, 170])
.range([0, w_leg]);
// Visualisation selection
var svg_leg = d3.select("#legendTitle").append("svg:svg")
.attr("width", w_leg)
.attr("height", h_leg)
.attr("opacity", 0)
.attr("id", "svg_leg")
.append("svg:g");
// Add a rect for each member of the series.
var rect_leg = svg_leg.selectAll("rect")
.data(data_leg)
.enter().append("svg:rect")
.attr("x", 0)
.attr("y", 5)
.attr("width", function (d) { return x_leg(d.y); })
.attr("height", 15)
.attr("transform", function (d, i) { return "translate(" + x_leg(d.y0) + ")"; })
.style("fill", function (d, i) { return color_leg[i]; })
.style("fill-opacity", "1");
svg_leg.selectAll(".legendLabel")
.data(data_leg)
.enter().append("svg:text")
.attr("x",0)
.attr("y", 17)
.attr("class", "legendLabel")
.attr("text-anchor", "start")
.attr("vertical-align", "middle")
.text(function(d) { return d.name ;})
.style("fill", function (d, i) { return labelColor_leg[i]; })
.attr("transform", function(d,i) { return "translate(" + x_leg((d.y0) + 5) + ")" ; });
</script>
</div>
<div id="FTE-calc-note">
* This data is for the purposes of an example, and is not real data
<P>
<div id="author">BY SARA QUIGLEY</div>
</div>
</body>
</html>
Modified http://mbostock.github.com/d3/d3.v2.js to a secure url
https://mbostock.github.com/d3/d3.v2.js