The Balance Recommendations feature helps chefs discover ingredient combinations that maximize flavor balance when building dishes. It analyzes existing flavors in the database and generates recommendations for components that can be added to a dish.
- Generates component combinations of 2-3 ingredients
- Calculates balance score for each combination (0-1 scale)
- Ranks recommendations by balance, with highest balance first
- Limits recommendations to top 10 combinations
- Fetches all available components from existing dishes
- Queries flavor database for ingredient data
- Limits component set to 50 items (if more exist) to avoid excessive computation
- Smart sampling for 3-component combinations to keep generation time reasonable
Balance is calculated using the same algorithm as the backend:
- Identifies the dominant taste
- Calculates deviations of other tastes from the dominant one
- Score = 1 - (average_deviation / dominant_value)
- Higher scores = more balanced combinations
- Color-coded cards with balance indicators:
- 🟢 Green border: Balance > 70%
- 🟠 Orange border: Balance 50-70%
- 🔴 Red border: Balance < 50%
- 5-star rating visualization for balance
- Intensity percentage display
- Detailed taste breakdown (sweet, salty, sour, bitter, umami)
- "Use This" button to instantly add recommended components to the dish
- Seamless integration with dish editing workflow
- Components added to existing dish components
File: /menu_app/frontend/components/analysis/BalanceRecommendations.tsx
Integration: Embedded in the Dish detail page (/menu_app/frontend/components/pages/Dish.tsx) on the right-hand side analysis panel
-
Data Collection
- Fetches all dishes created by the user
- Extracts all unique component names
- Limits to 50 components if more exist
-
Flavor Lookup
- Queries the flavor database for all component flavors
- Uses existing flavor API endpoint
-
Combination Generation
- 2-component pairs: All possible pairs (n choose 2)
- 3-component combinations: Sampled subset to avoid explosion of combinations
- Uses step-based sampling to keep computation reasonable
- Step size = max(1, floor(components_count / 10))
-
Scoring
- For each combination:
- Combines taste values using maximal taste algorithm
- Averages the combined tastes
- Calculates balance score
- Calculates intensity score
- For each combination:
-
Ranking
- Sorts by balance score (highest first)
- Returns top 10 recommendations
Matches the backend implementation:
-
Maximal Taste Combination
- For each taste dimension (sweet, salty, sour, bitter, umami)
- Takes the maximum value across all components
- Results in a strongly flavored combination
-
Averaging
- Divides the maximal values by the number of components
- Provides realistic flavor intensity
-
Balance Scoring
- Finds the dominant taste (highest value)
- Calculates deviations for all other tastes
- Returns balance as deviation from maximum
- Up to 50 components: Full 2-component pairs + sampled 3-component combinations
- 2-component pairs: O(n²) complexity, manageable for 50 components (~1,225 combinations)
- 3-component combinations: Sampled to ~10% of components for step-based generation
- Total combinations: Typically 1,000-2,000 recommendations processed
- Component limiting: Caps at 50 components to prevent excessive combinations
- Sampling strategy: Skips 3-component combinations using a step-based approach
- Lazy loading: Recommendations are only generated when the dish page is loaded
- Sorting: Top 10 recommendations displayed to avoid overwhelming the UI
- Embedded in right-side analysis panel on dish detail page
- Responsive grid layout (1 column mobile, 2 columns tablet, 3 columns desktop)
- Scrollable if multiple recommendations exceed viewport
Each recommendation card displays:
- Title: Ingredient combination names (e.g., "Lemon + Salt")
- Balance Score: Visual rating out of 5 (actual value shown as percentage)
- Intensity: Percentage indicator (0-100%)
- Taste Breakdown: Individual taste values
- Sweet, Salty, Sour, Bitter, Umami
- Call-to-Action: "Use This" button to add components to dish
- Color borders: Indicate balance quality
- Star ratings: 5-star visual representation of balance
- Hover effects: Cards lift and get enhanced shadow on hover
- Responsive design: Adapts to mobile, tablet, and desktop viewports
-
GET /api/dishes - Fetches all dishes by user
- Extracts component names from dishes
-
GET /flavor-api - Fetches flavor data
- URL:
https://damonb--416ddf5e54ea11f08babf69ea79377d9.web.val.run - Query param:
flavors=["ingredient1", "ingredient2", ...] - Returns: Array of flavor objects with taste, texture, aroma data
- URL:
- Material-UI (MUI): Box, Card, Button, Typography, Rating, CircularProgress, Grid, Paper
- React Router: useNavigate for API calls
- React Hooks: useState, useEffect for state management
- No dishes: Shows informative message
- No components: Displays error message
- API failures: Catches and displays errors
- Flavor lookup issues: Handles missing flavors gracefully
-
Filtering Options
- Filter by taste profile (e.g., "sweet-forward")
- Filter by intensity level
- Filter by cuisine type
-
Advanced Scoring
- Combine balance with other metrics (texture, aroma)
- Weight different taste dimensions differently
- Consider ingredient compatibility heuristics
-
Caching
- Cache recommendations for faster subsequent loads
- Invalidate cache when new dishes are added
-
Analytics
- Track which recommendations are most often used
- Learn from chef preferences over time
- Suggest trending combinations
-
Customization
- Let users set custom balance algorithms
- Adjust component sampling rate
- Customize number of recommendations displayed
- Component renders on dish detail page
- Recommendations load for dishes with components
- Balance scores display correctly (0-1 range)
- Cards are color-coded appropriately
- "Use This" button adds components to dish
- Responsive design works on mobile, tablet, desktop
- Error messages display for edge cases
- Loading spinner shows while fetching data
- Empty database: Shows "No components found" message
- Single component dish: Still generates 2-component recommendations
- Many flavors (50+): Correctly limits to 50 and shows subset
- Failed API calls: Displays error messages
- Large recommendation sets: Only shows top 10, performant rendering