|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<head> |
|
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> |
|
<script type="text/javascript" src="superformula.js"></script> |
|
<script type="text/javascript" src="bulletQ.js"></script> |
|
<script type="text/javascript" src="strategy_space_config.js"></script> |
|
<title>Strategy Spaces</title> |
|
<link type="text/css" rel="stylesheet" href="strategy_space.css"/> |
|
</head> |
|
<body> |
|
|
|
<script type="text/javascript">// voronoi path for strategy space |
|
var dispatch = d3.dispatch("load", "statechange"); |
|
|
|
var selectedSquare; |
|
var defaultSquare = 5; |
|
|
|
|
|
var voro_width = 220, |
|
voro_height = 220, |
|
bounds = d3.geom.polygon([[.5, .5], [.5, voro_height - .5], [voro_width - .5, voro_height - .5], [voro_width - .5, .5]]), |
|
color = d3.scale.category10(), |
|
p0 = [voro_width / 8, voro_width / 8], |
|
p1 = [(voro_width / 8) * 3, voro_width / 8], |
|
p2 = [(voro_width / 8) * 5, voro_width / 8], |
|
p3 = [(voro_width / 8) * 7, voro_width / 8], |
|
p4 = [voro_width / 8, (voro_width / 8) * 3], |
|
p5 = [(voro_width / 8) * 3, (voro_width / 8) * 3], |
|
p6 = [(voro_width / 8) * 5, (voro_width / 8) * 3], |
|
p7 = [(voro_width / 8) * 7, (voro_width / 8) * 3], |
|
p8 = [voro_width / 8, (voro_width / 8) * 5], |
|
p9 = [(voro_width / 8) * 3, (voro_width / 8) * 5], |
|
p10 = [(voro_width / 8) * 5, (voro_width / 8) * 5], |
|
p11 = [(voro_width / 8) * 7, (voro_width / 8) * 5], |
|
p12 = [voro_width / 8, (voro_width / 8) * 7], |
|
p13 = [(voro_width / 8) * 3, (voro_width / 8) * 7], |
|
p14 = [(voro_width / 8) * 5, (voro_width / 8) * 7], |
|
p15 = [(voro_width / 8) * 7, (voro_width / 8) * 7]; |
|
|
|
var voronoi = d3.select("body").selectAll("svg") |
|
.data([ |
|
[p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15] // squares |
|
]) |
|
.enter().append("svg") |
|
.attr("width", voro_width) |
|
.attr("height", voro_height) |
|
.attr("class", "voronoi"); |
|
|
|
var g = voronoi.selectAll("g") |
|
.data(function(points) { return points; }) |
|
.enter().append("g") |
|
.style("fill", "#ccc") |
|
.style("fill-opacity", 0); |
|
|
|
g.append("path") |
|
.data(function(points) { return d3.geom.voronoi(points).map(clip); }) |
|
.attr("class", "voronoi") |
|
.style("fill", "#e6e6e6") |
|
.attr("id",function(d, i) { return i; }) |
|
.property("value", "") |
|
.attr("d", function(polygon) { return "M" + polygon.join("L") + "Z"; }); |
|
|
|
g.append("circle") |
|
.attr("r", 5) |
|
.attr("class", "voronoi") |
|
.attr("transform", function(point) { return "translate(" + point + ")"; }); |
|
|
|
d3.selectAll("path.voronoi").filter(function(d, i) { return i = d.id ? this : null; }) |
|
.style('fill', d3.rgb(31, 120, 180)); |
|
|
|
d3.selectAll("circle.voronoi").filter(function(d, i) { return i == defaultSquare ; }) |
|
.style("fill", "#f6b23d") |
|
.style("fill-opacity", 1); |
|
|
|
function clip(polygon) { |
|
return bounds.clip(polygon); |
|
} |
|
|
|
g.selectAll("path") |
|
.on("mouseover", function(d, i) { |
|
d3.select(this) |
|
.style('fill', d3.rgb(31, 120, 180)); |
|
voronoi.select('circle#point-'+i) |
|
.style('fill', d3.rgb(31, 120, 180)) |
|
}) |
|
.on("mouseout", function(d, i) { |
|
d3.select(this) |
|
.style("fill", d3.rgb(230, 230, 230)); |
|
voronoi.select('circle#point-'+i) |
|
.style('fill', 'black') |
|
}) |
|
.on("click", function(d, i) { |
|
//d3.selectAll("path.voronoi").property("value", ""); |
|
d3.selectAll("circle.voronoi") |
|
.style("fill-opacity", 0); |
|
|
|
d3.selectAll("circle.voronoi").filter(function(d, i) { return i == defaultSquare ; }) |
|
.style("fill", "#fff") |
|
.style("fill-opacity", .85); |
|
|
|
d3.select(this) |
|
.style("fill", d3.rgb(31, 120, 180)); |
|
|
|
d3.select(this.nextSibling) |
|
.transition() //use default duration |
|
.style("fill-opacity", 1) |
|
.style("fill", "#f6b23d"); // yellow |
|
selectedSquare = this.id; |
|
dispatch.statechange(this.id); |
|
voronoi.select('circle#point-'+i) |
|
.style('fill', 'black') |
|
}); |
|
|
|
dispatch.on("statechange.slCaWorld", function(square) { |
|
|
|
update(square); |
|
|
|
}); |
|
|
|
|
|
function update(dilemmaPosition) { |
|
|
|
d3.json("ss_lever.json", function(data) { |
|
|
|
var outcomes = d3.selectAll(".lever") |
|
.data(data[dilemmaPosition].bullets) |
|
.transition() |
|
.ease("cubic-in-out") |
|
.delay(500) |
|
.duration(4000) |
|
.call(chart); |
|
}); |
|
|
|
d3.json("ss_implication.json", function(data) { |
|
|
|
var outcomes = d3.selectAll(".bulletGroup") |
|
.data(data[dilemmaPosition].bullets) |
|
.transition() |
|
.ease("cubic-in-out") |
|
.delay(2000) |
|
.duration(3500) |
|
.attr("transform", "translate(" + mO[3] + "," + mO[0] + ")") |
|
.call(outcomeChart); |
|
}); |
|
|
|
|
|
} |
|
|
|
function updateLevers(d, slider) { |
|
d.ranges = d.ranges; |
|
d.markers = d.markers; |
|
d.measures = d.measures.map(function(d) { return leverData[selectedSquare][d.index] ;}) |
|
return d; |
|
} |
|
</script> <!-- // voronoi --> |
|
<script type="text/javascript"> |
|
|
|
var format = d3.format(".4n"), |
|
scale = d3.scale.linear().domain([-10, 20, 1000]).range([0, 800, 1000]); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", 800) |
|
.attr("height", 600) |
|
.attr("class", "pathContainer"); |
|
|
|
var shape = d3.superformula() |
|
.type("quigleyDiamond") |
|
.size(75000) |
|
.segments(3600); |
|
|
|
var path = svg.append("path") |
|
.attr("class", "diamond") |
|
.attr("transform", "translate(300,300)") |
|
.attr("d", shape);; |
|
|
|
svg.append("radialGradient") |
|
.attr("id", "radial-gradient") |
|
.attr("gradientUnits", "userSpaceOnUse") |
|
.attr("cx", 0) |
|
.attr("cy", 0) |
|
.attr("r", 250) |
|
.selectAll("stop") |
|
.data([ |
|
{offset: "10%", color: "rgb(116, 169, 207)"}, // same as the action measures |
|
{offset: "95%", color: "rgb(240, 240, 240)"} |
|
]) |
|
.enter().append("stop") |
|
.attr("offset", function(d) { return d.offset; }) |
|
.attr("stop-color", function(d) { return d.color; }); |
|
|
|
var labelData = [ |
|
{ |
|
"title": "Choice A", |
|
"x": 300, |
|
"y": 140, |
|
"color": "rgb(37, 52, 148)" |
|
}, |
|
{ |
|
"title": "Choice D", |
|
"x": 520, |
|
"y": 304, |
|
"color": "" |
|
}, |
|
{ |
|
"title": "Choice B", |
|
"x": 300, |
|
"y": 474, |
|
"color": "rgb(37, 52, 148)" |
|
}, |
|
{ |
|
"title": "Choice C", |
|
"x": 85, |
|
"y": 304, |
|
"color": "" |
|
} |
|
]; |
|
|
|
|
|
// this needs to be refactored so that text elements are bound to labelData |
|
svg.append("text") |
|
.attr("class", "diamond-label") |
|
.attr("transform", "translate(" + labelData[0].x +"," + labelData[0].y + ")") |
|
.style("text-anchor", "middle") |
|
.text(labelData[0].title); |
|
|
|
svg.append("text") |
|
.attr("class", "diamond-label") |
|
.attr("transform", "translate(" + labelData[1].x +"," + labelData[1].y + ")") |
|
.style("text-anchor", "middle") |
|
.text(labelData[1].title); |
|
|
|
svg.append("text") |
|
.attr("class", "diamond-label") |
|
.attr("transform", "translate(" + labelData[2].x +"," + labelData[2].y + ")") |
|
.style("text-anchor", "middle") |
|
.text(labelData[2].title); |
|
|
|
svg.append("text") |
|
.attr("class", "diamond-label") |
|
.attr("transform", "translate(" + labelData[3].x +"," + labelData[3].y + ")") |
|
.style("text-anchor", "middle") |
|
.text(labelData[3].title); |
|
|
|
// actions |
|
|
|
var chart = bulletChart() |
|
.width(w - m[1] - m[3]) |
|
.height(h - m[0] - m[2]); |
|
|
|
d3.json("ss_lever.json", function(data) { |
|
|
|
var vis = d3.select("#chart").selectAll("svg") |
|
.data(data[defaultSquare].bullets) |
|
.enter().append("svg") |
|
.attr("class", "lever") |
|
.attr("id", function(d) {return d.id ;}) |
|
.attr("width", w) |
|
.attr("height", h) |
|
.append("g") |
|
.attr("transform", "translate(" + m[3] + "," + m[0] + ")") |
|
.call(chart); |
|
|
|
var title = vis.append("g") |
|
.attr("text-anchor", "end") |
|
.attr("transform", "translate(-6," + (h - m[0] - m[2]) / 2 + ")"); |
|
|
|
title.append("text") |
|
.attr("class", "title") |
|
.text(function(d) { return d.title; }); |
|
|
|
title.append("text") |
|
.attr("class", "subtitle") |
|
.attr("dy", "1.25em") |
|
.text(function(d) { return d.subtitle; }); |
|
|
|
chart.duration(1000); |
|
|
|
}); |
|
|
|
|
|
// implications |
|
|
|
var outcomeChart = bulletChart() |
|
.width(wO - mO[1] - mO[3]) |
|
.height(hO - mO[0] - mO[2]); |
|
|
|
|
|
|
|
d3.json("ss_implication.json", function(data) { |
|
// default is 10 |
|
var vis = d3.select("#implications").selectAll("svg") |
|
.data(data[defaultSquare].bullets) |
|
.enter().append("svg") |
|
.attr("class", "implication") |
|
.attr("id", function(d) {return d.id ;}) |
|
.attr("width", wO) |
|
.attr("height", hO) |
|
.append("g") |
|
.attr("class", "bulletGroup") |
|
.attr("transform", "translate(" + mO[3] + "," + mO[0] + ")") |
|
.call(outcomeChart); |
|
|
|
var title = vis.append("g") |
|
.attr("text-anchor", "end") |
|
.attr("transform", "translate(-6," + (hO - mO[0] - mO[2]) / 2 + ")"); |
|
|
|
title.append("text") |
|
.attr("class", "title") |
|
.text(function(d) { return d.title; }); |
|
|
|
title.append("text") |
|
.attr("class", "subtitle") |
|
.attr("dy", "1.25em") |
|
.text(function(d) { return d.subtitle; }); |
|
|
|
outcomeChart.duration(1000); |
|
|
|
}); |
|
|
|
</script> |
|
|
|
|
|
<div></div> |
|
<div id="header">Strategy Spaces: |
|
<span id="sub-header">Crossing pairs of dilemma choices</span></div> |
|
<div id="diamond"></div> |
|
<div id="voronoi"></div> |
|
<div id="chart"></div> |
|
<div id="implications"></div> |
|
</body> |
|
</html> |