Using Measure Data
This guide explains the process of searching for measures, retrieving detailed data, fetching chart data and rendering the chart in a React component.
Searching for Measures
First, we need to search for specific measures related to our data. We use the MeasuresSearch GraphQL query to find measures that contain the keyword “Diet” in their name.
This query returns detailed information about each measure, such as its measureId
, name
, description
, format
, precision
, unitType
, and associated population
, subpopulations
and source
.
query MeasuresSearch {
measures_A(where: { name: { contains: "Diet" } }) {
measureId
name
description
format
precision
unitType
source {
name
}
}
}
Using the Playground, we can run the query and get the response:
{
"data": {
"measures_A": [
{
"measureId": "116",
"name": "Diet, Fruit and Vegetables",
"description": "Percentage of adults who reported that they consumed fruits and vegetables five or more times per day (pre-2011 BRFSS methodology)",
"format": "Percent",
"precision": 1,
"unitType": "Percentage of population",
"source": {
"name": "CDC, Behavioral Risk Factor Surveillance System"
}
}
]
}
}
Getting Measure Data
Once we have identified the measure of interest, we retrieve the detailed data for that measure using the GetMeasureData GraphQL query.
This query fetches specific data points for the measure, such as the dateLabel
, state
, rank
and value
.
query GetMeasureData {
measure_A(metricId: 116) {
name
description
format
precision
unitType
source {
name
}
data(where: { state: { in: ["NY"] } }) {
dateLabel
rank
state
value
}
}
}
Using the Playground, we can run the query and get the response:
{
"data": {
"measure_A": {
"name": "Diet, Fruit and Vegetables",
"description": "Percentage of adults who reported that they consumed fruits and vegetables five or more times per day (pre-2011 BRFSS methodology)",
"format": "Percent",
"precision": 1,
"unitType": "Percentage of population",
"source": {
"name": "CDC, Behavioral Risk Factor Surveillance System"
},
"data": [
{
"dateLabel": "1997",
"rank": 17,
"state": "NY",
"value": 25.4
},
{
"dateLabel": "2000",
"rank": 19,
"state": "NY",
"value": 25.5
}
]
}
}
}
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.
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.
import { fetchGraphqlClient } from "util/graphql";
export const fetchChartData = async () => {
return await fetchGraphqlClient<any>({
body: JSON.stringify({
query: `query GetFilteredMeasure {
measure_A(metricId: 116) {
measureId
name
description
format
precision
unitType
isWeightPositive
population {
name
}
source {
name
}
subpopulations {
name
}
data(where: { state: { in: ["NY"]}}) {
dateLabel
rank
state
value
dataNotes {
name
description
}
}
}
}`,
}),
});
};
Rendering the Chart
Finally, we use the fetched data to render a chart in our React component. The SampleLineChart component uses the useState and useEffect hooks to manage and fetch the data. We use the recharts
library to create a line chart, displaying the measure data over time.
npm install recharts
"use client";
import React, { useState, useEffect } from "react";
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Label,
} from "recharts";
import { fetchChartData } from "./fetch";
type ChartData = {
name: string;
description: string;
source: string;
unitType: string;
format: string;
data: {
year: string;
state: string;
percent: number;
rank: number;
}[];
};
const SampleLineChart = () => {
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 { data } = await fetchChartData();
const formattedData = {
name: data?.measure_A?.name,
description: data?.measure_A?.description,
source: data?.measure_A?.source.name,
unitType: data?.measure_A?.unitType,
format: data?.measure_A?.format,
data: (data?.measure_A?.data || []).map((i) => ({
year: i.dateLabel,
state: i.state,
percent: i.value,
rank: i.rank,
})),
};
setChartData(formattedData);
} catch (error) {
console.error(error);
setError("An error occurred while fetching the chart data.");
} finally {
setLoading(false);
}
};
getChartData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
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>Source: {chartData?.source}</cite>
</figcaption>
<ResponsiveContainer width="100%" height={400}>
<LineChart
data={chartData?.data}
margin={{ top: 30, right: 30, left: 30, bottom: 40 }}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="year"
interval={0}
angle={45}
dx={10}
dy={15}
allowDecimals={false}
>
<Label value="Year" position="bottom" dy={15} fill="#003C71" />
</XAxis>
<YAxis
tickFormatter={(tick) => `${tick}%`}
tickCount={10}
domain={[0, 100]}
>
<Label
value={chartData?.unitType}
angle={-90}
position="middle"
dx={-30}
fill="#003C71"
/>
</YAxis>
<Tooltip includeHidden label={"Toolip"} />
<Line name={"Rank"} unit=" of 50" dataKey="rank" hide={true} />
<Line
name={chartData?.format}
unit={"%"}
dataKey="percent"
stroke="#003C71"
activeDot={{ stroke: "white", strokeWidth: 3, r: 6 }}
strokeWidth={3}
/>
</LineChart>
</ResponsiveContainer>
</figure>
);
};
export default SampleLineChart;
"use client";
import React, { useState, useEffect } from "react";
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Label,
} from "recharts";
import { fetchChartData } from "./fetch";
type ChartData = {
name: string;
description: string;
source: string;
unitType: string;
format: string;
data: {
year: string;
state: string;
percent: number;
rank: number;
}[];
};
const SampleLineChart = () => {
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 { data } = await fetchChartData();
const formattedData = {
name: data?.measure_A?.name,
description: data?.measure_A?.description,
source: data?.measure_A?.source.name,
unitType: data?.measure_A?.unitType,
format: data?.measure_A?.format,
data: (data?.measure_A?.data || []).map((i) => ({
year: i.dateLabel,
state: i.state,
percent: i.value,
rank: i.rank,
})),
};
setChartData(formattedData);
} catch (error) {
console.error(error);
setError("An error occurred while fetching the chart data.");
} finally {
setLoading(false);
}
};
getChartData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
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>Source: {chartData?.source}</cite>
</figcaption>
<ResponsiveContainer width="100%" height={400}>
<LineChart
data={chartData?.data}
margin={{ top: 30, right: 30, left: 30, bottom: 40 }}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="year"
interval={0}
angle={45}
dx={10}
dy={15}
allowDecimals={false}
>
<Label value="Year" position="bottom" dy={15} fill="#003C71" />
</XAxis>
<YAxis
tickFormatter={(tick) => `${tick}%`}
tickCount={10}
domain={[0, 100]}
>
<Label
value={chartData?.unitType}
angle={-90}
position="middle"
dx={-30}
fill="#003C71"
/>
</YAxis>
<Tooltip includeHidden label={"Toolip"} />
<Line name={"Rank"} unit=" of 50" dataKey="rank" hide={true} />
<Line
name={chartData?.format}
unit={"%"}
dataKey="percent"
stroke="#003C71"
activeDot={{ stroke: "white", strokeWidth: 3, r: 6 }}
strokeWidth={3}
/>
</LineChart>
</ResponsiveContainer>
</figure>
);
};
export default SampleLineChart;
"use client";
import React, { useState, useEffect } from "react";
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
Label,
} from "recharts";
import { fetchChartData } from "./fetch";
type ChartData = {
name: string;
description: string;
source: string;
unitType: string;
format: string;
data: {
year: string;
state: string;
percent: number;
rank: number;
}[];
};
const SampleLineChart = () => {
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 { data } = await fetchChartData();
const formattedData = {
name: data?.measure_A?.name,
description: data?.measure_A?.description,
source: data?.measure_A?.source.name,
unitType: data?.measure_A?.unitType,
format: data?.measure_A?.format,
data: (data?.measure_A?.data || []).map((i) => ({
year: i.dateLabel,
state: i.state,
percent: i.value,
rank: i.rank,
})),
};
setChartData(formattedData);
} catch (error) {
console.error(error);
setError("An error occurred while fetching the chart data.");
} finally {
setLoading(false);
}
};
getChartData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
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>Source: {chartData?.source}</cite>
</figcaption>
<ResponsiveContainer width="100%" height={400}>
<LineChart
data={chartData?.data}
margin={{ top: 30, right: 30, left: 30, bottom: 40 }}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="year"
interval={0}
angle={45}
dx={10}
dy={15}
allowDecimals={false}
>
<Label value="Year" position="bottom" dy={15} fill="#003C71" />
</XAxis>
<YAxis
tickFormatter={(tick) => `${tick}%`}
tickCount={10}
domain={[0, 100]}
>
<Label
value={chartData?.unitType}
angle={-90}
position="middle"
dx={-30}
fill="#003C71"
/>
</YAxis>
<Tooltip includeHidden label={"Toolip"} />
<Line name={"Rank"} unit=" of 50" dataKey="rank" hide={true} />
<Line
name={chartData?.format}
unit={"%"}
dataKey="percent"
stroke="#003C71"
activeDot={{ stroke: "white", strokeWidth: 3, r: 6 }}
strokeWidth={3}
/>
</LineChart>
</ResponsiveContainer>
</figure>
);
};
export default SampleLineChart;