Created
August 3, 2016 19:24
-
-
Save jsanch/0f0ad4ea1a916eef191a2d98cd1899c1 to your computer and use it in GitHub Desktop.
code used in https://cdc-nchs.demo.socrata.com/nhis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link rel="stylesheet" href="https://marks.github.io/cdc-indicator-explorer/css/nhis-early-release.css"> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> | |
<link href="https://pingendo.github.io/pingendo-bootstrap/themes/default/bootstrap.css" rel="stylesheet" type="text/css"> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" type="text/css"> | |
<!-- base dependencies (bootstrap, font-awesome) --> | |
<!-- visualization dependencies (plotly) --> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"></script> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script> | |
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
<script type="text/javascript" src="https://cdn.rawgit.com/socrata/soda-js/master/lib/soda-js.bundle.js"></script> | |
<div class="section" style='padding-top:0px;'> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-md-12"> | |
<div class="page-header" style="margin-top:20px"> | |
<h1 style="margin-top:0px;">NHIS Early Release Explorer <small>alpha</small></h1></div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-md-3"> | |
<div class="well"> | |
<form id="form" role="form"> | |
<div class="form-group"> | |
<label for="topicDropdown">Select a topic:</label> | |
<select class="form-control" id="topicDropdown"> | |
<option>Serious psychological distress</option> | |
<option selected>Diagnosed diabetes </option> | |
<option>Asthma</option> | |
</select> | |
</div> | |
<button type="submit" class="btn btn-default for-accessibility">Submit</button> | |
</form> | |
</div> | |
<div class=""> | |
<hr /> | |
<h2>About this tool</h2> | |
<p>This tool uses the <a href='https://cdc-nchs.demo.socrata.com/dataset/KHI-Combined-Data-Figures-14-1-14-2-14-3-/y73x-njsu' target='blank'>NHIS</a> dataset from <code>cdc-nchs.demo. socrata.com</code>. Visit the dataset page to explore the data in your browser, create custom visualizations, and export the data as CSV, JSON, XML, and/or access it via API. | |
<br /><br /> | |
<p><strong>Data URL</strong></p> | |
<code id="query-url"></code> | |
<br /><br /> | |
<p><strong>Built With</strong></p> | |
<p>This tool uses open source technology and the Socrata open data platform. The following components of the tool are licensed under the <a href='https://en.wikipedia.org/wiki/MIT_License'>MIT license</a>: Twitter Bootstrap, jQuery, Font Awesome, Lodash, soda-js.</p> | |
</div> | |
</div> | |
<div class="col-md-9"> | |
<div class="row"> | |
<div class="col-md-12"> | |
<h2 id='visualizations-header'>Loading...</h2> | |
</div> | |
</div> | |
<div class="row"> | |
<div id="visualizations"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- <script src="https://marks.github.io/cdc-indicator-explorer/js/nhis-early-release.js"></script> --> | |
<script> | |
$(document).ready(function() { | |
/* do these things when ready() */ | |
sodaConsumer = new soda.Consumer('cdc-nchs.demo.socrata.com'); | |
processInput() // run visualization on load | |
/* event handlers */ | |
$("#form select").change(function(event) { | |
event.preventDefault(); | |
formSubmitted() | |
}); | |
$("#form").submit(function(event) { // needed for accessibility reasons | |
event.preventDefault(); | |
formSubmitted() | |
}); | |
}); | |
/* helper methods */ | |
function formSubmitted(){ | |
$("#visualizations").html("") | |
processInput() | |
} | |
function processInput() { | |
params = { | |
topic: $("#form #topicDropdown").val(), | |
} | |
// set header text | |
$("h2#visualizations-header").text(params.topic) | |
// get data from socrata API | |
var sodaQuery = sodaConsumer.query() | |
.withDataset('xt9n-yu9c') | |
.where({ | |
'topic': params.topic, | |
}) | |
.select('*') | |
.order('figure_id asc, metric asc, gender desc, year asc') | |
// .where('locationabbr IN ("US","' + params.state + '")') | |
// .where('year IS NOT NULL') | |
var queryURL = decodeURIComponent(sodaQuery.getURL()) | |
$("code#query-url").text(queryURL) | |
sodaQuery | |
.getRows() | |
.on('success', handleData) | |
.on('error', function(error) { | |
console.error(error); | |
}); | |
} | |
function handleData(rows) { | |
console.log(rows) | |
/* for each figure, create a chart */ | |
var rowsGroupedByFigure = _.groupBy(rows,'figure_id') | |
_.each(rowsGroupedByFigure, function(rowsForFigure,figureId){ | |
var figure = rowsForFigure[0].figure | |
var figureType = figureId.split(".")[1] | |
var figureSlug = slugify(figureId+"--"+figure) | |
/* ------------------------------------------------------------------------ */ | |
var trendChartHTML = plotlyVisualizationPanelTemplate({ | |
slug:figureSlug, | |
title:"<small>Figure "+figureId+"</small><br />"+figure, | |
css_class:"chart", | |
caption:"<strong>Cras justo odio:</strong> Dapibus ac facilisis in, egestas eget quam. Donec id elit non mi porta gravida at eget metus. Nullam id dolor id nibh ultricies vehicula ut id elit." | |
}) | |
$("#visualizations").append(trendChartHTML) | |
console.log(rowsForFigure) | |
var plotlyLayout = { | |
barmode: 'group', | |
yaxis: {title: undefined}, | |
xaxis: {title: undefined}, | |
bargap:0.2, | |
bargroupgap:0.05 | |
} | |
if(figureType == "1") { | |
var data = _.map(_.groupBy(rowsForFigure, 'metric'), function(rowsForChart, metric){ | |
return { | |
x: _.map(rowsForChart,'year'), | |
y: _.map(rowsForChart,'value'), | |
name: metric, | |
marker: { | |
color: seriesNameToColor(metric) | |
}, | |
error_y: { | |
type: 'data', | |
symmetric: false, | |
array: _.map(rowsForChart, function(i){return parseFloat(i.confidence_interval_upper_bound) - parseFloat(i.value)}), | |
arrayminus: _.map(rowsForChart, function(i){return parseFloat(i.value)-parseFloat(i.confidence_interval_lower_bound)}), | |
visible: true | |
}, | |
type: 'bar', | |
} | |
}) | |
plotlyLayout.yaxis.title = "Percent" | |
plotlyLayout.xaxis.title = "Year" | |
// accordion revealing data table | |
var rowsByYear = _.groupBy(rowsForFigure, 'year') | |
var accordionAndTableHtml = datatableByYearAccordionTemplate({rowsByYear: rowsByYear}) | |
$("."+figureSlug+" .data-table").html(accordionAndTableHtml) | |
} else if(figureType == "2") { | |
var data = _.map(_.groupBy(rowsForFigure, 'gender'), function(rowsForChart, metric){ | |
return { | |
x: _.map(rowsForChart,'age_group'), | |
y: _.map(rowsForChart,'value'), | |
name: metric, | |
marker: { | |
color: seriesNameToColor(metric) | |
}, | |
error_y: { | |
type: 'data', | |
symmetric: false, | |
array: _.map(rowsForChart, function(i){return parseFloat(i.confidence_interval_upper_bound) - parseFloat(i.value)}), | |
arrayminus: _.map(rowsForChart, function(i){return parseFloat(i.value)-parseFloat(i.confidence_interval_lower_bound)}), | |
visible: true | |
}, | |
type: 'bar', | |
} | |
}) | |
plotlyLayout.yaxis.title = "Percent" | |
plotlyLayout.xaxis.title = "Age Group (years)" | |
} else if(figureType == "3") { | |
var data = _.map(_.groupBy(rowsForFigure, 'metric'), function(rowsForChart, metric){ | |
return { | |
x: _.map(rowsForChart,'race_ethnicity'), | |
y: _.map(rowsForChart,'value'), | |
name: metric, | |
marker: { | |
color: seriesNameToColor(metric) | |
}, | |
error_y: { | |
type: 'data', | |
symmetric: false, | |
array: _.map(rowsForChart, function(i){return parseFloat(i.confidence_interval_upper_bound) - parseFloat(i.value)}), | |
arrayminus: _.map(rowsForChart, function(i){return parseFloat(i.value)-parseFloat(i.confidence_interval_lower_bound)}), | |
visible: true | |
}, | |
type: 'bar', | |
} | |
}) | |
plotlyLayout.yaxis.title = "Percent" | |
plotlyLayout.xaxis.title = "Race/Ethnicity" | |
} else { | |
var data = [] | |
} | |
Plotly.newPlot(figureSlug, data, plotlyLayout, {displaylogo: false, displayModeBar: false}); | |
}) | |
} | |
var plotlyVisualizationPanelTemplate = _.template('<div class="col-md-12 <%= slug %>"> \ | |
<div class="panel panel-default"> \ | |
<div class="panel-body"> \ | |
<h3><%= title %></h3> \ | |
<div class="<%= css_class %>" id="<%= slug %>"></div> \ | |
<div class="data-table"></div> \ | |
<p><%= caption %></p> \ | |
</div>\ | |
</div> \ | |
</div>') | |
var datatableByYearAccordionTemplate = _.template(' \ | |
<div class="panel-group"> \ | |
<div class="panel panel-default"> \ | |
<div class="panel-heading"> \ | |
<h4 class="panel-title"> \ | |
<a data-toggle="collapse" href="#collapse1">View Data Table</a> \ | |
</h4> \ | |
</div> \ | |
<div id="collapse1" class="panel-collapse collapse"> \ | |
<div class="panel-body"> \ | |
<table> \ | |
<tr> \ | |
<th class="tg-031e">Year</th> \ | |
<th class="tg-s6z2">Crude[1] percent<br>(95% confidence interval)</th> \ | |
<th class="tg-s6z2">Age-adjusted[2] percent<br>(95% confidence interval)</th> \ | |
</tr> \ | |
<% _.each(rowsByYear, function(metricsForYear, year){ %> \ | |
<tr><td class="tg-031e"><%= year %></td> \ | |
<% _.each(metricsForYear, function(row){ %> \ | |
<td class="tg-s6z2"><%= rowToValueWithInterval(row) %></td> \ | |
<% }) %> \ | |
</tr> \ | |
<% }) %> \ | |
</table> \ | |
</div> \ | |
<div class="panel-footer">Data Source: CDC/NCHS, National Health Interview Survey</div> \ | |
</div> \ | |
</div> \ | |
</div>') | |
function seriesNameToColor(name) { | |
switch(name) { | |
case "Crude[1] percent": | |
return "#69318f" | |
case "Age-adjusted[2] percent": | |
return "#609639" | |
case "Total": | |
return "#609639" | |
case "Male": | |
return "#a388bc" | |
case "Female": | |
return "#69318f" | |
default: | |
return "#a388bc" | |
} | |
} | |
function rowToValueWithInterval(row){ | |
return row.value+" ("+row.confidence_interval_lower_bound+"-"+row.confidence_interval_upper_bound+")" | |
} | |
function slugify(text){ | |
return text.toString().toLowerCase() | |
.replace(/\s+/g, '-') // Replace spaces with - | |
.replace(/[^\w\-]+/g, '') // Remove all non-word chars | |
.replace(/\-\-+/g, '-') // Replace multiple - with single - | |
.replace(/^-+/, '') // Trim - from start of text | |
.replace(/-+$/, ''); // Trim - from end of text | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment