D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
saadkhalid90
Full window
Github gist
Slopegraphs to show trends in indicators
<!DOCTYPE html> <meta name="robots" content="noindex"> <html> <head> <script src="https://d3js.org/d3.v4.min.js"></script> <meta charset="utf-8"> <title>Slope graph</title> <link href="https://fonts.googleapis.com/css?family=Lato:300,400" rel="stylesheet"> <style id="jsbin-css"> body { font-family: 'Lato', sans-serif; font-weight: 300; background-color: white; } .parent_label { font-weight: 400; } .PHSI_text, .PHSII_text { color: #424242; } </style> </head> <body> <div id = "vizContain"> <div id = "Title-and-Info"> <h3>Health Indicator Slopegraphs (Punjab Health Survey Round I and II)</h3> <p>The slopegraphs show trends in district wise value of key maternal and early childhood indicators from Punjab Health Survey. You can select an indicator from the input below. A positive and negative change of over 10 percent points is encoded by blue and red respectively. Data source: Bureau of Statistics, Punjab</p> </div> <div id = "select_box_div"> <select id = "indicators"> <option value = "Skilled Birth">Skilled Birth</option> <option value = "Institutional Delivery">Institutional Delivery</option> <option value = "Full Immunization">Full Immunization</option> <option value = "Skilled ANC Coverage">Skilled ANC Coverage</option> <option value = "PNC for newborn">PNC for newborn</option> <option value = "PNC for mothers">PNC for mothers</option> <option value = "NNT Protection">NNT Protection</option> </select> <div> </div> <script id="jsbin-javascript"> d3.csv('PHS_slopes.csv', function(slope_data){ var slope_data_sub = slope_data.filter(function(d){ return d.Indicator == 'Skilled Birth'; }) // appending phs1 and phs2 into an array PHS var PHSI = slope_data_sub.map(function(d){ return d.PHSI }); var PHSII = slope_data_sub.map(function(d){ return d.PHSII }); var PHS = PHSI.concat(PHSII); // getting min and max of PHS var min_PHS = d3.min(PHS); var max_PHS = d3.max(PHS); var opacity_text_lines = 0.275; var opacity_circles = 0.4; // setting the svg var height = 600 * 1.25, width = 550 * 1.25 + 20; var margins = { top: 25, bottom: 20, left: 45, right: 70 }; var extra_margins = { left: 50, right: 70 } var slope_graph_div = d3.select("body") //.select("div.vizContain") .append("div") .attr("id", "slope_graph_div"); // setting up the svg var svg = slope_graph_div.append("svg") .attr("height", height) .attr("width", width); height = height - margins.top - margins.bottom; width = width - margins.left - margins.right; // append a chart with margins chart = svg.append("g") .attr("height", height) .attr("width", width) .attr("transform", "translate(" + margins.left + ", " + margins.bottom +")"); // defining the scale yScale = d3.scaleLinear() .domain([min_PHS, max_PHS]) .range([ height - margins.bottom, margins.top ]); var x_line1 = margins.left + extra_margins.left; var x_line2 = chart.attr("width") - extra_margins.right; function border_lines(outer_margin, inner_margin, parent, label_1, label_2){ var x_line1 = outer_margin.left + inner_margin.left; var x_line2 = parent.attr("width") - inner_margin.right; parent.append("line") .attr("x1", x_line1) .attr("x2", x_line1) .attr("y1", yScale(min_PHS)) .attr("y2", yScale(max_PHS)) .style("stroke", "grey") .style("stroke-dasharray", 3) .classed("border_line", true); parent.append("line") .attr("x1", x_line2) .attr("x2", x_line2) .attr("y1", yScale(min_PHS)) .attr("y2", yScale(max_PHS)) .style("stroke", "grey") .style("stroke-dasharray", 3) .classed("border_line", true); parent.append('text') .text(label_1) .attr("x", x_line1) .attr("y", outer_margin.top/ 3) .style("text-anchor", "middle") //.style("font-family", "sans-serif") .style("font-size", "13px") .attr("class", "parent_label"); parent.append('text') .text(label_2) .attr("x", x_line2) .attr("y", outer_margin.top/ 3) .style("text-anchor", "middle") //.style("font-family", "sans-serif") .style("font-size", "13px") .attr("class", "parent_label"); } border_lines(margins, extra_margins, chart, "PHS Round I", "PHS Round II"); // defining a group for each trend chart.selectAll("g") .data(slope_data_sub) .enter() .append("g") .attr("class", function(d, i){ return d.District; }) chart.selectAll("g") .append("circle") .classed("circles_PHSI", "true") .attr("r", 2) .attr("cx", x_line1) .attr("cy", function(d, i){ return yScale(d.PHSI) }) .style("opacity", opacity_circles); chart.selectAll("g") .append("circle") .classed("circles_PHSII", "true") .attr("r", 2) .attr("cx", x_line2) .attr("cy", function(d, i){ return yScale(d.PHSII) }) .style("opacity", opacity_circles); chart.selectAll("g") .append("line") .classed("slope_lines", "true") //.attr("r", 2) .attr("x1", x_line1) .attr("y1", function(d, i){ return yScale(d.PHSI) }) .attr("x2", x_line2) .attr("y2", function(d, i){ return yScale(d.PHSII) }) .style("stroke", function(d, i){ return color_slope_lines(d.PHSII - d.PHSI) }) .style("opacity", opacity_text_lines) .style("stroke-width", 1.5); var text_padding = 5; // text for PHS I chart.selectAll("g") .append("text") .classed("PHSI_text", true) .text(function(d, i){ return d.District + ", " + d.PHSI; }) .attr("x", x_line1 - text_padding) .attr("y", function(d, i){ return yScale(d.PHSI); }) .style("font-size", 10) //.style("font-family", "sans-serif") .style("opacity", opacity_text_lines) .style("text-anchor", "end"); // text for PHS II chart.selectAll("g") .append("text") .classed("PHSII_text", true) .text(function(d, i){ return d.District + ", " + d.PHSII; }) .attr("x", x_line2 + text_padding) .attr("y", function(d, i){ return yScale(d.PHSII); }) .style("font-size", 10) //.style("font-family", "sans-serif") .style("opacity", opacity_text_lines) .style("text-anchor", "start"); chart.selectAll("g") .data(slope_data_sub) .exit() .remove(); chart.selectAll("g") .on("mouseover", function(d, i){ d3.select(this).selectAll("text") .style("font-size", "12px") .style("font-weight", 400); d3.select(this) .selectAll('*') .style("opacity", 1); }) chart.selectAll("g") .on("mouseout", function(d, i){ d3.select(this).selectAll("text") .style("font-size", "10px") .style("font-weight", 300); d3.select(this) .selectAll('circle') .style("opacity", opacity_circles); d3.select(this) .selectAll('line,text') .style("opacity", opacity_text_lines); }) // function to color the slope lines function color_slope_lines(difference){ if (difference >= 10){ return "blue"; } else if (difference <= - 10){ return "red"; } else { return "black"; } } function update_slope_graph(indicator_categ){ slope_data_sub = slope_data.filter(function(d, i){ return (d.Indicator == indicator_categ); }) // appending phs1 and phs2 into an array PHS var PHSI = slope_data_sub.map(function(d){ return d.PHSI }); var PHSII = slope_data_sub.map(function(d){ return d.PHSII }); var PHS = PHSI.concat(PHSII); // getting min and max of PHS var min_PHS = d3.min(PHS); var max_PHS = d3.max(PHS); yScale.domain([min_PHS, max_PHS]); var transition_duration = 1500; // defining a group for each trend chart.selectAll("g") .data(slope_data_sub); chart.selectAll(".circles_PHSI") .data(slope_data_sub); chart.selectAll(".circles_PHSII") .data(slope_data_sub); chart.selectAll(".slope_lines") .data(slope_data_sub); chart.selectAll(".PHSI_text") .data(slope_data_sub); chart.selectAll(".PHSII_text") .data(slope_data_sub); chart.selectAll(".circles_PHSI") .transition() .duration(transition_duration) .attr("cx", x_line1) .attr("cy", function(d, i){ return yScale(d.PHSI) }); chart.selectAll(".circles_PHSII") .transition() .duration(transition_duration) .attr("cx", x_line2) .attr("cy", function(d, i){ return yScale(d.PHSII) }); chart.selectAll(".slope_lines") .transition() .duration(transition_duration) //.attr("r", 2) .attr("x1", x_line1) .attr("y1", function(d, i){ return yScale(d.PHSI) }) .attr("x2", x_line2) .attr("y2", function(d, i){ return yScale(d.PHSII) }) .style("stroke", function(d, i){ return color_slope_lines(d.PHSII - d.PHSI) }); // .style("opacity", 0.2) // .style("stroke-width", 1.5); var text_padding = 5; // text for PHS I chart.selectAll(".PHSI_text") .transition() .duration(transition_duration) .attr("x", x_line1 - text_padding) .attr("y", function(d, i){ return yScale(d.PHSI); }) .text(function(d, i){ return d.District + ", " + d.PHSI; }); // text for PHS II chart.selectAll(".PHSII_text") .transition() .duration(transition_duration) .attr("x", x_line2 + text_padding) .attr("y", function(d, i){ return yScale(d.PHSII); }) .text(function(d, i){ return d.District + ", " + d.PHSII; }); chart.selectAll("g") .on("mouseover", function(d, i){ d3.select(this).selectAll("text") .style("font-size", "12px") .style("font-weight", 400); d3.select(this) .selectAll('*') .style("opacity", 1); }) chart.selectAll("g") .on("mouseout", function(d, i){ d3.select(this).selectAll("text") .style("font-size", "10px") .style("font-weight", 400); d3.select(this) .selectAll('circle') .style("opacity", opacity_circles); d3.select(this) .selectAll('line,text') .style("opacity", opacity_text_lines); }) } d3.select("#indicators").on("input", function() { update_slope_graph(this.value); }); }) </script> </body> </html>
Modified
http://d3js.org/d3.v4.min.js
to a secure url
https://d3js.org/d3.v4.min.js