View Javadoc

1   /*
2    * Created on 26-Jun-2005
3    */
4   package ca.spaz.cron.summary;
5   
6   import java.awt.*;
7   import java.util.*;
8   import java.util.List;
9   
10  import javax.swing.*;
11  import javax.swing.border.Border;
12  
13  import ca.spaz.cron.database.*;
14  import ca.spaz.cron.targets.Target;
15  import ca.spaz.cron.user.User;
16  import ca.spaz.cron.user.impl.CRONUser;
17  
18  public class TargetSummaryChart extends JComponent {
19     double energy = 0;
20     double protein = 0;
21     double carbs = 0;
22     double lipid = 0;
23     
24     public TargetSummaryChart() {
25        setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
26     }
27     
28     public void update(Observable source, Object message) {
29       if (!(message instanceof List)) {
30           return;
31       }
32       List consumed = (List) message;
33       energy = getAmount(consumed, NutrientInfo.getByTableName("kcals"));
34       protein = getAmount(consumed, NutrientInfo.getByTableName("protein"));
35       carbs = getAmount(consumed, NutrientInfo.getByTableName("carbs"));
36       lipid = getAmount(consumed, NutrientInfo.getByTableName("lipid"));
37       // @TODO: add vitamin & mineral summary bars 
38       repaint();
39     }
40     
41     private double getAmount(List servings, NutrientInfo ni) {
42        double total = 0;
43        for (Iterator iter = servings.iterator(); iter.hasNext();) {
44           Serving serving = (Serving) iter.next();
45           double weight = serving.getGrams()/100.0;
46           total += weight * serving.getFood().getNutrientAmount(ni);
47       }
48       return total;
49     }
50     
51     // @TODO: refactor this code as it's highly redundant
52     public void paintComponent(Graphics g) {
53        User user = CRONUser.getUser();
54        
55        int w = getWidth();
56        int h = getHeight();
57        int xo = 0;
58        int yo = 0;
59        Border border = getBorder();
60        if (border != null) {
61           Insets insets = border.getBorderInsets(this);
62           w -= insets.left + insets.right;
63           h -= insets.top + insets.bottom;
64           xo = insets.left;
65           yo = insets.top;
66        }
67        
68        //int b = 4;
69        int min = w<h?w:h;
70        int barHeight = 24;
71        int pieRadius = 80;
72        double barFill = 0;
73        
74        g.setFont(g.getFont().deriveFont(Font.BOLD));
75        FontMetrics fm = g.getFontMetrics();
76        Graphics2D g2d = (Graphics2D)g;      
77        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f));
78        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
79        
80        Target energyTarget = user.getTarget(NutrientInfo.getByTableName("kcals"));
81        g.setColor(Color.LIGHT_GRAY);
82        g.fillRect(xo,yo,w,barHeight);
83        g.setColor(Color.ORANGE);      
84        if (energy > 0) {
85           barFill = energy/energyTarget.getMin();
86           if (barFill > 1) {
87              barFill = 1;
88              g.setColor(Color.ORANGE.brighter());
89              g.fill3DRect(xo,yo,(int)(w*barFill), barHeight, false);
90           } else {
91              g.fill3DRect(xo,yo,(int)(w*barFill), barHeight, true);
92           }
93        }
94        g.setColor(Color.BLACK);
95        g.drawString("Calories: " + (int)energy +" / " + (int)energyTarget.getMin() 
96              + " (" + Math.round(100*energy/energyTarget.getMin()) + "%)", 
97              xo+10, yo+barHeight/2+fm.getAscent()/2);
98  
99  
100       Target proteinTarget = user.getTarget(NutrientInfo.getByTableName("protein"));
101       g.setColor(Color.LIGHT_GRAY);
102       g.fillRect(xo,yo+(barHeight+5),w-pieRadius,barHeight);
103       g.setColor(Color.GREEN);
104       if (protein > 0) {
105          barFill = protein/proteinTarget.getMin();
106          if (barFill > 1) {
107             barFill = 1;
108             g.setColor(Color.GREEN.brighter());
109             g.fill3DRect(xo,yo+(barHeight+5),(int)((w-pieRadius)*barFill), barHeight,false);
110          } else {
111             g.fill3DRect(xo,yo+(barHeight+5),(int)((w-pieRadius)*barFill), barHeight,true);
112          }
113       }
114       g.setColor(Color.BLACK);
115       g.drawString("Protein: " + (int)protein +"g / " + (int)proteinTarget.getMin() 
116             + "g (" + Math.round(100*protein/proteinTarget.getMin()) + "%)", 
117             xo+10, yo+(barHeight+5)+barHeight/2+fm.getAscent()/2);
118 
119       
120       Target carbTarget = user.getTarget(NutrientInfo.getByTableName("carbs"));
121       g.setColor(Color.LIGHT_GRAY);
122       g.fillRect(xo,yo+(barHeight+5)*2,w-pieRadius,barHeight);
123       g.setColor(Color.BLUE);
124       if (carbs > 0) {
125          barFill = carbs/carbTarget.getMin();
126          if (barFill > 1) {
127             barFill = 1;
128             g.setColor(Color.BLUE.brighter());
129             g.fill3DRect(xo,yo+(barHeight+5)*2,(int)((w-pieRadius)*barFill), barHeight,false);
130          } else {
131             g.fill3DRect(xo,yo+(barHeight+5)*2,(int)((w-pieRadius)*barFill), barHeight,true);
132          }
133       }
134       g.setColor(Color.BLACK);
135       g.drawString("Carbohydrates: " + (int)carbs +"g / " + (int)carbTarget.getMin() 
136             + "g (" + Math.round(100*carbs/carbTarget.getMin()) + "%)", 
137             xo+10, yo+(barHeight+5)*2+barHeight/2+fm.getAscent()/2);
138 
139       Target lipidTarget = user.getTarget(NutrientInfo.getByTableName("lipid"));
140       g.setColor(Color.LIGHT_GRAY);
141       g.fillRect(xo,yo+(barHeight+5)*3,w-pieRadius,barHeight);
142       g.setColor(Color.RED);
143       if (lipid > 0) {
144          barFill = lipid/lipidTarget.getMin();
145          if (barFill > 1) {
146             barFill = 1;
147             g.setColor(Color.RED.brighter());
148             g.fill3DRect(xo,yo+(barHeight+5)*3,(int)((w-pieRadius)*barFill), barHeight, false);
149          } else {
150             g.fill3DRect(xo,yo+(barHeight+5)*3,(int)((w-pieRadius)*barFill), barHeight,true);
151          }
152       }
153       g.setColor(Color.BLACK);
154       g.drawString("Lipids: " + (int)lipid +"g / " + (int)lipidTarget.getMin() 
155             + "g (" + Math.round(100*lipid/lipidTarget.getMin()) + "%)", 
156             xo+10, yo+(barHeight+5)*3+barHeight/2+fm.getAscent()/2);
157 
158       paintPFC(g, xo+(w-pieRadius)+10, yo+(barHeight+5)+10, pieRadius-20);
159    }
160    
161    
162    private void paintPFC(Graphics g, int xo, int yo, int radius) {
163       double total = protein + carbs + lipid;
164       g.setColor(Color.GREEN);
165       int amount = 0;
166       g.fillArc(xo,yo,radius-4,radius-4, amount, (int)(360*(protein/total)));
167       amount += (int)(360*(protein/total));
168       
169       g.setColor(Color.BLUE);
170       g.fillArc(xo,yo,radius-4,radius-4, amount, (int)(360*(carbs/total)));
171       amount += (int)(360*(carbs/total));
172 
173       g.setColor(Color.RED);
174       g.fillArc(xo,yo,radius-4,radius-4, amount, (int)(360*(lipid/total)));      
175    }
176 
177    public Dimension getPreferredSize() {
178       return new Dimension(300, 120);
179    }
180 }