Skip to content

Commit

Permalink
Merge pull request #67 from Datawheel/staging
Browse files Browse the repository at this point in the history
v0.10
  • Loading branch information
davelandry authored Jun 18, 2019
2 parents e8adeef + c3f6587 commit 01fd26a
Show file tree
Hide file tree
Showing 34 changed files with 774 additions and 467 deletions.
6 changes: 4 additions & 2 deletions app/components/Stat.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ export default class Stat extends Component {
<span className="stat-label-year"> {year}</span>
}
</dt>
<dd className={`stat-value title ${ value && value.length > 30 ? "font-sm" : "font-md" } ${ themeClass }`}>
{ value ? `${value} ` : null }
<dd className={`stat-value title ${ themeClass }`}>
{ value &&
<span className={`${typeof value === "string" && value.length < 30 ? "font-md" : "font-sm"}`}> {value} </span>
}
{ qualifier &&
<span className={`stat-value-qualifier ${
qualifier.length > 20 ? "font-xs" : "font-sm"
Expand Down
18 changes: 18 additions & 0 deletions app/d3plus.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,24 @@ export default {
fontMax: fontSizeLg
}
},
// sets all BarChart labels to "styles.white"
Bar: {
labelConfig: {
fontColor: styles.white
}
},
// sets all Pie chart labels to "styles.white"
Circle: {
labelConfig: {
fontColor: styles.white
}
},
// set all Treemap labels to "styles.white"
Rect: {
labelConfig: {
fontColor: styles.white
}
},
// line charts
Line: {
stroke: colorLogic,
Expand Down
16 changes: 11 additions & 5 deletions app/pages/Profile/Profile.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {Component} from "react";
import {connect} from "react-redux";
import {Helmet} from "react-helmet";
import {nest} from "d3-collection";
import {Icon} from "@blueprintjs/core";
import {fetchData, TopicTitle} from "@datawheel/canon-core";
import ProfileHeader from "./components/ProfileHeader";
Expand All @@ -10,7 +11,7 @@ import "./Profile.css";
import Introduction from "./sections/about/Introduction";
import FoodInsecurity from "./sections/foodAccess/FoodInsecurity";
import FoodAvailability from "./sections/foodAccess/FoodAvailability";
import FoodStamps from "./sections/foodAccess/FoodStamps";
import PublicFoodAssistance from "./sections/foodAccess/PublicFoodAssistance";
import StoreAccessByDemographic from "./sections/foodAccess/StoreAccessByDemographic";
import PreventiveCare from "./sections/healthBehaviors/PreventiveCare";
import RiskyBehaviors from "./sections/healthBehaviors/RiskyBehaviors";
Expand Down Expand Up @@ -120,7 +121,7 @@ class Profile extends Component {
<div className="section-container">
<FoodInsecurity />
<FoodAvailability />
<FoodStamps />
<PublicFoodAssistance />
<StoreAccessByDemographic />
</div>

Expand Down Expand Up @@ -177,7 +178,7 @@ class Profile extends Component {
<AirQuality />
</div>

<TopicTitle slug="special-population">
<TopicTitle slug="special-populations">
<div className="section-container">
<Icon iconName="people" />
Special Populations
Expand All @@ -201,7 +202,7 @@ class Profile extends Component {
Profile.need = [
Introduction,
FoodAvailability,
FoodStamps,
PublicFoodAssistance,
FoodInsecurity,
StoreAccessByDemographic,
CancerPrevalenceByDemographics,
Expand Down Expand Up @@ -245,7 +246,12 @@ Profile.need = [
fetchData("childrenTractIds", "/api/geo/children/<id>/?level=Tract"),
fetchData("childrenZipIds", "/api/geo/children/<id>/?level=Zip"),
fetchData("population", "https://acs.datausa.io/api/data?measures=Population&Geography=<id>&year=all"),
fetchData("currentLevelOverallCoverage", "/api/data?measures=Population by Insurance Coverage&drilldowns=Health Insurance Coverage Status&Geography=<id>&Year=latest", d => d.data)
fetchData("currentLevelOverallCoverage", "/api/data?measures=Population by Insurance Coverage&drilldowns=Health Insurance Coverage Status&Geography=<id>&Year=latest", d => d.data),
fetchData("sortedCancerTypes", "/api/data?measures=Cancer Diagnosis&drilldowns=Cancer Site&Year=all&order=Cancer Site&sort=asc", d => {
const cancerList = [];
nest().key(d => d["Cancer Site"]).entries(d.data).forEach(group => cancerList.push(group.key));
return cancerList;
})
];

const mapStateToProps = state => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {updateSource} from "utils/helper";
import SourceGroup from "components/SourceGroup";
import Options from "components/Options";

const formatRaceNames = d => d.replace("Health Center Patients", "");
const formatRaceNames = d => d.replace("Health Center Patients", "").trim();
const lowerCaseRaceName = d => d.trim() === "Black" || d.trim() === "White" ? d.toLowerCase() : d;
const formatPercentage = d => `${formatAbbreviate(d * 100)}%`;

Expand Down Expand Up @@ -66,8 +66,6 @@ class HealthCenterDemographics extends SectionColumns {
topZipLevelData = recentYearZipLevelData[0];
}

// const isHealthCentersSelected = dropdownValue === "Health Centers";

return (
<SectionColumns>
<SectionTitle>Health Center Demographics</SectionTitle>
Expand All @@ -92,13 +90,13 @@ class HealthCenterDemographics extends SectionColumns {
title={"Most common race utilizing health centers"}
year={`${topMostRaceData.Year}`}
value={formatRaceNames(topMostRaceData.RaceType)}
qualifier={`${formatPercentage(topMostRaceData[topMostRaceData.RaceType])} of the population in Wayne County`}
qualifier={`${formatPercentage(topMostRaceData[topMostRaceData.RaceType])} of the health center visiting population in Wayne County`}
/>

{isZipLevelDataAvailable ? <p>In {topZipLevelData.Year}, {lowerCaseRaceName(formatRaceNames(topZipLevelData.RaceType))} residents of {`zip ${topZipLevelData.Geography}`} visited health centers more than any other race/ethnicity group that utilizes services offered by health centers ({formatPercentage(topZipLevelData[topZipLevelData.RaceType])} of the health center population), as compared to the {lowerCaseRaceName(formatRaceNames(topMostRaceData.RaceType))} residents in Wayne County ({formatPercentage(topMostRaceData[topMostRaceData.RaceType])} of the health center population).</p>
: <p>In {topMostRaceData.Year}, {lowerCaseRaceName(formatRaceNames(topMostRaceData.RaceType))} residents of Wayne County visited health centers more than any other reported race/ethnicity group that utilizes services offered by health centers ({formatPercentage(topMostRaceData[topMostRaceData.RaceType])} of the health center population). This is followed by {lowerCaseRaceName(formatRaceNames(topSecondRaceData.RaceType))} residents ({formatPercentage(topSecondRaceData[topSecondRaceData.RaceType])}) and then {lowerCaseRaceName(formatRaceNames(topThirdRaceData.RaceType))} residents ({formatPercentage(topThirdRaceData[topThirdRaceData.RaceType])}).</p>}
{isZipLevelDataAvailable ? <p>In {topZipLevelData.Year}, {formatPercentage(topZipLevelData[topZipLevelData.RaceType])} of the health center visiting population in {`zip ${topZipLevelData.Geography}`} were {lowerCaseRaceName(formatRaceNames(topZipLevelData.RaceType))}, compared to {lowerCaseRaceName(formatRaceNames(topMostRaceData.RaceType))} residents in Wayne County ({formatPercentage(topMostRaceData[topMostRaceData.RaceType])}).</p>
: <p>In {topMostRaceData.Year}, {formatPercentage(topMostRaceData[topMostRaceData.RaceType])} of the health center visiting population in Wayne County were {lowerCaseRaceName(formatRaceNames(topMostRaceData.RaceType))}, followed by {lowerCaseRaceName(formatRaceNames(topSecondRaceData.RaceType))} ({formatPercentage(topSecondRaceData[topSecondRaceData.RaceType])}) and then {lowerCaseRaceName(formatRaceNames(topThirdRaceData.RaceType))} ({formatPercentage(topThirdRaceData[topThirdRaceData.RaceType])}).</p>}

<p> The following chart shows the health center visitors breakdown across all reported race/ethnicity groups in {isZipLevelDataAvailable ? topZipLevelData.Geography : "Wayne County"}.</p>
<p> The following chart shows the health center visitors breakdown across all reported racial groups in {isZipLevelDataAvailable ? topZipLevelData.Geography : "Wayne County"}.</p>

<SourceGroup sources={this.state.sources} />
<Contact slug={this.props.slug} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import rangeFormatter from "utils/rangeFormatter";
import places from "utils/places";
import Stat from "components/Stat";
import StatGroup from "components/StatGroup";
import CensusTractDefinition from "components/CensusTractDefinition";
import {updateSource} from "utils/helper";
import SourceGroup from "components/SourceGroup";
import Options from "components/Options";
Expand Down Expand Up @@ -91,9 +92,9 @@ const formatGeomapCoverageData = (data, meta, childrenTractIds) => {
};

const getGeomapTitle = meta => {
if (meta.level === "county") return "Most covered population within places in Wayne County";
else if (meta.level === "tract") return "Most covered population within census tracts in Wayne County";
else return `Most covered population within tracts in ${meta.name}`;
if (meta.level === "county") return "Most covered place in Wayne County";
else if (meta.level === "tract") return "Most covered census tract in Wayne County";
else return `Most covered census tract in ${meta.name}`;
};

const getGeomapQualifier = (data, meta) => {
Expand Down Expand Up @@ -184,7 +185,7 @@ class HealthInsuranceCoverage extends SectionColumns {
<Stat
title={getGeomapTitle(meta)}
year={topRecentYearChildrenGeographyData.Year}
value={formatGeomapLabel(topRecentYearChildrenGeographyData, meta, tractToPlace)}
value={meta.level === "place" || meta.level === "tract" ? <CensusTractDefinition text={formatGeomapLabel(topRecentYearChildrenGeographyData, meta, tractToPlace)} /> : formatGeomapLabel(topRecentYearChildrenGeographyData, meta, tractToPlace)}
qualifier={getGeomapQualifier(topRecentYearChildrenGeographyData, meta)}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ const formatGeomapLabel = (d, meta, tractToPlace) => {
};

const getGeomapTitle = meta => {
if (meta.level === "county") return "Highest median property value within places in Wayne County";
else if (meta.level === "tract") return "Highest median property value within census tracts in Wayne County";
else return `Highest median property value within tracts in ${meta.name}`;
if (meta.level === "county") return "Lowest median property value within places in Wayne County";
else if (meta.level === "tract") return "Lowest median property value within census tracts in Wayne County";
else return `Lowest median property value within tracts in ${meta.name}`;
};

const formatGeomapPropertyValueData = (data, meta, childrenTractIds) => {
Expand All @@ -55,7 +55,7 @@ const formatGeomapPropertyValueData = (data, meta, childrenTractIds) => {
if (childrenTractIds.includes(d["ID Geography"])) filteredChildrenGeography.push(d);
});
}
const topRecentYearData = filteredChildrenGeography.sort((a, b) => b["Property Value"] - a["Property Value"])[0];
const topRecentYearData = filteredChildrenGeography.sort((a, b) => a["Property Value"] - b["Property Value"])[0];
return [filteredChildrenGeography, topRecentYearData];
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Rentals extends SectionColumns {
/>
{/* Show stats for Renter-Occupied Housing Units with Extra Pay on Utilities for most recent year. */}
<Stat
title="Units with utilities included"
title="Units with utilities included in rent"
year={utilitiesDataAvailable ? utilitiesData[0].Year : ""}
value={utilitiesDataAvailable ? `${formatPercentage(recentYearNoExtraUtilitiesPercentage)}` : "N/A"}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ const definitions = [
{term: "Robbery", definition: "Robbery is the crime of taking or attempting to take anything of value by force, threat of force, or by putting the victim in fear."},
{term: "Rape", definition: "Rape is defined in most jurisdictions as sexual intercourse, or other forms of sexual penetration, committed by a perpetrator against a victim without their consent."},
{term: "Murder and Non-negligent Manslaughter", definition: "Murder and non-negligent manslaughter are described by UCR as the willful (non-negligent) killing of one human being by another or a death that results from the commission of another criminal act."},
{term: "Arson", definition: "Arson is the crime of willfully and maliciously burning of property (such as a building) especially with criminal or fraudulent intent."}
{term: "Arson", definition: "Arson is the crime of willfully and maliciously burning of property (such as a building) especially with criminal or fraudulent intent."},
{term: "Aggravated Assault", definition: "Aggravated assault is the crime of physically attacking another person which results in serious bodily harm and/or is made with a deadly or dangerous weapon such as a gun, knife, sword, ax or blunt instrument."}
];

class ViolentAndPropertyCrimes extends SectionColumns {
Expand Down
6 changes: 3 additions & 3 deletions app/pages/Profile/sections/economy/DistressScore.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class DistressScore extends SectionColumns {
value={topDistressScoreData.Zip}
qualifier={`(${formatAbbreviate(topDistressScoreData["Distress Score"])} percentile)`}
/>
<p>In {topDistressScoreData.Year}, the highest distress score was observed in the zip code {topDistressScoreData.Zip} ({formatAbbreviate(topDistressScoreData["Distress Score"])} percentile), 0 percentile would be the least distressed (desired outcome), and 100 percentile would be the most distressed (unfavorable outcome).</p>
<p>The following map shows the distress score percentile for each zip code in Wayne County.</p>
<p>In {topDistressScoreData.Year}, the highest distress score was observed in the zip code {topDistressScoreData.Zip} ({formatAbbreviate(topDistressScoreData["Distress Score"])}), 0 would be the least distressed (desired outcome), and 100 would be the most distressed (unfavorable outcome).</p>
<p>The following map shows the distress score for each zip code in Wayne County.</p>

<SourceGroup sources={this.state.sources} />
<Glossary definitions={definitions} />
Expand Down Expand Up @@ -95,7 +95,7 @@ class DistressScore extends SectionColumns {
},
height: 400,
time: "Year",
tooltipConfig: {tbody: [["Year", d => d.Year], ["Distress Score", d => `${formatAbbreviate(d["Distress Score"])} percentile`]]},
tooltipConfig: {tbody: [["Year", d => d.Year], ["Distress Score", d => `${formatAbbreviate(d["Distress Score"])}`]]},
topojson: "/topojson/zipcodes.json",
topojsonFilter: d => zipcodes.includes(d.properties.ZCTA5CE10),
topojsonId: d => d.properties.ZCTA5CE10
Expand Down
10 changes: 5 additions & 5 deletions app/pages/Profile/sections/economy/Poverty.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import SourceGroup from "components/SourceGroup";
import Options from "components/Options";

const definitions = [
{term: "Poverty", definition: "The Census Bureau uses a set of money income thresholds that vary by family size and composition to determine who is in poverty. If a family's total income is less than the family's threshold, then that family and every individual in it is considered in poverty. The official poverty thresholds do not vary geographically, but they are updated for inflation using Consumer Price Index (CPI-U). The official poverty definition uses money income before taxes and does not include capital gains or noncash benefits (such as public housing, Medicaid, and food stamps)."}
{term: "Poverty", definition: <p>The Census Bureau uses a set of <a href="https://www.census.gov/data/tables/time-series/demo/income-poverty/historical-poverty-thresholds.html">money income thresholds</a> that vary by family size and composition to determine who is in poverty. If a family's total income is less than the family's threshold, then that family and every individual in it is considered in poverty. The official poverty thresholds do not vary geographically, but they are updated for inflation using Consumer Price Index (CPI-U). The official poverty definition uses money income before taxes and does not include capital gains or noncash benefits (such as public housing, Medicaid, and food stamps).</p>}
];

const formatPopulation = d => `${formatAbbreviate(d)}%`;
Expand All @@ -39,14 +39,14 @@ const formatPovertyByRaceData = povertyByRace => {
};

const formatPovertyByAgeAndGender = povertyByAgeAndGender => {
const belowPovertyLevelByAgeAndGender = povertyByAgeAndGender.filter(d => d["ID Poverty Status"] === 0);
nest()
.key(d => d.Year)
.entries(povertyByAgeAndGender)
.entries(belowPovertyLevelByAgeAndGender)
.forEach(group => {
const total = sum(group.values, d => d["Poverty Population"]);
group.values.forEach(d => total !== 0 ? d.share = d["Poverty Population"] / total * 100 : d.share = 0);
});
const belowPovertyLevelByAgeAndGender = povertyByAgeAndGender.filter(d => d["ID Poverty Status"] === 0);
const topMalePovertyData = belowPovertyLevelByAgeAndGender.filter(d => d.Gender === "Male").sort((a, b) => b.share - a.share)[0];
const topFemalePovertyData = belowPovertyLevelByAgeAndGender.filter(d => d.Gender === "Female").sort((a, b) => b.share - a.share)[0];
return [belowPovertyLevelByAgeAndGender, topMalePovertyData, topFemalePovertyData];
Expand Down Expand Up @@ -157,8 +157,7 @@ class Poverty extends SectionColumns {
time: "Year",
title: d => `Population in Poverty by Race/Ethnicity in ${d[0].Geography}`,
xConfig: {
tickFormat: d => formatPopulation(d),
title: "Share"
tickFormat: d => formatPopulation(d)
},
tooltipConfig: {tbody: [["Year", d => d.Year], ["Share", d => formatPopulation(d.share)], [titleCase(meta.level), d => d.Geography]]}
}}
Expand All @@ -184,6 +183,7 @@ class Poverty extends SectionColumns {
{povertyByAgeAndGenderAvailable
? <BarChart ref={comp => this.viz2 = comp } config={{
data: `https://acs.datausa.io/api/data?measures=Poverty Population&drilldowns=Poverty Status,Age,Gender&Geography=${meta.id}&Year=all`,
stacked: true,
discrete: "x",
height: 400,
groupBy: "Gender",
Expand Down
10 changes: 5 additions & 5 deletions app/pages/Profile/sections/economy/Unemployment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ class Unemployment extends SectionColumns {
}
]}
/>
<p>
{workExperienceAvailable ? <span>In {getMaleFullTimeData[0].Year}, the gender breakdown of the working population in {getMaleFullTimeData[0].Geography} that worked full-time was {formatPercentage(getMaleFullTimeData[0].share)} for men and {formatPercentage(getFemaleFullTimeData[0].share)} for women.</span> : ""}
{employmentStatusAvailable ? <span> The most common unemployed age group for men was {getTopMaleUnemploymemtData.Age.toLowerCase()} ({formatPercentage(getTopMaleUnemploymemtData.share)}), and the most common female unemployed age group for women was {getTopFemaleUnemploymemtData.Age.toLowerCase()} ({formatPercentage(getTopFemaleUnemploymemtData.share)}).</span> : ""}
{} In {recentYearUnemploymentRate.Year}, the overall unemployment rate in {recentYearUnemploymentRate.Geography} was {formatPercentage(recentYearUnemploymentRate["Unemployment Rate"])}.
</p>

{workExperienceAvailable ? <p>In {getMaleFullTimeData[0].Year}, the gender breakdown of the working population in {getMaleFullTimeData[0].Geography} that worked full-time was {formatPercentage(getMaleFullTimeData[0].share)} for men and {formatPercentage(getFemaleFullTimeData[0].share)} for women.</p> : ""}

{employmentStatusAvailable ? <p>The most common unemployed age group for men was {getTopMaleUnemploymemtData.Age.toLowerCase()} ({formatPercentage(getTopMaleUnemploymemtData.share)}), and for women was {getTopFemaleUnemploymemtData.Age.toLowerCase()} ({formatPercentage(getTopFemaleUnemploymemtData.share)}).</p> : ""}
<p> In {recentYearUnemploymentRate.Year}, the overall unemployment rate in {recentYearUnemploymentRate.Geography} was {formatPercentage(recentYearUnemploymentRate["Unemployment Rate"])}.</p>

<SourceGroup sources={this.state.sources} />
<Contact slug={this.props.slug} />
Expand Down
Loading

0 comments on commit 01fd26a

Please sign in to comment.