var margin = {
top: 20,
right: 210,
bottom: 50,
left: 70
},
outerWidth = 1050,
outerHeight = 500,
width = outerWidth - margin.left - margin.right,
height = outerHeight - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]).nice();
var y = d3.scale.linear()
.range([height, 0]).nice();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickSize(-height);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickSize(-width);
var xCat = "age",
yCat = "Prob_Mortality",
rCat = "los_icu",
colorCat = "first_careunit";
var labels = {
"los_icu": "Length of stay in ICU",
"Prob_Mortality": "Probability",
"age": "Age"
}
d3.csv("icu_data.csv", function(data) {
data.forEach(function(d) {
d.Prob_Mortality = +d.Prob_Mortality;
d.icustay_id = +d.icustay_id;
d.age = +d.age;
d.los_icu = +d.los_icu;
d.hospital_expire_flag = +d.hospital_expire_flag;
d.first_careunit = d.first_careunit;
});
var xMax = d3.max(data, function(d) {
return d[xCat];
}) * 1.05,
xMin = d3.min(data, function(d) {
return d[xCat];
}),
xMin = xMin > 0 ? 0 : xMin,
yMax = d3.max(data, function(d) {
return d[yCat];
}) * 1.05,
yMin = d3.min(data, function(d) {
return d[yCat];
}),
yMin = yMin > 0 ? 0 : yMin;
x.domain([xMin, xMax]);
y.domain([yMin, yMax]);
var color = d3.scale.category10();
var tip = d3.tip()
.attr("class", "d3-tip")
.offset([-10, 0])
.html(function(d) {
return labels[xCat] + ": " + d[xCat] + "
" + labels[yCat] + ": " + d[yCat] + "
" + labels[rCat] + ": " + d[rCat];
});
var zoomBeh = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([0, 1000])
.on("zoom", zoom);
var svg = d3.select("#scatter")
.append("svg")
.attr("width", outerWidth)
.attr("height", outerHeight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoomBeh);
svg.call(tip);
svg.append("rect")
.attr("width", width)
.attr("height", height);
svg.append("g")
.classed("x axis", true)
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.classed("label", true)
.attr("x", width)
.attr("y", margin.bottom - 10)
.style("text-anchor", "end")
.text("Age");
svg.append("g")
.classed("y axis", true)
.call(yAxis)
.append("text")
.classed("label", true)
.attr("transform", "rotate(-90)")
.attr("y", -margin.left)
.attr("dy", "1.5em")
.style("text-anchor", "end")
.text("Probability of Mortality");
var objects = svg.append("svg")
.classed("objects", true)
.attr("width", width)
.attr("height", height);
objects.append("svg:line")
.classed("axisLine hAxisLine", true)
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", width)
.attr("y2", 0)
.attr("transform", "translate(0," + height + ")");
objects.append("svg:line")
.classed("axisLine vAxisLine", true)
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", 0)
.attr("y2", height);
objects.selectAll(".dot")
.data(data)
.enter().append("circle")
.classed("dot", true)
.attr({
r: function(d) {
return 4 * Math.sqrt(d[rCat] / Math.PI);
},
cx: function(d) {
return x(d[xCat]);
},
cy: function(d) {
return y(d[yCat]);
}
})
.style("fill", function(d) {
return color(d[colorCat]);
})
.on("mouseover", tip.show)
.on("mouseout", tip.hide);
var legend = svg.selectAll(".legend")
.data(color.domain())
.enter().append("g")
.classed("legend", true)
.attr("transform", function(d, i) {
return "translate(0," + i * 20 + ")";
});
legend.append("rect")
.attr("x", width + 10)
.attr("width", 12)
.attr("height", 12)
.style("fill", color);
legend.on("click", function(type) {
// dim all of the icons in legend
d3.selectAll(".legend")
.style("opacity", 0.1);
// make the one selected be un-dimmed
d3.select(this)
.style("opacity", 1);
// select all dots and apply 0 opacity (hide)
d3.selectAll(".dot")
// .transition()
// .duration(500)
.style("opacity", 0.0)
// filter out the ones we want to show and apply properties
.filter(function(d) {
return d["first_careunit"] == type;
})
.style("opacity", 1) // need this line to unhide dots
.style("stroke", "black")
// apply stroke rule
.style("fill", function(d) {
if (d.hospital_expire_flag == 1) {
return this
} else {
return "white"
};
});
});
legend.append("text")
.attr("x", width + 26)
.attr("dy", ".65em")
.text(function(d) {
return d;
});
d3.select("button.reset").on("click", change)
d3.select("button.changexlos").on("click", updateX)
function change() {
xMax = d3.max(data, function(d) {
return d[xCat];
});
xMin = d3.min(data, function(d) {
return d[xCat];
});
zoomBeh.x(x.domain([xMin, xMax])).y(y.domain([yMin, yMax]));
var svg = d3.select("#scatter").transition();
svg.select(".x.axis").duration(750).call(xAxis).select(".label").text(labels[xCat]);
objects.selectAll(".dot").transition().duration(1000)
.attr({
r: function(d) {
return 4 * Math.sqrt(d[rCat] / Math.PI);
},
cx: function(d) {
return x(d[xCat]);
},
cy: function(d) {
return y(d[yCat]);
}
})
}
function zoom() {
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
svg.selectAll(".dot")
.attr({
cx: function(d) {
return x(d[xCat]);
},
cy: function(d) {
return y(d[yCat]);
}
})
// .attr("transform", transform);
}
function transform(d) {
return "translate(" + x(d[xCat]) + "," + y(d[yCat]) + ")";
}
function updateX() {
xCat = "los_icu",
yCat = "Prob_Mortality",
rCat = "age",
colorCat = "first_careunit";
xMax = d3.max(data, function(d) {
return d[xCat];
}) * 1.05,
xMin = d3.min(data, function(d) {
return d[xCat];
}),
xMin = xMin > 0 ? 0 : xMin,
yMax = d3.max(data, function(d) {
return d[yCat];
}) * 1.05,
yMin = d3.min(data, function(d) {
return d[yCat];
}),
yMin = yMin > 0 ? 0 : yMin;
x.domain([xMin, xMax]);
y.domain([yMin, yMax]);
var zoomBeh = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([0, 1000])
.on("zoom", zoom);
var svg = d3.select("svg").transition();
svg.select(".y.axis")
.duration(1000)
.call(yAxis);
svg.select('.x.axis')
.duration(1000)
.call(xAxis);
svg.select('.label')
.duration(1000)
.attr("x", width)
.attr("y", margin.bottom - 10)
.style("text-anchor", "end")
.text("Length of Stay");
d3.selectAll("circle.dot")
.transition()
.duration(1000)
.attr({
r: function(d) {
return 4 * Math.sqrt(d[rCat] / Math.PI);
},
cx: function(d) {
return x(d[xCat]);
},
cy: function(d) {
return y(d[yCat]);
}
})
}
});