Skip to Content
API DocumentationGuidesUse Measure Data from a Specific Report (Grouped by Population)

Using Measure Data from a Specific Report (Grouped by Population)

This guide explains the process of searching for reports and their measures, fetching desired data and rendering the chart in a React component.

Searching for Reports

First, we need find the Report we’d like to use. Let’s use the GetReports GraphQL query to list all Reports grouped by Report Type.

query GetReports { reportTypes_A { reportTypeId name reports(order: { releaseDate: DESC }) { reportId name releaseDate } } }

Using the Playground, we can run the query and get the response:

{ "data": { "reportTypes_A": [ { "reportTypeId": 1, "name": "Annual", "reports": [ { "reportId": 276, "name": "2023 Annual", "releaseDate": 2023 } ] }, { "reportTypeId": 2, "name": "Senior", "reports": [ { "reportId": 277, "name": "2024 Senior", "releaseDate": 2024 } ] }, { "reportTypeId": 3, "name": "HWC", "reports": [ { "reportId": 275, "name": "2023 HWC", "releaseDate": 2023 } ] } ] } }

The data.reportTypes_A and data.reportTypes_A.reports array has been truncated for brevity. The actual response contains more data points.

Getting Report Measures

Once we’ve identified the Report of interest, we retrieve all Report Measure data for that Report using the GetReportMeasures GraphQL query.

Measure data is nested within reportMeasures with a new field called endDate. This is the date that measure data will be filtered by to only use data from the specified Report.

query GetReportMeasures { report_A(editionId: 276) { reportId name releaseDate reportMeasures { endDate measure { measureId name description unitType format } } } }

Using the Playground, we can run the query and get the response:

{ "data": { "report_A": { "reportId": 276, "name": "2023 Annual", "releaseDate": 2023, "reportMeasures": [ { "endDate": "2022-01-01T00:00:00.000Z", "measure": { "measureId": "147", "name": "Air Pollution", "description": "Average exposure of the general public to particulate matter of 2.5 microns or less, measured in micrograms per cubic meter", "unitType": "Micrograms of fine particles per cubic meter", "format": "Numeric" } }, { "endDate": "2022-01-01T00:00:00.000Z", "measure": { "measureId": "171", "name": "Smoking", "description": "Percentage of adults who reported smoking at least 100 cigarettes in their lifetime and currently smoke daily or some days", "unitType": "Percentage of adults", "format": "Percent" } }, { "endDate": "2022-01-01T00:00:00.000Z", "measure": { "measureId": "173", "name": "Obesity", "description": "Percentage of adults who have a body mass index of 30.0 or higher based on reported height and weight ", "unitType": "Percentage of adults", "format": "Percent" } } ] } } }

The data.report_A.reportMeasures array has been truncated for brevity. The actual response contains more data points.

Getting Measure Population Data

Once we have identified the measure of interest, we retrieve the detailed data for that measure using the GetMeasurePopulationData GraphQL query.

Instead of fetching all data points, we’re getting grouped data points for each population at the national level (state = “ALL”).

Note that the datum endDate is included to compare against the Report Measure endDate from the previous step.

query GetMeasurePopulationData { measure_A(metricId: 171) { measureId name description unitType format source { name } subpopulations { name population { name populationCategory { name } } data(where: { state: { in: ["ALL"] } }) { endDate dateLabel value } } } }

Using the Playground, we can run the query and get the response:

{ "data": { "measure_A": { "measureId": "171", "name": "Smoking", "description": "Percentage of adults who reported smoking at least 100 cigarettes in their lifetime and currently smoke daily or some days", "unitType": "Percentage of adults", "format": "Percent", "source": { "name": "CDC, Behavioral Risk Factor Surveillance System" }, "subpopulations": [ { "name": "Smoking - College Grad", "population": { "name": "College Grad", "populationCategory": { "name": "Education" } }, "data": [ { "endDate": "2012-01-01T00:00:00.000Z", "dateLabel": "2012", "value": 7.8 }, { "endDate": "2013-01-01T00:00:00.000Z", "dateLabel": "2013", "value": 7.6 } ] } ] } } }

The data.measure_A.data array has been truncated for brevity. The actual response contains more data points.

Setting up GraphQL Data Fetching

We create a utility function to fetch data from the GraphQL API. This function sends a GraphQL query to the API and returns the response.

util/graphql.ts
export type GraphQLResponse<T> = { data?: T; errors?: { message: string }[]; }; export const fetchGraphqlClient = async <T>({ method = "POST", body, }: RequestInit): Promise<GraphQLResponse<T>> => { const headers: HeadersInit = { "Content-Type": "application/json", "X-Api-Key": process.env.AHR_API_KEY }; const response = await fetch("https://api.americashealthrankings.org/graphql", { method, headers, body, }).then((data) => data.json()); return response as GraphQLResponse<T>; };

Fetching Chart Data

We then create a utility function fetchChartData to fetch the measure data using a GraphQL client. This function sends a GraphQL query to get the filtered measure data and returns the response.

fetch.ts
import { fetchGraphqlClient } from "util/graphql"; export const fetchChartData = async () => { return await fetchGraphqlClient<any>({ body: JSON.stringify({ query: `query GetMeasurePopulationData { measure_A(metricId: 171) { measureId name description unitType format source { name } subpopulations { name population { name populationCategory { name } } data(where: { state: { in: ["ALL"]}}) { endDate dateLabel value } } } }`, }), }); };

Rendering the Chart

Finally, we use the fetched data to render a list of all available Population Categories and a mixed chart in our React component. The DynamicLineBarChart component uses the useState and useEffect hooks to manage and fetch the data. We use the recharts library to create a mixed chart, displaying the Population data based on the selected Population Category.

npm install recharts
DynamicLineBarChart.tsx
"use client"; import React, { useEffect, useState } from "react"; import { fetchChartData } from "./fetch"; import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell, Label, } from "recharts"; type ChartData = { name: string; description: string; source: string; year: string; unitType: string; format: string; data: { [key: string]: { population: string; percent: number; yearData: { year: string; value: number; }[]; }[]; }; }; const colors = [ "#003C71", "#0075CF", "#5DAFF6", "#98CCFF", "#008A99", "#63C7C9", "#FF612B", "#FFCC61", "#999999", ]; const reportMeasureEndDate = "2023-01-01T00:00:00.000Z"; const DynamicLineBarChart = () => { const [populationCategory, setPopulationCategory] = useState<string>("Education"); const [chartData, setChartData] = useState<ChartData | null>(null); const [loading, setLoading] = useState<boolean>(true); const [error, setError] = useState<string | null>(null); useEffect(() => { const getChartData = async () => { try { const measure = await fetchChartData().then( (res) => res.data?.measure_A, ); const data = {}; let dateLabel = ""; measure.subpopulations.forEach((subpopulation) => { const populationCategory = subpopulation?.population?.populationCategory?.name; if (!data[populationCategory]) { data[populationCategory] = []; } const reportMeasureData = subpopulation?.data.find((datum) => { return datum.endDate === reportMeasureEndDate; }); const yearData = subpopulation?.data.map((datum) => ({ year: datum.dateLabel, value: datum.value, })); if (!!reportMeasureData) { data[populationCategory].push({ population: subpopulation?.population?.name, percent: reportMeasureData?.value, yearData, }); if (!dateLabel) { dateLabel = reportMeasureData?.dateLabel; } } }); const formattedData = { name: measure?.name, description: measure?.description, source: measure?.source.name, year: dateLabel, unitType: measure?.unitType, format: measure?.format, data, }; setChartData(formattedData); } catch (error) { console.error(error); setError("An error occurred while fetching the chart data."); } finally { setLoading(false); } }; getChartData(); }, []); const renderPopulationCategories = () => { return Object.keys(chartData?.data || {}).map((pg, i) => { return ( <p key={`population-category-${i}`} onClick={() => { setPopulationCategory(pg); }} className={`${pg === populationCategory ? "nx-border-primary-500" : "nx-cursor-pointer"} nx-border nx-rounded-lg nx-p-2`} style={{ borderWidth: pg === populationCategory ? "2px" : "1px", }} > {pg} </p> ); }); }; if (loading) { return <div>Loading...</div>; } if (error) { return <div>Error: {error}</div>; } const processLineChartData = () => { if (!chartData?.data[populationCategory]) return []; const yearMap = {}; chartData.data[populationCategory].forEach((item) => { item.yearData.forEach((yearItem) => { if (!yearMap[yearItem.year]) { yearMap[yearItem.year] = { year: yearItem.year, }; } yearMap[yearItem.year][item.population] = yearItem.value; }); }); return Object.values(yearMap); }; return ( <figure> <figcaption className="nx-mt-2 nx-mb-2"> <hgroup> <h3 className="nx-text-2xl nx-font-bold">{chartData?.name}</h3> <h4 className="nx-text-md">{chartData?.description}</h4> </hgroup> <cite> America's Health Rankings analysis of {chartData?.source}, United Health Foundation, AmericasHealthRankings.org, accessed{" "} {chartData?.year}. </cite> </figcaption> <div className="nx-flex nx-flex-row nx-gap-1 nx-items-center nx-flex-wrap"> {renderPopulationCategories()} </div> <div className="nx-flex nx-flex-row nx-w-full nx-py-4"> <ResponsiveContainer width="100%" height={400}> <LineChart data={processLineChartData()} margin={{ top: 0, right: 10, left: 0, bottom: 20 }} > <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="year"> <Label value="Data Year" position="middle" fill="#003C71" dy={20} /> </XAxis> <YAxis unit={"%"}> <Label value={`${chartData?.unitType}${["Income", "Education"].includes(populationCategory) ? " age 25+" : ""}`} angle={-90} position="middle" dx={-20} fill="#003C71" /> </YAxis> <Tooltip /> {chartData?.data[populationCategory].map((item, index) => ( <Line unit={"%"} key={item.population} type="monotone" dataKey={item.population} stroke={colors[index % colors.length]} strokeWidth={2} /> ))} </LineChart> </ResponsiveContainer> <ResponsiveContainer width="100%" height={400}> <BarChart layout="vertical" data={chartData?.data[populationCategory]} margin={{ top: 0, right: 0, left: 50, bottom: 20 }} > <CartesianGrid strokeDasharray="3 3" /> <XAxis type="number" unit={"%"}> <Label value={`${chartData?.unitType}${["Income", "Education"].includes(populationCategory) ? " age 25+" : ""}`} position="middle" fill="#003C71" dy={20} /> </XAxis> <YAxis type="category" dataKey="population" width={90} /> <Tooltip /> <Bar dataKey="percent" fill="#1490ff" unit={"%"}> {chartData?.data[populationCategory].map((_, index) => ( <Cell key={`cell-${index}`} fill={colors[index % colors.length]} /> ))} </Bar> </BarChart> </ResponsiveContainer> </div> </figure> ); }; export default DynamicLineBarChart;

Chart Component

Loading...