Display Macro Chart
Display a Macronutrient chart using nutrients from PassioFoodItem and PassioRecipe.
Require victory-native
and react-native-svg
npm package to display the chart.
yarn install victory-native
yarn install react-native-svg
Example
Displaying the nutritional values for calories
, carbs
, proteins
, and fats
using the mockFood
data, which includes logged dates
for the respective food entries.
Retrieve mock data from this.
MockFoodObtain the utility function for fetching nutrition from the provided page.
Utils PassioNutrientMacrosNutrient
import React from 'react';
import { Text, View, ScrollView } from 'react-native';
import {
VictoryAxis,
VictoryBar,
VictoryChart,
VictoryLabel,
VictoryTheme,
} from 'victory-native';
import { useMacrosNutrients } from './useMacrosNutrients';
import {
mergeAndSumMacroChartData,
type NutrientsTypes,
} from '../../../utils/PassioNutrient';
// Color mapping for each nutrient type
const NutrientColors = {
calories: '#FF4D61',
fat: '#00D795',
protein: '#0899FF',
carbs: '#00D795',
};
const MacrosNutrient = () => {
// Fetch nutrient data using custom hook
const { passioIDAttributesData, macros } = useMacrosNutrients();
// Function to render individual nutrient chart
const renderNutrientChart = (item: NutrientsTypes) => (
<View key={item}>
{/* Nutrient type label */}
<Text style={{ marginVertical: 8, alignSelf: 'center' }}>{item}</Text>
{/* Victory Chart for the nutrient */}
<VictoryChart theme={VictoryTheme.material} height={200}>
{/* X-axis configuration */}
<VictoryAxis
style={{
ticks: { stroke: 'transparent' },
grid: { stroke: 'none' },
axis: { stroke: '#F7F7F7' },
tickLabels: { fill: '#333333', fontSize: 14 },
axisLabel: {},
}}
/>
{/* Y-axis configuration */}
<VictoryAxis
dependentAxis
fixLabelOverlap
style={{
ticks: { stroke: 'transparent' },
axis: { stroke: 'none' },
grid: { stroke: '#F7F7F7' },
axisLabel: { padding: 0 },
tickLabels: { fill: '#333333', fontSize: 14 },
}}
/>
{/* Victory Bar chart for the nutrient */}
<VictoryBar
cornerRadius={8}
labelComponent={
<VictoryLabel
text={({ datum }) => Math.round(datum.value)}
dy={-10}
/>
}
alignment="middle"
style={{
data: {
borderTop: 24,
width: 20,
fill: NutrientColors[item],
},
}}
data={mergeAndSumMacroChartData(
passioIDAttributesData.filter((data) => data.type === item)
)}
x={(d) => d.label}
y="value"
/>
</VictoryChart>
</View>
);
// Render the component
return (
<ScrollView>
<View>
{/* Iterate over nutrient types and render charts */}
{macros.map(renderNutrientChart)}
</View>
</ScrollView>
);
};
export default MacrosNutrient;
useMacrosNutrients
import { useEffect, useMemo, useState } from 'react';
import {
getNutrientsFromAttribute,
type NutrientsTypes,
} from '../../../utils/PassioNutrient';
import { PassioSDK } from '@passiolife/nutritionai-react-native-sdk-v2';
import { DateTime } from 'luxon';
import { mockFood } from './mockFood';
export interface MacroChartData {
label: string;
value: number;
type: NutrientsTypes;
}
export const useMacrosNutrients = () => {
// State to store nutrient data
const macros: NutrientsTypes[] = useMemo(() => {
return ['calories', 'carbs', 'fat', 'protein'];
}, []);
const [passioIDAttributesData, setPassioIDAttributesData] = useState<
MacroChartData[]
>([]);
// Effect to fetch and process nutrient data on component mount
useEffect(() => {
// Temporary array to store processed nutrient data
const data: MacroChartData[] = [];
async function fetchData() {
// Create a copy of mockFood array to avoid modifying the original
const copyFood = [...mockFood];
// Fetch attributes for each PassioID and process nutrient data
await Promise.all(
copyFood.map(async (foodLog) => {
// Get attributes for a PassioID using PassioSDK
const attribute = await PassioSDK.getAttributesForPassioID(
foodLog.passioID
);
// If attributes are available, process the nutrients
if (attribute) {
// Get nutrients from the attribute for specific nutrient types
getNutrientsFromAttribute(attribute, macros).forEach((item) => {
// Convert timestamp to a formatted date and add the nutrient data to the array
data.push({
label: DateTime.fromJSDate(
new Date(foodLog.eventTimestamp)
).toFormat('dd/MM'),
value: item.unitMass?.value ?? 0,
type: item.name,
});
});
}
})
);
// Update the state with the processed nutrient data
setPassioIDAttributesData(data);
}
// Call the fetchData function
fetchData();
}, [macros]); // Empty dependency array to ensure the effect runs only once on mount
// Return the macros constant and the processed nutrient data
return {
macros,
passioIDAttributesData,
};
};
Result
Last updated