Source code for usda_fdc.analysis.visualization

"""
Visualization utilities for nutrient analysis.
"""

from typing import Dict, List, Any, Optional

from .analysis import NutrientAnalysis

[docs]def generate_macronutrient_chart_data(analysis: NutrientAnalysis) -> Dict[str, Any]: """ Generate data for a macronutrient distribution chart. Args: analysis: The nutrient analysis. Returns: A dictionary with chart data. """ return { "type": "pie", "data": { "labels": ["Protein", "Carbohydrates", "Fat"], "datasets": [{ "data": [ analysis.macronutrient_distribution.get("protein", 0), analysis.macronutrient_distribution.get("carbs", 0), analysis.macronutrient_distribution.get("fat", 0) ], "backgroundColor": [ "#FF6384", "#36A2EB", "#FFCE56" ] }] }, "options": { "title": { "display": True, "text": "Macronutrient Distribution" } } }
[docs]def generate_dri_chart_data(analysis: NutrientAnalysis) -> Dict[str, Any]: """ Generate data for a DRI comparison chart. Args: analysis: The nutrient analysis. Returns: A dictionary with chart data. """ # Collect nutrients with DRI values nutrients_with_dri = [ (nutrient_id, value) for nutrient_id, value in analysis.nutrients.items() if value.dri_percent is not None ] # Sort by DRI percentage nutrients_with_dri.sort(key=lambda x: x[1].dri_percent or 0, reverse=True) # Take top 10 top_nutrients = nutrients_with_dri[:10] return { "type": "horizontalBar", "data": { "labels": [value.nutrient.name for _, value in top_nutrients], "datasets": [{ "label": "% of DRI", "data": [value.dri_percent for _, value in top_nutrients], "backgroundColor": "#36A2EB" }] }, "options": { "title": { "display": True, "text": "Nutrient Content (% of DRI)" }, "scales": { "xAxes": [{ "ticks": { "beginAtZero": True } }] } } }
[docs]def generate_html_report(analysis: NutrientAnalysis) -> str: """ Generate an HTML report for a nutrient analysis. Args: analysis: The nutrient analysis. Returns: An HTML string. """ # Generate chart data macro_chart = generate_macronutrient_chart_data(analysis) dri_chart = generate_dri_chart_data(analysis) # Convert chart data to JSON strings import json macro_chart_json = json.dumps(macro_chart) dri_chart_json = json.dumps(dri_chart) # Create HTML html = f""" <!DOCTYPE html> <html> <head> <title>Nutrient Analysis: {analysis.food.description}</title> <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script> <style> body {{ font-family: Arial, sans-serif; margin: 20px; }} .container {{ max-width: 800px; margin: 0 auto; }} .chart-container {{ width: 100%; height: 400px; margin-bottom: 30px; }} table {{ width: 100%; border-collapse: collapse; margin-bottom: 30px; }} th, td {{ padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }} th {{ background-color: #f2f2f2; }} </style> </head> <body> <div class="container"> <h1>Nutrient Analysis: {analysis.food.description}</h1> <p>Serving Size: {analysis.serving_size}g</p> <h2>Macronutrients</h2> <table> <tr> <th>Nutrient</th> <th>Amount</th> <th>% of Calories</th> </tr> <tr> <td>Calories</td> <td>{analysis.calories_per_serving:.1f} kcal</td> <td>100%</td> </tr> <tr> <td>Protein</td> <td>{analysis.protein_per_serving:.1f} g</td> <td>{analysis.macronutrient_distribution.get("protein", 0):.1f}%</td> </tr> <tr> <td>Carbohydrates</td> <td>{analysis.carbs_per_serving:.1f} g</td> <td>{analysis.macronutrient_distribution.get("carbs", 0):.1f}%</td> </tr> <tr> <td>Fat</td> <td>{analysis.fat_per_serving:.1f} g</td> <td>{analysis.macronutrient_distribution.get("fat", 0):.1f}%</td> </tr> </table> <div class="chart-container"> <canvas id="macroChart"></canvas> </div> <h2>Nutrient Content</h2> <div class="chart-container"> <canvas id="driChart"></canvas> </div> <h2>Detailed Nutrients</h2> <table> <tr> <th>Nutrient</th> <th>Amount</th> <th>% of DRI</th> </tr> """ # Add nutrient rows for nutrient_id, value in sorted( analysis.nutrients.items(), key=lambda x: x[1].dri_percent or 0, reverse=True ): dri_percent = f"{value.dri_percent:.1f}%" if value.dri_percent is not None else "N/A" html += f""" <tr> <td>{value.nutrient.name}</td> <td>{value.amount:.1f} {value.unit}</td> <td>{dri_percent}</td> </tr> """ # Close the table and add chart initialization html += f""" </table> </div> <script> // Initialize macronutrient chart var macroCtx = document.getElementById('macroChart').getContext('2d'); var macroChart = new Chart(macroCtx, {macro_chart_json}); // Initialize DRI chart var driCtx = document.getElementById('driChart').getContext('2d'); var driChart = new Chart(driCtx, {dri_chart_json}); </script> </body> </html> """ return html