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]); } }) } });