Package net.sf.nfp.mini.view

Source Code of net.sf.nfp.mini.view.GraphView$AdditionalInfo

/*
* Natural Family Planning for J2ME
* Copyright (C) 2007 Krzysztof Rzymkowski <rzymek@users.sourceforge.net>
*  
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package net.sf.nfp.mini.view;

import java.util.Vector;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

import net.sf.log.mobile.Log;
import net.sf.nfp.mini.data.MucusRegistry;
import net.sf.nfp.mini.data.Observation;
import net.sf.nfp.mini.misc.Color;
import net.sf.nfp.mini.misc.Interval;
import net.sf.nfp.mini.misc.Transformation;
import net.sf.nfp.mini.misc.Utils;

public class GraphView extends PropagatingCanvas
  private static final int DISTURBED_CROSS_COLOR = 0x800000;
  private static final int DOT_RADIUS = 2;
  private static final int BACKGROUND_COLORS[] = { 0x222222, 0x666666, 0xffffff, 0x666666 };
  private int margin;
  private Font font;
  private Transformation tx;
  private Transformation ty;
  private Transformation ity;
  private int offset;
  private int selectedDay;
  private final int height;
  private final int detailsHeight;
  private int titleColor = Color.WHITE;
  private String title = "";
  private Vector observations;
  private int backgroundStripeHeight;
 
  public static class AdditionalInfo {
    public static final byte TEMP_LINE = 1;
    public static final byte DAY_LINE = 2;
    public static final byte DAY = 3;
    public static final byte INTERVAL = 4;

    public int a;
    public int b;
    public int color;
    public byte type;
  };
 
  public Vector/*AdditionalInfo*/ additional = new Vector();

  public GraphView() {
    offset = 6 * DOT_RADIUS;
    selectedDay = 0;
    showNotify();
    font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_SMALL);
    margin = font.stringWidth("00.0");
    detailsHeight = font.getHeight() + 2;
    Log.log("font.getHeight()="+font.getHeight());
    Log.log("detailsHeight="+detailsHeight );
    height = getHeight() - detailsHeight;
    tx = new Transformation(0, (getWidth() - margin) / 6, margin,
        getWidth());
    ty = new Transformation(Observation.MIN_TEMP, Observation.MAX_TEMP,
        height, 0);
    ity = new Transformation(0, height, Observation.MAX_TEMP,
        Observation.MIN_TEMP);
    backgroundStripeHeight = Math.abs(ty.get(Observation.MIN_TEMP)
        - ty.get(Observation.MIN_TEMP + 10));
  }

  protected void safePaint(Graphics g) {
    Log.log("GraphView.safePaint()");
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.setColor(Color.BLACK);
    g.setFont(font);
    drawBackground(g);
    drawAdditionalInfo(g);
    drawData(g);
    drawDetails(g);
    drawTemperatureLabels(g);
    drawTitle(g);
  }
 
  private void drawAdditionalInfo(Graphics g) {
    for(int i=0;i<additional.size();++i) {
      AdditionalInfo info = (AdditionalInfo) additional.elementAt(i);
      g.setColor(info.color);
      int x,y;
      switch(info.type) {
      case AdditionalInfo.DAY:
        x = tx.get(info.a);
        y = ty.get(info.b);
        drawDot(g, x, y, DOT_RADIUS + 4);
        break;
      case AdditionalInfo.DAY_LINE:
        x = tx.get(info.a);
        g.drawLine(x, 0, x, height);
        break;
      case AdditionalInfo.INTERVAL:
        drawInterval(g, new Interval(info.a, info.b), info.color, false);
        break;
      case AdditionalInfo.TEMP_LINE:
        y = ty.get(info.a);
        g.drawLine(margin, y, getWidth(), y);
        break;
      }
    }
  }

  private void drawTitle(Graphics g) {
    Log.log("GraphView.drawTitle()");
    int x = getWidth() - font.stringWidth(title) - 2;
    int width = font.stringWidth(title) + 2;
    int height = font.getHeight() + 2;
    g.setColor(titleColor);
    g.fillRect(x, 0, width, height);
    g.setColor(Color.BLACK);
    g.drawRoundRect(x, 0, width, height, 10, 10);
    g.drawString(title, x + 1, 1, 20);
  }

  private void drawData(Graphics g) {
    if(observations == null)
      return;
    int prevX = 0;
    int prevY = 0;
    boolean drawLine = false;
    boolean lastIsBleeding = true;
    for (int day = 0; day < observations.size(); day++) {
      Observation observation = (Observation) observations.elementAt(day);
      if(observation == null) {
        if(lastIsBleeding)
          drawInterval(g, new Interval(day, day+1), 0xff6060, true);
        continue;
      }
      if(observation.isBleeding()) {
        drawInterval(g, new Interval(day, day+1), 0x800000, true);
        if(day == selectedDay)
          drawInterval(g, new Interval(day, day+1), 0xff0000, true);
        continue;
      }else lastIsBleeding = false;
      if(!observation.hasTemperature())
        continue;
      int x = tx.get(day) + offset;
      int y = ty.get(observation.getTemperature());
      g.setColor(Color.BLACK);
      if (drawLine)
        g.drawLine(prevX + DOT_RADIUS, prevY, x - DOT_RADIUS, y);
      if (day == selectedDay) {
        g.setColor(Color.BLACK);
        drawDot(g, x, y, DOT_RADIUS + 2);
      }
      setMucusColor(g, observation);
      drawDot(g, x, y);
      g.setColor(Color.BLACK);
      fillDot(g, x, y);
      if(observation.isDisturbed()) {
        //draw a red cross
        g.setColor(DISTURBED_CROSS_COLOR);
        int r = DOT_RADIUS+2;
        g.drawLine(x - r, y - r, x + r, y + r);
        g.drawLine(x - r, y + r, x + r, y - r);
      }     
     
      prevX = x;
      prevY = y;
      drawLine = true;
    }
  }

  private void setMucusColor(Graphics g, Observation observation) {
    g.setColor(MucusRegistry.MUCUS_COLORS[observation.getMucus().getCategory()]);
  }

  private static void drawDot(Graphics g, int x, int y) {
    drawDot(g, x, y, DOT_RADIUS);
  }

  private static void drawDot(Graphics g, int x, int y, int radius) {
    g.fillArc(x - radius, y - radius, 2 * radius, 2 * radius, 0, 360);
  }

  private static void fillDot(Graphics g, int x, int y) {
    g.drawArc(x - DOT_RADIUS, y - DOT_RADIUS, 2 * DOT_RADIUS,
        2 * DOT_RADIUS, 0, 360);
  }

  private void drawTemperatureLabels(Graphics g) {
    Log.log("GraphView.drawTemperatureLabels()");
   
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, margin, height);
    g.setColor(0);
    g.drawLine(margin, 0, margin, height);
   
    final int tempStart = Observation.MIN_TEMP + 10;
    final int tempEnd = Observation.MAX_TEMP - 10;
    final int step = 10;
    int prevY = Integer.MAX_VALUE;
    for (int temp = tempStart; temp <= tempEnd; temp += step) {
      int y = ty.get(temp - step/2);
      if(prevY - font.getHeight() < y)
        continue;
      String tempString = Utils.formatTemperature(temp)
        .substring(0, "00.0".length());
      g.drawString(tempString, 0, y, Graphics.BOTTOM | Graphics.LEFT);
      prevY = y;
    }
  }

  private void drawDetails(Graphics g) {   
    g.setColor(Color.BLACK);
    g.drawLine(0, height-1, getWidth(), height-1);
    if (observations ==null || observations.isEmpty()) {
      return;
    } else {
      try {
        Observation observation = (Observation) observations.elementAt(selectedDay);
        if(observation == null)
          return;
        if(observation.isBleeding())
          g.setColor(Color.RED);
        else
          setMucusColor(g, observation);
        g.fillRect(0, height, getWidth(), detailsHeight);
        g.setColor(Color.BLACK);
        String detailString = Utils.zeroPadded(selectedDay + 1, 2) + ": "
            + observation;
        Log.log("GraphView.drawDetails()");
        g.drawString(detailString, 0, getHeight() - 1, Graphics.BOTTOM
            | Graphics.LEFT);
      }catch(Exception ex){
        ex.printStackTrace();
        return;
      }
    }
  }

  private void drawBackground(Graphics g) {
    Log.log("GraphView.drawBackground()");
    drawInterval(g, Interval.MAX, Color.WHITE, false);
  }

  private void drawInterval(Graphics g, Interval interval, int color, boolean mini) {
    if (interval == null)
      return;
    int colorIndex = 0;
    int boxStart;
    int boxWidth;
    if (Interval.MAX.equals(interval)) {
      boxStart = margin;
      boxWidth = getWidth() - margin;
    } else {
      boxStart = tx.get(interval.getStart());
      boxWidth = tx.get(interval.getEnd()) - boxStart;
      boxStart += offset;
    }
    int tempStart = Observation.MIN_TEMP;
    int tempEnd = Observation.MAX_TEMP;
    if (mini) {
      tempStart += 40;
      tempEnd -= 40;
      colorIndex = 4 % BACKGROUND_COLORS.length;
    }
    final int step = 10;
    for (int tempStep = tempStart; tempStep <= tempEnd; tempStep += step) {
      colorIndex = (colorIndex + 1) % BACKGROUND_COLORS.length;
      int c = BACKGROUND_COLORS[colorIndex];
      c = Color.blend(new Color(c), new Color(color)).getRGB();
      g.setColor(c);
      g.fillRect(boxStart, ty.get(tempStep + step), boxWidth, backgroundStripeHeight);
    }
  }

  /**
   * @param direction one of GraphView.DIRECTION_LEFT or GraphView.DIRECTION_RIGHT  
   */
  public void selectNextDot(int direction) {
    if(observations == null)
      return;
    int next = selectedDay + direction;
    while (0 <= next && next < observations.size()
        && observations.elementAt(next) == null)
      next += direction;
    if (0 <= next && next < observations.size())
      selectedDay = next;
    setSelectedDay(selectedDay);
  }
 
  public void setSelectedDay(int day) {
    selectedDay = day;
    while (tx.get(selectedDay + DOT_RADIUS) + offset > getWidth())
      offset -= 3 * DOT_RADIUS;
    while (tx.get(selectedDay - DOT_RADIUS) + offset < margin)
      offset += 3 * DOT_RADIUS;
    repaint();
  }

  public void setObservations(Vector observations) {
    this.observations = observations;
  }

  public void setTitle(String title) {
    //#ifndef midp1.0
    super.setTitle(title);
    //#endif
    this.title = title;
  }

  public Observation getSelectedObservation() {
    if(observations == null || selectedDay > observations.size())
      return null;
    return (Observation) observations.elementAt(selectedDay);
  }

  protected void showNotify() {
    //#ifndef midp1.0
    setFullScreenMode(true);
    //#endif
  }
}
TOP

Related Classes of net.sf.nfp.mini.view.GraphView$AdditionalInfo

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.