From 1e74123cfed4374b403574b6cd16bd8d4e73bf45 Mon Sep 17 00:00:00 2001
From: Normand Briere <nbriere@noware.ca>
Date: Tue, 10 Jul 2018 22:17:11 -0400
Subject: [PATCH] Refactoring.
---
timeflow/data/time/TimeUnit.java | 472 ++++++-----
timeflow/app/TimeflowApp.java | 12
timeflow/views/ListView.java | 499 ++++++------
timeflow/data/time/RoughTime.java | 3
timeflow/vis/Mouseover.java | 176 ++--
timeflow/format/file/HtmlFormat.java | 264 +++---
timeflow/vis/timeline/AxisTicMarks.java | 220 ++--
timeflow/views/TimelineView.java | 94 +
timeflow/views/AbstractVisualizationView.java | 8
timeflow/vis/VisualAct.java | 1
timeflow/app/ui/LinkTabPane.java | 414 +++++-----
timeflow/vis/timeline/AxisRenderer.java | 151 +-
12 files changed, 1,220 insertions(+), 1,094 deletions(-)
diff --git a/timeflow/app/TimeflowApp.java b/timeflow/app/TimeflowApp.java
index 4826184..1bdc790 100755
--- a/timeflow/app/TimeflowApp.java
+++ b/timeflow/app/TimeflowApp.java
@@ -35,7 +35,8 @@
public JMenu filterMenu;
JMenuItem save = new JMenuItem("Save");
FilterControlPanel filterControlPanel;
- LinkTabPane leftPanel;
+ //LinkTabPane
+ JTabbedPane leftPanel;
TFListener filterMenuMaker = new TFListener()
{
@Override
@@ -90,14 +91,15 @@
// left tab area, with vertical gray divider.
JPanel leftHolder = new JPanel();
- container.add(leftHolder, BorderLayout.WEST);
+ container.add(leftHolder, BorderLayout.EAST); // WEST);
leftHolder.setLayout(new BorderLayout());
JPanel pad = new Pad(3, 3);
pad.setBackground(Color.gray);
leftHolder.add(pad, BorderLayout.EAST);
- leftPanel = new LinkTabPane();//JTabbedPane();
+ leftPanel = new //LinkTabPane();
+ JTabbedPane();
leftHolder.add(leftPanel, BorderLayout.CENTER);
JPanel configPanel = new JPanel();
@@ -112,9 +114,9 @@
configPanel.add(legend, BorderLayout.CENTER);
legend.add(new SizeLegendPanel(model), BorderLayout.NORTH);
legend.add(new ColorLegendPanel(model), BorderLayout.CENTER);
- leftPanel.addTab(configPanel, "Display", true);
+ leftPanel.add(configPanel, "Display"); //, true);
- leftPanel.addTab(filterControlPanel, "Filter", true);
+ leftPanel.add(filterControlPanel, "Filter"); //, true);
// center tab area
diff --git a/timeflow/app/ui/LinkTabPane.java b/timeflow/app/ui/LinkTabPane.java
index 1f4ee01..911461c 100755
--- a/timeflow/app/ui/LinkTabPane.java
+++ b/timeflow/app/ui/LinkTabPane.java
@@ -8,201 +8,225 @@
import java.util.*;
// custom JTabbedPane-like thing.
-public class LinkTabPane extends JPanel {
-
- ArrayList<String> tabNames=new ArrayList<String>();
- HashMap<String, JComponent> tabMap=new HashMap<String, JComponent>();
- String currentName;
- CardLayout cards=new CardLayout();
- JPanel center=new JPanel();
- LinkTop top=new LinkTop();
-
- public LinkTabPane()
- {
- setBackground(Color.white);
- setLayout(new BorderLayout());
- add(top, BorderLayout.NORTH);
- add(center, BorderLayout.CENTER);
- center.setLayout(cards);
- top.addMouseListener(new MouseAdapter() {
- @Override
- public void mousePressed(MouseEvent e) {
- String s=top.getName(e.getX());
- if (s!=null)
- {
- String old=currentName;
- setCurrentName(s);
- firePropertyChange("tab", old, s);
- }
- }});
- }
-
- public String getTitleAt(int i)
- {
- return tabNames.get(i);
- }
-
- public void setSelectedIndex(int i)
- {
- setCurrentName(getTitleAt(i));
- }
-
- public void addTab(JComponent component, String name, boolean left)
- {
- tabNames.add(name);
- tabMap.put(name, component);
- center.add(component, name);
- top.addName(name, left);
- repaint();
- if (currentName==null)
- currentName=name;
- }
-
- public String getCurrentName()
- {
- return currentName;
- }
-
- public void setCurrentName(final String currentName)
- {
- this.currentName=currentName;
- top.repaint();
- SwingUtilities.invokeLater(new Runnable() {public void run() {cards.show(center, currentName);}});
+public class LinkTabPane extends JPanel
+{
- }
-
- class LinkTop extends JPanel
- {
- int left, right;
- ArrayList<HotLink> leftHots=new ArrayList<HotLink>();
- ArrayList<HotLink> rightHots=new ArrayList<HotLink>();
- Font font=new Font("Verdana", Font.PLAIN, 14);
- FontMetrics fm=getFontMetrics(font);
-
- LinkTop()
- {
- setLayout(new FlowLayout(FlowLayout.LEFT));
- setBackground(new Color(220,220,220));
- }
-
- public void paintComponent(Graphics g1)
- {
- int w=getSize().width, h=getSize().height;
- Graphics2D g=(Graphics2D)g1;
- g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
- g.setColor(getBackground());
- g.fillRect(0,0,w,h);
- g.setColor(Color.gray);
- for (int i=0; i<2; i++)
- {
- g.drawLine(0,i,w,i);
- g.drawLine(0,h-1-i,w,h-1-i);
- }
-
- for (HotLink hot: leftHots)
- {
- draw(g, hot, h, 0);
- }
-
- for (HotLink hot: rightHots)
- {
- draw(g, hot, h, w);
- }
-
- for (int i=0; i<leftHots.size(); i++)
- {
-
- if (i<leftHots.size()-1)
- {
- HotLink hot=leftHots.get(i);
- for (int j=0; j<1; j++)
- g.drawLine(hot.x+hot.width-1-j, 7, hot.x+hot.width-1-j, h-7);
- }
- }
-
- for (int i=0; i<rightHots.size(); i++)
- {
-
- if (i<rightHots.size()-1)
- {
- HotLink hot=rightHots.get(i);
- for (int j=0; j<1; j++)
- g.drawLine(hot.x+w-1-j, 7, hot.x+w-1-j, h-7);
- }
- }
- }
-
- void draw(Graphics g, HotLink hot, int h, int dx)
- {
- int x=hot.x+dx;
- if (hot.s.equals(currentName))
- {
- g.setColor(Color.lightGray);
- g.fillRect(x,2,hot.width,h-4);
- g.setColor(Color.gray);
- g.drawLine(x-1, 0, x-1, h);
- g.drawLine(x+hot.width-1, 0, x+hot.width-1, h);
- }
- g.setColor(Color.darkGray);
- g.setFont(font);
- int sw=fm.stringWidth(hot.s);
- g.drawString(hot.s, x+(hot.width-sw)/2, h-10);
-
- }
-
- String getName(int x)
- {
- for (HotLink h: leftHots)
- {
- if (h.x<=x && h.x+h.width>x)
- return h.s;
- }
- for (HotLink h: rightHots)
- {
- int w=getSize().width;
- if (h.x+w<=x && h.x+h.width+w>x)
- return h.s;
- }
+ ArrayList<String> tabNames = new ArrayList<String>();
+ HashMap<String, JComponent> tabMap = new HashMap<String, JComponent>();
+ String currentName;
+ CardLayout cards = new CardLayout();
+ JPanel center = new JPanel();
+ LinkTop top = new LinkTop();
- if (leftHots.size()>0)
- return leftHots.get(leftHots.size()-1).s;
- if (rightHots.size()>0)
- return rightHots.get(0).s;
- return null;
- }
-
- void addName(String name, boolean leftward)
- {
- if (leftward)
- {
- int x=right;
- int w=fm.stringWidth(name)+24;
- leftHots.add(new HotLink(name, x, 0, w, 30));
- right+=w;
- }
- else
- {
- int x=left;
- int w=fm.stringWidth(name)+24;
- rightHots.add(new HotLink(name, x-w, 0, w, 30));
- left-=w;
- }
- }
-
- class HotLink extends Rectangle
- {
- String s;
- HotLink(String s, int x, int y, int w, int h)
- {
- super(x,y,w,h);
- this.s=s;
- }
- }
-
- public Dimension getPreferredSize()
- {
- return new Dimension(30,30);
- }
- }
-
+ public LinkTabPane()
+ {
+ setBackground(Color.white);
+ setLayout(new BorderLayout());
+ add(top, BorderLayout.NORTH);
+ add(center, BorderLayout.CENTER);
+ center.setLayout(cards);
+ top.addMouseListener(new MouseAdapter()
+ {
+
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ String s = top.getName(e.getX());
+ if (s != null)
+ {
+ String old = currentName;
+ setCurrentName(s);
+ firePropertyChange("tab", old, s);
+ }
+ }
+ });
+ }
+
+ public String getTitleAt(int i)
+ {
+ return tabNames.get(i);
+ }
+
+ public void setSelectedIndex(int i)
+ {
+ setCurrentName(getTitleAt(i));
+ }
+
+ public void addTab(JComponent component, String name, boolean left)
+ {
+ tabNames.add(name);
+ tabMap.put(name, component);
+ center.add(component, name);
+ top.addName(name, left);
+ repaint();
+ if (currentName == null)
+ {
+ currentName = name;
+ }
+ }
+
+ public String getCurrentName()
+ {
+ return currentName;
+ }
+
+ public void setCurrentName(final String currentName)
+ {
+ this.currentName = currentName;
+ top.repaint();
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ cards.show(center, currentName);
+ }
+ });
+
+ }
+
+ class LinkTop extends JPanel
+ {
+ int left, right;
+ ArrayList<HotLink> leftHots = new ArrayList<HotLink>();
+ ArrayList<HotLink> rightHots = new ArrayList<HotLink>();
+ Font font = new Font("Verdana", Font.PLAIN, 14);
+ FontMetrics fm = getFontMetrics(font);
+
+ LinkTop()
+ {
+ setLayout(new FlowLayout(FlowLayout.LEFT));
+ setBackground(new Color(220, 220, 220));
+ }
+
+ public void paintComponent(Graphics g1)
+ {
+ int w = getSize().width, h = getSize().height;
+ Graphics2D g = (Graphics2D) g1;
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setColor(getBackground());
+ g.fillRect(0, 0, w, h);
+ g.setColor(Color.gray);
+ for (int i = 0; i < 2; i++)
+ {
+ g.drawLine(0, i, w, i);
+ g.drawLine(0, h - 1 - i, w, h - 1 - i);
+ }
+
+ for (HotLink hot : leftHots)
+ {
+ draw(g, hot, h, 0);
+ }
+
+ for (HotLink hot : rightHots)
+ {
+ draw(g, hot, h, w);
+ }
+
+ for (int i = 0; i < leftHots.size(); i++)
+ {
+
+ if (i < leftHots.size() - 1)
+ {
+ HotLink hot = leftHots.get(i);
+ for (int j = 0; j < 1; j++)
+ {
+ g.drawLine(hot.x + hot.width - 1 - j, 7, hot.x + hot.width - 1 - j, h - 7);
+ }
+ }
+ }
+
+ for (int i = 0; i < rightHots.size(); i++)
+ {
+
+ if (i < rightHots.size() - 1)
+ {
+ HotLink hot = rightHots.get(i);
+ for (int j = 0; j < 1; j++)
+ {
+ g.drawLine(hot.x + w - 1 - j, 7, hot.x + w - 1 - j, h - 7);
+ }
+ }
+ }
+ }
+
+ void draw(Graphics g, HotLink hot, int h, int dx)
+ {
+ int x = hot.x + dx;
+ if (hot.s.equals(currentName))
+ {
+ g.setColor(Color.lightGray);
+ g.fillRect(x, 2, hot.width, h - 4);
+ g.setColor(Color.gray);
+ g.drawLine(x - 1, 0, x - 1, h);
+ g.drawLine(x + hot.width - 1, 0, x + hot.width - 1, h);
+ }
+ g.setColor(Color.darkGray);
+ g.setFont(font);
+ int sw = fm.stringWidth(hot.s);
+ g.drawString(hot.s, x + (hot.width - sw) / 2, h - 10);
+
+ }
+
+ String getName(int x)
+ {
+ for (HotLink h : leftHots)
+ {
+ if (h.x <= x && h.x + h.width > x)
+ {
+ return h.s;
+ }
+ }
+ for (HotLink h : rightHots)
+ {
+ int w = getSize().width;
+ if (h.x + w <= x && h.x + h.width + w > x)
+ {
+ return h.s;
+ }
+ }
+
+ if (leftHots.size() > 0)
+ {
+ return leftHots.get(leftHots.size() - 1).s;
+ }
+ if (rightHots.size() > 0)
+ {
+ return rightHots.get(0).s;
+ }
+ return null;
+ }
+
+ void addName(String name, boolean leftward)
+ {
+ if (leftward)
+ {
+ int x = right;
+ int w = fm.stringWidth(name) + 24;
+ leftHots.add(new HotLink(name, x, 0, w, 30));
+ right += w;
+ } else
+ {
+ int x = left;
+ int w = fm.stringWidth(name) + 24;
+ rightHots.add(new HotLink(name, x - w, 0, w, 30));
+ left -= w;
+ }
+ }
+
+ class HotLink extends Rectangle
+ {
+ String s;
+
+ HotLink(String s, int x, int y, int w, int h)
+ {
+ super(x, y, w, h);
+ this.s = s;
+ }
+ }
+
+ public Dimension getPreferredSize()
+ {
+ return new Dimension(30, 30);
+ }
+ }
}
diff --git a/timeflow/data/time/RoughTime.java b/timeflow/data/time/RoughTime.java
index 9cadc5a..55b4bbb 100755
--- a/timeflow/data/time/RoughTime.java
+++ b/timeflow/data/time/RoughTime.java
@@ -100,7 +100,8 @@
public String format()
{
- return units.formatFull(time);
+ //return units.formatFull(time);
+ return TimeUnit.SECOND.formatFull(time);
}
public static int compare(RoughTime t1, RoughTime t2)
diff --git a/timeflow/data/time/TimeUnit.java b/timeflow/data/time/TimeUnit.java
index 760b3be..4032258 100755
--- a/timeflow/data/time/TimeUnit.java
+++ b/timeflow/data/time/TimeUnit.java
@@ -3,241 +3,255 @@
import java.util.*;
import java.text.*;
-public class TimeUnit {
+public class TimeUnit
+{
- public static final TimeUnit YEAR=new TimeUnit("Years", Calendar.YEAR, 365*24*60*60*1000L, "yyyy", "yyyy");
- public static final TimeUnit MONTH=new TimeUnit("Months", Calendar.MONTH, 30*24*60*60*1000L, "MMM", "MMM yyyy");
- public static final TimeUnit WEEK=new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7*24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit DAY=new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit DAY_OF_WEEK=new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit HOUR=new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60*60*1000L, "kk:mm", "MMM d yyyy kk:mm");
- public static final TimeUnit MINUTE=new TimeUnit("Minutes", Calendar.MINUTE, 60*1000L, ":mm", "MMM d yyyy kk:mm");
- public static final TimeUnit SECOND=new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy kk:mm:ss");
- public static final TimeUnit DECADE=multipleYears(10);
- public static final TimeUnit CENTURY=multipleYears(100);
-
- private static final double DAY_SIZE=24*60*60*1000L;
-
- private int quantity;
- private long roughSize;
- private SimpleDateFormat format, fullFormat;
- private String name;
- private int calendarCode;
-
- private TimeUnit()
- {
- }
-
- private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern)
- {
- this.name=name;
- this.calendarCode=calendarCode;
- this.roughSize=roughSize;
- format=new SimpleDateFormat(formatPattern);
- fullFormat=new SimpleDateFormat(fullFormatPattern);
- quantity=1;
- }
-
- public String toString()
- {
- return "[TimeUnit: "+name+"]";
- }
+ public static final TimeUnit YEAR = new TimeUnit("Years", Calendar.YEAR, 365 * 24 * 60 * 60 * 1000L, "yyyy", "yyyy");
+ public static final TimeUnit MONTH = new TimeUnit("Months", Calendar.MONTH, 30 * 24 * 60 * 60 * 1000L, "MMM", "MMM yyyy");
+ public static final TimeUnit WEEK = new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7 * 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit DAY = new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit DAY_OF_WEEK = new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit HOUR = new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60 * 60 * 1000L, "kk:mm", "MMM d yyyy kk:mm");
+ public static final TimeUnit MINUTE = new TimeUnit("Minutes", Calendar.MINUTE, 60 * 1000L, ":mm", "MMM d yyyy kk:mm");
+ public static final TimeUnit SECOND = new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy kk:mm:ss");
+ public static final TimeUnit DECADE = multipleYears(10);
+ public static final TimeUnit CENTURY = multipleYears(100);
+ private static final double DAY_SIZE = 24 * 60 * 60 * 1000L;
+ private int quantity;
+ private long roughSize;
+ private SimpleDateFormat format, fullFormat;
+ private String name;
+ private int calendarCode;
- public static TimeUnit multipleYears(int numYears)
- {
- TimeUnit t=new TimeUnit();
- t.name=numYears+" Years";
- t.calendarCode=Calendar.YEAR;
- t.roughSize=YEAR.roughSize*numYears;
- t.format=YEAR.format;
- t.fullFormat=YEAR.fullFormat;
- t.quantity=numYears;
- return t;
- }
-
- public static TimeUnit multipleWeeks(int num)
- {
- TimeUnit t=new TimeUnit();
- t.name=num+" Weeks";
- t.calendarCode=Calendar.WEEK_OF_YEAR;
- t.roughSize=WEEK.roughSize*num;
- t.format=WEEK.format;
- t.fullFormat=WEEK.fullFormat;
- t.quantity=num;
- return t;
- }
-
- public TimeUnit times(int quantity)
- {
- TimeUnit t=new TimeUnit();
- t.name=quantity+" "+this.name;
- t.calendarCode=this.calendarCode;
- t.roughSize=this.roughSize*quantity;
- t.format=this.format;
- t.fullFormat=this.fullFormat;
- t.quantity=quantity;
- return t;
-
- }
+ private TimeUnit()
+ {
+ }
-
- public int numUnitsIn(TimeUnit u)
- {
- return (int)Math.round(u.getRoughSize()/(double)getRoughSize());
- }
-
- public boolean isDayOrLess()
- {
- return roughSize <= 24*60*60*1000L;
- }
-
- public RoughTime roundDown(long timestamp)
- {
- return round(timestamp, false);
- }
-
- public RoughTime roundUp(long timestamp)
- {
- return round(timestamp, true);
- }
-
- private static final int[] calendarUnits={Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR};
- public RoughTime round(long timestamp, boolean up)
- {
- Calendar c=TimeUtils.cal(timestamp);
-
- if (calendarCode==Calendar.WEEK_OF_YEAR )
- {
- c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK));
- }
- else
- {
-
- // set to minimum all fields of finer granularity.
- int roundingCode=calendarCode;
- if (calendarCode==Calendar.WEEK_OF_YEAR || calendarCode==Calendar.DAY_OF_WEEK)
- roundingCode=Calendar.DAY_OF_MONTH;
- for (int i=0; i<calendarUnits.length; i++)
- {
- if (calendarUnits[i]==roundingCode)
- break;
- if (i==calendarUnits.length-1)
- throw new IllegalArgumentException("Unsupported Calendar Unit: "+calendarCode);
- c.set(calendarUnits[i], c.getMinimum(calendarUnits[i]));
- }
- if (quantity>1)
- {
- c.set(calendarCode, quantity*(c.get(calendarCode)/quantity));
- }
- }
-
- // if rounding up, then add a unit at current granularity.
- if (up)
- c.add(calendarCode, quantity);
-
- return new RoughTime(c.getTimeInMillis(), this);
- }
-
- public int get(long timestamp)
- {
- Calendar c= TimeUtils.cal(timestamp);
- int n=c.get(calendarCode);
- return quantity==1 ? n : n%quantity;
- }
-
- public void addTo(RoughTime r)
- {
- addTo(r,1);
- }
-
- public void addTo(RoughTime r, int times)
- {
- Calendar c=TimeUtils.cal(r.getTime());
- c.add(calendarCode, quantity*times);
- r.setTime(c.getTimeInMillis());
- }
-
- // Finding the difference between two dates, in a given unit of time,
- // is much subtler than you'd think! And annoyingly, the Calendar class does not do
- // this for you, even though it actually "knows" how to do so since it
- // can add fields.
- //
- // The most vexing problem is dealing with daylight savings time,
- // which means that one day a year has 23 hours and one day has 25 hours.
- // We also have to handle the fact that months and years aren't constant lengths.
- //
- // Rather than write all this ourselves, in this code we
- // use the Calendar class to do the heavy lifting.
- public long difference(long x, long y)
- {
- // If this is not one of the hard cases,
- // just divide the timespan by the length of time unit.
- // Note that we're not worrying about hours and daylight savings time.
- if (calendarCode!=Calendar.YEAR && calendarCode!=Calendar.MONTH &&
- calendarCode!=Calendar.DAY_OF_MONTH && calendarCode!=Calendar.DAY_OF_WEEK &&
- calendarCode!=Calendar.WEEK_OF_YEAR)
- {
- return (x-y)/roughSize;
- }
-
- Calendar c1=TimeUtils.cal(x), c2=TimeUtils.cal(y);
- int diff=0;
- switch (calendarCode)
- {
- case Calendar.YEAR:
- return (c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))/quantity;
-
- case Calendar.MONTH:
- diff= 12*(c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))+
- c1.get(Calendar.MONTH)-c2.get(Calendar.MONTH);
- return diff/quantity;
-
- case Calendar.DAY_OF_MONTH:
- case Calendar.DAY_OF_WEEK:
- case Calendar.DAY_OF_YEAR:
- case Calendar.WEEK_OF_MONTH:
- case Calendar.WEEK_OF_YEAR:
- // This is ugly, but believe me, it beats the alternative methods :-)
- // We use the Calendar class's knowledge of daylight savings time.
- // and also the fact that if we calculate this naively, then we aren't going
- // to be off by more than one in either direction.
- int naive=(int)Math.round((x-y)/(double)roughSize);
- c2.add(calendarCode, naive*quantity);
- if (c1.get(calendarCode)==c2.get(calendarCode))
- return naive/quantity;
- c2.add(calendarCode, quantity);
- if (c1.get(calendarCode)==c2.get(calendarCode))
- return naive/quantity+1;
- return naive/quantity-1;
- }
- throw new IllegalArgumentException("Unexpected calendar code: "+calendarCode);
- }
+ private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern)
+ {
+ this.name = name;
+ this.calendarCode = calendarCode;
+ this.roughSize = roughSize;
+ format = new SimpleDateFormat(formatPattern);
+ fullFormat = new SimpleDateFormat(fullFormatPattern);
+ quantity = 1;
+ }
- public long approxNumInRange(long start, long end)
- {
- return 1+(end-start)/roughSize;
- }
-
- public long getRoughSize() {
- return roughSize;
- }
+ public String toString()
+ {
+ return "[TimeUnit: " + name + "]";
+ }
- public String format(Date date)
- {
- return format.format(date);
- }
+ public static TimeUnit multipleYears(int numYears)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = numYears + " Years";
+ t.calendarCode = Calendar.YEAR;
+ t.roughSize = YEAR.roughSize * numYears;
+ t.format = YEAR.format;
+ t.fullFormat = YEAR.fullFormat;
+ t.quantity = numYears;
+ return t;
+ }
- public String formatFull(Date date)
- {
- return fullFormat.format(date);
- }
+ public static TimeUnit multipleWeeks(int num)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = num + " Weeks";
+ t.calendarCode = Calendar.WEEK_OF_YEAR;
+ t.roughSize = WEEK.roughSize * num;
+ t.format = WEEK.format;
+ t.fullFormat = WEEK.fullFormat;
+ t.quantity = num;
+ return t;
+ }
- public String formatFull(long timestamp)
- {
- return fullFormat.format(new Date(timestamp));
- }
+ public TimeUnit times(int quantity)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = quantity + " " + this.name;
+ t.calendarCode = this.calendarCode;
+ t.roughSize = this.roughSize * quantity;
+ t.format = this.format;
+ t.fullFormat = this.fullFormat;
+ t.quantity = quantity;
+ return t;
- public String getName() {
- return name;
- }
+ }
+
+ public int numUnitsIn(TimeUnit u)
+ {
+ return (int) Math.round(u.getRoughSize() / (double) getRoughSize());
+ }
+
+ public boolean isDayOrLess()
+ {
+ return roughSize <= 24 * 60 * 60 * 1000L;
+ }
+
+ public RoughTime roundDown(long timestamp)
+ {
+ return round(timestamp, false);
+ }
+
+ public RoughTime roundUp(long timestamp)
+ {
+ return round(timestamp, true);
+ }
+ private static final int[] calendarUnits =
+ {
+ Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR
+ };
+
+ public RoughTime round(long timestamp, boolean up)
+ {
+ Calendar c = TimeUtils.cal(timestamp);
+
+ if (calendarCode == Calendar.WEEK_OF_YEAR)
+ {
+ c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK));
+ } else
+ {
+
+ // set to minimum all fields of finer granularity.
+ int roundingCode = calendarCode;
+ if (calendarCode == Calendar.WEEK_OF_YEAR || calendarCode == Calendar.DAY_OF_WEEK)
+ {
+ roundingCode = Calendar.DAY_OF_MONTH;
+ }
+ for (int i = 0; i < calendarUnits.length; i++)
+ {
+ if (calendarUnits[i] == roundingCode)
+ {
+ break;
+ }
+ if (i == calendarUnits.length - 1)
+ {
+ throw new IllegalArgumentException("Unsupported Calendar Unit: " + calendarCode);
+ }
+ c.set(calendarUnits[i], c.getMinimum(calendarUnits[i]));
+ }
+ if (quantity > 1)
+ {
+ c.set(calendarCode, quantity * (c.get(calendarCode) / quantity));
+ }
+ }
+
+ // if rounding up, then add a unit at current granularity.
+ if (up)
+ {
+ c.add(calendarCode, quantity);
+ }
+
+ return new RoughTime(c.getTimeInMillis(), this);
+ }
+
+ public int get(long timestamp)
+ {
+ Calendar c = TimeUtils.cal(timestamp);
+ int n = c.get(calendarCode);
+ return quantity == 1 ? n : n % quantity;
+ }
+
+ public void addTo(RoughTime r)
+ {
+ addTo(r, 1);
+ }
+
+ public void addTo(RoughTime r, int times)
+ {
+ Calendar c = TimeUtils.cal(r.getTime());
+ c.add(calendarCode, quantity * times);
+ r.setTime(c.getTimeInMillis());
+ }
+
+ // Finding the difference between two dates, in a given unit of time,
+ // is much subtler than you'd think! And annoyingly, the Calendar class does not do
+ // this for you, even though it actually "knows" how to do so since it
+ // can add fields.
+ //
+ // The most vexing problem is dealing with daylight savings time,
+ // which means that one day a year has 23 hours and one day has 25 hours.
+ // We also have to handle the fact that months and years aren't constant lengths.
+ //
+ // Rather than write all this ourselves, in this code we
+ // use the Calendar class to do the heavy lifting.
+ public long difference(long x, long y)
+ {
+ // If this is not one of the hard cases,
+ // just divide the timespan by the length of time unit.
+ // Note that we're not worrying about hours and daylight savings time.
+ if (calendarCode != Calendar.YEAR && calendarCode != Calendar.MONTH
+ && calendarCode != Calendar.DAY_OF_MONTH && calendarCode != Calendar.DAY_OF_WEEK
+ && calendarCode != Calendar.WEEK_OF_YEAR)
+ {
+ return (x - y) / roughSize;
+ }
+
+ Calendar c1 = TimeUtils.cal(x), c2 = TimeUtils.cal(y);
+ int diff = 0;
+ switch (calendarCode)
+ {
+ case Calendar.YEAR:
+ return (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR)) / quantity;
+
+ case Calendar.MONTH:
+ diff = 12 * (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR))
+ + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
+ return diff / quantity;
+
+ case Calendar.DAY_OF_MONTH:
+ case Calendar.DAY_OF_WEEK:
+ case Calendar.DAY_OF_YEAR:
+ case Calendar.WEEK_OF_MONTH:
+ case Calendar.WEEK_OF_YEAR:
+ // This is ugly, but believe me, it beats the alternative methods :-)
+ // We use the Calendar class's knowledge of daylight savings time.
+ // and also the fact that if we calculate this naively, then we aren't going
+ // to be off by more than one in either direction.
+ int naive = (int) Math.round((x - y) / (double) roughSize);
+ c2.add(calendarCode, naive * quantity);
+ if (c1.get(calendarCode) == c2.get(calendarCode))
+ {
+ return naive / quantity;
+ }
+ c2.add(calendarCode, quantity);
+ if (c1.get(calendarCode) == c2.get(calendarCode))
+ {
+ return naive / quantity + 1;
+ }
+ return naive / quantity - 1;
+ }
+ throw new IllegalArgumentException("Unexpected calendar code: " + calendarCode);
+ }
+
+ public long approxNumInRange(long start, long end)
+ {
+ return 1 + (end - start) / roughSize;
+ }
+
+ public long getRoughSize()
+ {
+ return roughSize;
+ }
+
+ public String format(Date date)
+ {
+ return format.format(date);
+ }
+
+ public String formatFull(Date date)
+ {
+ return fullFormat.format(date);
+ }
+
+ public String formatFull(long timestamp)
+ {
+ return fullFormat.format(new Date(timestamp));
+ }
+
+ public String getName()
+ {
+ return name;
+ }
}
diff --git a/timeflow/format/file/HtmlFormat.java b/timeflow/format/file/HtmlFormat.java
index cf50499..3792f28 100755
--- a/timeflow/format/file/HtmlFormat.java
+++ b/timeflow/format/file/HtmlFormat.java
@@ -9,135 +9,145 @@
public class HtmlFormat implements Export
{
- TFModel model;
- java.util.List<Field> fields;
- Field title;
-
- public HtmlFormat() {}
-
- public HtmlFormat(TFModel model)
- {
- setModel(model);
- }
-
- public void setModel(TFModel model)
- {
- this.model=model;
- fields=model.getDB().getFields();
- title=model.getDB().getField(VirtualField.LABEL);
- }
-
- @Override
- public void export(TFModel model, BufferedWriter out) throws Exception {
- setModel(model);
- out.write(makeHeader());
- for (Act a: model.getDB())
- out.write(makeItem(a));
- out.write(makeFooter());
- out.flush();
- }
-
- public void append(ActList acts, int start, int end, StringBuffer b)
- {
- for (int i=start; i<end; i++)
- {
- Act a=acts.get(i);
- b.append(makeItem(a,i));
- }
- }
-
- private String makeItem(Act act)
- {
- return makeItem(act, -1);
- }
-
- public String makeItem(Act act, int id)
- {
- StringBuffer page=new StringBuffer();
-
-
- page.append("<tr><td valign=top align=left width=200><b>");
- if (title!=null)
- {
- Field f=model.getColorField();
- Color c=Color.black;
- if (f!=null)
- {
- if (f.getType()==String.class)
- c=model.getDisplay().makeColor(act.getString(f));
- else
- {
- String[] tags=act.getTextList(f);
- if (tags.length==0)
- c=Color.gray;
- else
- c=model.getDisplay().makeColor(tags[0]);
- }
- }
-
- page.append("<font size=+1 color="+htmlColor(c)+">"+act.getString(title)+"</font><br>");
- }
-
- Field startField=model.getDB().getField(VirtualField.START);
-
- if (startField!=null)
- {
- page.append("<font color=#999999>"+model.getDisplay().format(
- act.getTime(startField))+"</font>");
- }
- page.append("</b><br>");
- if (id>=0)
- page.append("<a href=\"e"+id+"\">EDIT</a>");
- page.append("<br></td><td valign=top>");
- for (Field f: fields)
- {
- page.append("<b><font color=#003399>"+f.getName()+"</font></b> ");
- Object val=act.get(f);
- if (val instanceof URL)
- {
- page.append("<a href=\""+val+"\">"+val+"</a>");
- }
- else
- page.append(model.getDisplay().toString(val));
- page.append("<br>");
+ TFModel model;
+ java.util.List<Field> fields;
+ Field title;
- }
- page.append("<br></td></tr>");
+ public HtmlFormat()
+ {
+ }
- return page.toString();
- }
-
- public String makeHeader()
- {
- StringBuffer page=new StringBuffer();
- page.append("<html><body><blockquote>");
- page.append("<br>File: "+model.getDbFile()+"<br>");
- page.append("Source: "+model.getDB().getSource()+"<br><br>");
- page.append("<br><br>");
- page.append("<table border=0>");
+ public HtmlFormat(TFModel model)
+ {
+ setModel(model);
+ }
- return page.toString();
- }
-
- public String makeFooter()
- {
- return "</table></blockquote></body></html>";
- }
-
-
- static String htmlColor(Color c)
- {
- return '#'+hex2(c.getRed())+hex2(c.getGreen())+hex2(c.getBlue());
- }
-
- private static final String hexDigits="0123456789ABCDEF";
- private static String hex2(int n)
- {
- return hexDigits.charAt((n/16)%16)+""+hexDigits.charAt(n%16);
- }
- @Override
- public String getName() {
- return "HTML List";
- }
+ public void setModel(TFModel model)
+ {
+ this.model = model;
+ fields = model.getDB().getFields();
+ title = model.getDB().getField(VirtualField.LABEL);
+ }
+ @Override
+ public void export(TFModel model, BufferedWriter out) throws Exception
+ {
+ setModel(model);
+ out.write(makeHeader());
+ for (Act a : model.getDB())
+ {
+ out.write(makeItem(a));
+ }
+ out.write(makeFooter());
+ out.flush();
+ }
+
+ public void append(ActList acts, int start, int end, StringBuffer b)
+ {
+ for (int i = start; i < end; i++)
+ {
+ Act a = acts.get(i);
+ b.append(makeItem(a, i));
+ }
+ }
+
+ private String makeItem(Act act)
+ {
+ return makeItem(act, -1);
+ }
+
+ public String makeItem(Act act, int id)
+ {
+ StringBuffer page = new StringBuffer();
+
+ page.append("<tr><td valign=top align=left width=200><b>");
+ if (title != null)
+ {
+ Field f = model.getColorField();
+ Color c = Color.black;
+ if (f != null)
+ {
+ if (f.getType() == String.class)
+ {
+ c = model.getDisplay().makeColor(act.getString(f));
+ } else
+ {
+ String[] tags = act.getTextList(f);
+ if (tags.length == 0)
+ {
+ c = Color.gray;
+ } else
+ {
+ c = model.getDisplay().makeColor(tags[0]);
+ }
+ }
+ }
+
+ page.append("<font size=+1 color=" + htmlColor(c) + ">" + act.getString(title) + "</font><br>");
+ }
+
+ Field startField = model.getDB().getField(VirtualField.START);
+
+ if (startField != null)
+ {
+ page.append("<font color=#999999>" + model.getDisplay().format(act.getTime(startField)) + "</font>");
+ }
+ page.append("</b><br>");
+ if (id >= 0)
+ {
+ page.append("<a href=\"e" + id + "\">EDIT</a>");
+ }
+ page.append("<br></td><td valign=top>");
+ for (Field f : fields)
+ {
+ page.append("<b><font color=#003399>" + f.getName() + "</font></b> ");
+ Object val = act.get(f);
+ if (val instanceof URL)
+ {
+ page.append("<a href=\"" + val + "\">" + val + "</a>");
+ } else
+ {
+ page.append(model.getDisplay().toString(val));
+ }
+ page.append("<br>");
+
+ }
+ page.append("<br></td></tr>");
+
+ return page.toString();
+ }
+
+ public String makeHeader()
+ {
+ StringBuffer page = new StringBuffer();
+ page.append("<html><body><blockquote>");
+ page.append("<br>File: " + model.getDbFile() + "<br>");
+ page.append("Source: " + model.getDB().getSource() + "<br><br>");
+ page.append("<br><br>");
+ page.append("<table border=0>");
+
+ return page.toString();
+ }
+
+ public String makeFooter()
+ {
+ return "</table></blockquote></body></html>";
+ }
+
+ static String htmlColor(Color c)
+ {
+ return '#' + hex2(c.getRed()) + hex2(c.getGreen()) + hex2(c.getBlue());
+ }
+ private static final String hexDigits = "0123456789ABCDEF";
+
+ private static String hex2(int n)
+ {
+ return hexDigits.charAt((n / 16) % 16) + "" + hexDigits.charAt(n % 16);
+ }
+
+ @Override
+ public String getName()
+ {
+ return "HTML List";
+ }
}
diff --git a/timeflow/views/AbstractVisualizationView.java b/timeflow/views/AbstractVisualizationView.java
index 51026d6..349ee29 100755
--- a/timeflow/views/AbstractVisualizationView.java
+++ b/timeflow/views/AbstractVisualizationView.java
@@ -31,6 +31,10 @@
{
this.model = model;
+ final JPopupMenu popup = new JPopupMenu();
+ final JMenuItem edit = new JMenuItem("Edit");
+ final JMenuItem delete = new JMenuItem("Delete");
+
// deal with mouseovers.
addMouseMotionListener(new MouseMotionListener()
{
@@ -50,9 +54,6 @@
}
});
-
- final JPopupMenu popup = new JPopupMenu();
- final JMenuItem edit = new JMenuItem("Edit");
edit.addActionListener(new ActionListener()
{
@@ -64,7 +65,6 @@
});
popup.add(edit);
- final JMenuItem delete = new JMenuItem("Delete");
popup.add(delete);
delete.addActionListener(new ActionListener()
{
diff --git a/timeflow/views/ListView.java b/timeflow/views/ListView.java
index ec87f1c..1302bfa 100755
--- a/timeflow/views/ListView.java
+++ b/timeflow/views/ListView.java
@@ -20,247 +20,266 @@
import java.net.URL;
import java.util.*;
-public class ListView extends AbstractView {
+public class ListView extends AbstractView
+{
+ private JEditorPane listDisplay;
+ private JComboBox sortMenu = new JComboBox();
+ private ActComparator sort;//=ActComparator.byTime();
+ private int maxPerPage = 50;
+ private int pageStart = 0;
+ private int lastSize = 0;
+ private ActList acts;
+ private Field sortField;
+ private JLabel pageLabel = new JLabel("Page", JLabel.LEFT);
+ private JComboBox pageMenu = new JComboBox();
+ private boolean changing = false;
+ private JPanel controls;
- private JEditorPane listDisplay;
- private JComboBox sortMenu=new JComboBox();
- private ActComparator sort;//=ActComparator.byTime();
- private int maxPerPage=50;
- private int pageStart=0;
- private int lastSize=0;
- private ActList acts;
- private Field sortField;
-
- private JLabel pageLabel=new JLabel("Page", JLabel.LEFT);
- private JComboBox pageMenu=new JComboBox();
- private boolean changing=false;
-
- private JPanel controls;
-
- public ListView(TFModel model)
- {
- super(model);
-
- listDisplay=HtmlDisplay.create();
- listDisplay.addHyperlinkListener(new LinkIt());
- JScrollPane scrollPane = new JScrollPane(listDisplay);
- setLayout(new BorderLayout());
- add(scrollPane, BorderLayout.CENTER);
-
-
- controls=new JPanel();
- controls.setLayout(null);
- controls.setBackground(Color.white);
-
- int x=10, y=10;
- int ch=25, pad=5, cw=160;
- JLabel sortLabel=new JLabel("Sort Order", JLabel.LEFT);
- controls.add(sortLabel);
- sortLabel.setBounds(x,y,cw,ch);
- y+=ch+pad;
-
- controls.add(sortMenu);
- sortMenu.setBounds(x,y,cw,ch);
- y+=ch+3*pad;
-
- controls.add(pageLabel);
- pageLabel.setBounds(x,y,cw,ch);
- y+=ch+pad;
- controls.add(pageMenu);
- pageMenu.setBounds(x,y,cw,ch);
-
- showPageMenu(false);
- pageMenu.addActionListener(pageListener);
- sortMenu.addActionListener(sortListener);
- }
-
- protected JComponent _getControls()
- {
- return controls;
- }
-
- ActionListener sortListener=new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- if (changing || sortMenu.getItemCount()<=0) // this means the action was fired after all items removed.
- return;
- sortField=getModel().getDB().getField((String)sortMenu.getSelectedItem());
- sort=sortField==null ? null : ActComparator.by(sortField);
- setToFirstPage();
- makeList();
- }};
-
- ActionListener pageListener=new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- if (changing)
- return;
- pageStart=maxPerPage*pageMenu.getSelectedIndex();
- System.out.println(e.getActionCommand());
- makeList();
- }};
-
- @Override
- protected void onscreen(boolean majorChange)
- {
- _note(null);
- }
-
- public void _note(TFEvent e) {
- changing=true;
- if (e==null || e.affectsSchema() || e.affectsRowSet())
- {
- sortMenu.removeActionListener(sortListener);
- sortMenu.removeAllItems();
- pageStart=0;
- java.util.List<Field> fields=getModel().getDB().getFields();
- Field firstField=null;
- if (fields.size()>0)
- firstField=fields.get(0);
- for (Field f: fields)
- {
- sortMenu.addItem(f.getName());
- }
- sortField=getModel().getDB().getField(VirtualField.START);
- if (sortField!=null)
- sortMenu.setSelectedItem(sortField.getName());
- else
- sortField=firstField;
- sortMenu.addActionListener(sortListener);
- sort=null;
- }
- if (e!=null && e.affectsData())
- {
- setToFirstPage();
- }
- changing=false;
- makeList();
- }
-
- private void setToFirstPage()
- {
- pageStart=0;
- if (pageMenu.isVisible())
- {
- pageMenu.removeActionListener(pageListener);
- pageMenu.setSelectedIndex(0);
- pageMenu.addActionListener(pageListener);
- }
- }
-
- void showPageMenu(boolean visible)
- {
- pageLabel.setVisible(visible);
- pageMenu.setVisible(visible);
- if (visible)
- {
- pageMenu.removeActionListener(pageListener);
- pageMenu.setSelectedIndex(pageStart/maxPerPage);
- pageMenu.addActionListener(pageListener);
- }
- }
-
-
- void makeList()
- {
- HtmlFormat html=new HtmlFormat();
- html.setModel(getModel());
- StringBuffer page=new StringBuffer();
-
- page.append(html.makeHeader());
-
-
- ActList as=getModel().getActs();
- if (as==null || as.size()==0 && getModel().getDB().size()==0)
- {
- page.append("<tr><td><h1><font color=#003399>Empty Database</font></h1></td></tr>");
- showPageMenu(false);
- }
- else
- {
-
- if (sort==null)
- {
- Field timeField=getModel().getDB().getField(VirtualField.START);
- if (timeField!=null)
- sort=ActComparator.by(timeField);
- }
+ public ListView(TFModel model)
+ {
+ super(model);
- acts=as.copy();
- if (sort!=null)
- Collections.sort(acts, sort);
-
- boolean pages=acts.size()>maxPerPage;
- int last=Math.min(acts.size(), pageStart+maxPerPage);
- if (pages)
- {
- int n=acts.size();
- if (lastSize!=n)
- {
- pageMenu.removeActionListener(pageListener);
- pageMenu.removeAllItems();
- for (int i=0; i*maxPerPage<n;i++)
- {
- pageMenu.addItem("Items "+((i*maxPerPage)+1)+" to "+
- Math.min(n, (i+1)*maxPerPage));
- }
- pageMenu.addActionListener(pageListener);
- lastSize=n;
- }
- }
- showPageMenu(pages);
-
- page.append("<tr><td><h1><font color=#003399>"+(pages? (pageStart+1)+"-"+(last) +" of ": "")+acts.size()+" Events</font></h1>");
- page.append("<br><br></td></tr>");
+ listDisplay = HtmlDisplay.create();
+ listDisplay.addHyperlinkListener(new LinkIt());
+ JScrollPane scrollPane = new JScrollPane(listDisplay);
+ setLayout(new BorderLayout());
+ add(scrollPane, BorderLayout.CENTER);
- for (int i=pageStart; i<last; i++)
- {
- Act a=acts.get(i);
- page.append(html.makeItem(a,i));
- }
- }
- page.append(html.makeFooter());
- listDisplay.setText(page.toString());
- listDisplay.setCaretPosition(0);
- repaint();
- }
-
-
-
-
- @Override
- public String getName() {
- return "List";
- }
-
- static class ArrayRenderer extends DefaultTableCellRenderer {
- public void setValue(Object value) {
- setText(Display.arrayToString((Object[])value));
- }
- }
-
- public class LinkIt implements HyperlinkListener
- {
- public void hyperlinkUpdate(HyperlinkEvent e)
- {
- if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED)
- return;
-
- String s=e.getDescription();
- System.out.println(s);
- if (s.length()>0)
- {
- char c=s.charAt(0);
- if (c=='e') // code for "edit"
- {
- int i=Integer.parseInt(s.substring(1));
- EditRecordPanel.edit(getModel(), acts.get(i));
- return;
- }
-
- }
- Display.launchBrowser(e.getURL().toString());
-
- }
- }
+
+ controls = new JPanel();
+ controls.setLayout(null);
+ controls.setBackground(Color.white);
+
+ int x = 10, y = 10;
+ int ch = 25, pad = 5, cw = 160;
+ JLabel sortLabel = new JLabel("Sort Order", JLabel.LEFT);
+ controls.add(sortLabel);
+ sortLabel.setBounds(x, y, cw, ch);
+ y += ch + pad;
+
+ controls.add(sortMenu);
+ sortMenu.setBounds(x, y, cw, ch);
+ y += ch + 3 * pad;
+
+ controls.add(pageLabel);
+ pageLabel.setBounds(x, y, cw, ch);
+ y += ch + pad;
+ controls.add(pageMenu);
+ pageMenu.setBounds(x, y, cw, ch);
+
+ showPageMenu(false);
+ pageMenu.addActionListener(pageListener);
+ sortMenu.addActionListener(sortListener);
+ }
+
+ protected JComponent _getControls()
+ {
+ return controls;
+ }
+ ActionListener sortListener = new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (changing || sortMenu.getItemCount() <= 0) // this means the action was fired after all items removed.
+ {
+ return;
+ }
+ sortField = getModel().getDB().getField((String) sortMenu.getSelectedItem());
+ sort = sortField == null ? null : ActComparator.by(sortField);
+ setToFirstPage();
+ makeList();
+ }
+ };
+ ActionListener pageListener = new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ if (changing)
+ {
+ return;
+ }
+ pageStart = maxPerPage * pageMenu.getSelectedIndex();
+ System.out.println(e.getActionCommand());
+ makeList();
+ }
+ };
+
+ @Override
+ protected void onscreen(boolean majorChange)
+ {
+ _note(null);
+ }
+
+ public void _note(TFEvent e)
+ {
+ changing = true;
+ if (e == null || e.affectsSchema() || e.affectsRowSet())
+ {
+ sortMenu.removeActionListener(sortListener);
+ sortMenu.removeAllItems();
+ pageStart = 0;
+ java.util.List<Field> fields = getModel().getDB().getFields();
+ Field firstField = null;
+ if (fields.size() > 0)
+ {
+ firstField = fields.get(0);
+ }
+ for (Field f : fields)
+ {
+ sortMenu.addItem(f.getName());
+ }
+ sortField = getModel().getDB().getField(VirtualField.START);
+ if (sortField != null)
+ {
+ sortMenu.setSelectedItem(sortField.getName());
+ } else
+ {
+ sortField = firstField;
+ }
+ sortMenu.addActionListener(sortListener);
+ sort = null;
+ }
+ if (e != null && e.affectsData())
+ {
+ setToFirstPage();
+ }
+ changing = false;
+ makeList();
+ }
+
+ private void setToFirstPage()
+ {
+ pageStart = 0;
+ if (pageMenu.isVisible())
+ {
+ pageMenu.removeActionListener(pageListener);
+ pageMenu.setSelectedIndex(0);
+ pageMenu.addActionListener(pageListener);
+ }
+ }
+
+ void showPageMenu(boolean visible)
+ {
+ pageLabel.setVisible(visible);
+ pageMenu.setVisible(visible);
+ if (visible)
+ {
+ pageMenu.removeActionListener(pageListener);
+ pageMenu.setSelectedIndex(pageStart / maxPerPage);
+ pageMenu.addActionListener(pageListener);
+ }
+ }
+
+ void makeList()
+ {
+ HtmlFormat html = new HtmlFormat();
+ html.setModel(getModel());
+ StringBuffer page = new StringBuffer();
+
+ page.append(html.makeHeader());
+
+ ActList as = getModel().getActs();
+ if (as == null || as.size() == 0 && getModel().getDB().size() == 0)
+ {
+ page.append("<tr><td><h1><font color=#003399>Empty Database</font></h1></td></tr>");
+ showPageMenu(false);
+ } else
+ {
+
+ if (sort == null)
+ {
+ Field timeField = getModel().getDB().getField(VirtualField.START);
+ if (timeField != null)
+ {
+ sort = ActComparator.by(timeField);
+ }
+ }
+
+ acts = as.copy();
+ if (sort != null)
+ {
+ Collections.sort(acts, sort);
+ }
+
+ boolean pages = acts.size() > maxPerPage;
+ int last = Math.min(acts.size(), pageStart + maxPerPage);
+ if (pages)
+ {
+ int n = acts.size();
+ if (lastSize != n)
+ {
+ pageMenu.removeActionListener(pageListener);
+ pageMenu.removeAllItems();
+ for (int i = 0; i * maxPerPage < n; i++)
+ {
+ pageMenu.addItem("Items " + ((i * maxPerPage) + 1) + " to "
+ + Math.min(n, (i + 1) * maxPerPage));
+ }
+ pageMenu.addActionListener(pageListener);
+ lastSize = n;
+ }
+ }
+ showPageMenu(pages);
+
+ page.append("<tr><td><h1><font color=#003399>" + (pages ? (pageStart + 1) + "-" + (last) + " of " : "") + acts.size() + " Events</font></h1>");
+ page.append("<br><br></td></tr>");
+
+ for (int i = pageStart; i < last; i++)
+ {
+ Act a = acts.get(i);
+ page.append(html.makeItem(a, i));
+ }
+ }
+ page.append(html.makeFooter());
+ listDisplay.setText(page.toString());
+ listDisplay.setCaretPosition(0);
+ repaint();
+ }
+
+ @Override
+ public String getName()
+ {
+ return "List";
+ }
+
+ static class ArrayRenderer extends DefaultTableCellRenderer
+ {
+
+ public void setValue(Object value)
+ {
+ setText(Display.arrayToString((Object[]) value));
+ }
+ }
+
+ public class LinkIt implements HyperlinkListener
+ {
+
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType() != HyperlinkEvent.EventType.ACTIVATED)
+ {
+ return;
+ }
+
+ String s = e.getDescription();
+ System.out.println(s);
+ if (s.length() > 0)
+ {
+ char c = s.charAt(0);
+ if (c == 'e') // code for "edit"
+ {
+ int i = Integer.parseInt(s.substring(1));
+ EditRecordPanel.edit(getModel(), acts.get(i));
+ return;
+ }
+
+ }
+ Display.launchBrowser(e.getURL().toString());
+
+ }
+ }
}
diff --git a/timeflow/views/TimelineView.java b/timeflow/views/TimelineView.java
index 778ece2..06190c6 100755
--- a/timeflow/views/TimelineView.java
+++ b/timeflow/views/TimelineView.java
@@ -1,21 +1,24 @@
package timeflow.views;
import timeflow.app.ui.ComponentCluster;
-import timeflow.data.db.*;
+import timeflow.app.ui.EditRecordPanel;
+import timeflow.data.db.DBUtils;
import timeflow.data.time.*;
import timeflow.model.*;
-import timeflow.views.CalendarView.CalendarPanel;
-import timeflow.views.CalendarView.ScrollingCalendar;
-import timeflow.vis.*;
+//import timeflow.views.CalendarView.CalendarPanel;
+//import timeflow.views.CalendarView.ScrollingCalendar;
+import timeflow.vis.Mouseover;
+import timeflow.vis.TimeScale;
+import timeflow.vis.VisualAct;
import timeflow.vis.timeline.*;
import java.awt.*;
import java.awt.event.*;
-import java.awt.image.*;
+//import java.awt.image.*;
import javax.swing.*;
-import java.util.*;
+import java.util.ArrayList;
public class TimelineView extends AbstractView
{
@@ -67,12 +70,23 @@
// top part of grid: zoom buttons.
ComponentCluster buttons = new ComponentCluster("Zoom");
- ImageIcon zoomOutIcon = new ImageIcon("images/zoom_out.gif");
- JButton zoomOut = new JButton(zoomOutIcon);
+ //ImageIcon zoomOutIcon = new ImageIcon("images/zoom_out.gif");
+ JButton zoomIn = new JButton("In 1/2X");
+ buttons.addContent(zoomIn);
+ zoomIn.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ Interval zoom = visuals.getViewInterval().subinterval(0.333, 0.667).intersection(visuals.getGlobalInterval());
+ moveTime(zoom);
+ }
+ });
+
+ JButton zoomOut = new JButton("Out 2X");
buttons.addContent(zoomOut);
zoomOut.addActionListener(new ActionListener()
{
-
@Override
public void actionPerformed(ActionEvent e)
{
@@ -82,7 +96,7 @@
});
ImageIcon zoomOut100Icon = new ImageIcon("images/zoom_out_100.gif");
- JButton zoomOutAll = new JButton(zoomOut100Icon);
+ JButton zoomOutAll = new JButton("Fit 100%");
buttons.addContent(zoomOutAll);
zoomOutAll.addActionListener(new ActionListener()
{
@@ -221,17 +235,27 @@
public void run()
{
- int n = 15;
+ int n = 8;
for (int i = 0; i < n; i++)
{
- long start = ((n - i) * i1.start + i * i2.start) / n;
- long end = ((n - i) * i1.end + i * i2.end) / n;
+ final long start = ((n - i) * i1.start + i * i2.start) / n;
+ final long end = ((n - i) * i1.end + i * i2.end) / n;
try
{
- visuals.setTimeBounds(start, end);
- redraw();
+// visuals.setTimeBounds(start, end);
+// redraw();
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ visuals.setTimeBounds(start, end);
+ redraw();
+ }
+ });
- sleep(20);
+ //sleep(20);
} catch (Exception e)
{
}
@@ -312,7 +336,20 @@
{
if (e.getClickCount() == 2)
{
- moveTime(visuals.getViewInterval().subinterval(.333, .667));
+ Point p = new Point(e.getX(), e.getY());
+ Mouseover o = find(p);
+ //moveTime(visuals.getViewInterval().subinterval(.333, .667));
+ boolean onAct = o != null && o.thing instanceof VisualAct;
+ if (onAct)
+ {
+ VisualAct v = (VisualAct) o.thing;
+ selectedAct = v.getAct();
+ EditRecordPanel.edit(getModel(), selectedAct);
+ } else
+ {
+ selectedTime = getTime(p);
+ EditRecordPanel.add(getModel(), selectedTime);
+ }
}
}
@@ -358,6 +395,11 @@
int a = firstMouse.x;
int b = mouse.x;
+ if (a == b)
+ {
+ return;
+ }
+
long start = visuals.getTimeScale().toTime(a);
long end = visuals.getTimeScale().toTime(b);
if (b - a < 0)
@@ -397,12 +439,18 @@
@Override
public void mouseWheelMoved(MouseWheelEvent e)
{
- //bar.setValue(bar.getValue() + e.getWheelRotation() * 10);
- visuals.scale *= Math.exp(e.getWheelRotation()/10.0);
- visuals.scale = visuals.layout();
- //System.out.println(visuals.scale);
- timelinePanel.drawVisualization();
- scroller.calibrate();
+ if (e.isMetaDown())
+ {
+ visuals.scale *= Math.exp(e.getWheelRotation()/10.0);
+ visuals.scale = visuals.layout();
+ //System.out.println(visuals.scale);
+ timelinePanel.drawVisualization();
+ scroller.calibrate();
+ }
+ else
+ {
+ bar.setValue(bar.getValue() + e.getWheelRotation() * 40);
+ }
repaint();
}
});
diff --git a/timeflow/vis/Mouseover.java b/timeflow/vis/Mouseover.java
index adf3009..eb2b74b 100755
--- a/timeflow/vis/Mouseover.java
+++ b/timeflow/vis/Mouseover.java
@@ -5,90 +5,94 @@
import java.awt.*;
import java.util.ArrayList;
-public class Mouseover extends Rectangle {
- public Object thing;
- public Mouseover(Object thing, int x, int y, int w, int h)
- {
- super(x,y,w,h);
- this.thing=thing;
- }
-
- public void draw(Graphics2D g, int maxW, int maxH, Display display)
- {
- g.setColor(new Color(0,53,153));
- g.setColor(new Color(255,255,0,100));
- g.fill(this);
- }
-
- protected void draw(Graphics2D g, int maxW, int maxH, Display display, ArrayList labels, int numLines)
- {
- if (labels==null || labels.size()==0)
- return;
-
- // draw a background box.
-
- // find max number of chars, very very roughly!
- int boxW=50;
- for (int i=0; i<labels.size(); i+=2)
- {
- if (labels.get(i) instanceof String[])
- boxW=300;
- else if (labels.get(i) instanceof String)
- {
- boxW=Math.max(boxW, 50+50*((String)labels.get(i)).length());
- }
- }
-
-
- boxW=Math.min(350, boxW);
- int boxH=18*numLines+10;
- int mx=this.x+this.width+5;
- int my=this.y+this.height+35;
-
- // put box in a place where it does not obscure the data
- // or go off screen.
- if (my+boxH>maxH-10)
- {
- my=Math.max(10,this.y-boxH-5);
- }
- if (mx+boxW>maxW-10)
- {
- mx=Math.max(10,this.x-boxW-10);
- }
- int ty=my;
- g.setColor(new Color(0,0,0,70));
- g.fillRoundRect(mx-11, my-16, boxW, boxH,12,12);
- g.setColor(Color.white);
- g.fillRoundRect(mx-15, my-20, boxW, boxH,12,12);
- g.setColor(Color.darkGray);
- g.drawRoundRect(mx-15, my-20, boxW, boxH,12,12);
-
- // finally, draw the darn labels.
- for (int i=0; i<labels.size(); i+=2)
- {
- g.setFont(display.bold());
- String field=(String)labels.get(i);
- g.drawString(field,mx,ty);
- int sw=display.boldFontMetrics().stringWidth(field);
- g.setFont(display.plain());
- Object o=labels.get(i+1);
- if (o instanceof String)
- {
- g.drawString((String)o,mx+sw+9,ty);
- ty+=18;
- }
- else
- {
- ArrayList<String> lines=(ArrayList<String>)o;
- int dx=sw+9;
- for (String line: lines)
- {
- g.drawString((String)line,mx+dx,ty);
- ty+=18;
- dx=0;
- }
- ty+=5;
- }
- }
- }
+public class Mouseover extends Rectangle
+{
+ public Object thing;
+
+ public Mouseover(Object thing, int x, int y, int w, int h)
+ {
+ super(x, y, w, h);
+ this.thing = thing;
+ }
+
+ public void draw(Graphics2D g, int maxW, int maxH, Display display)
+ {
+ g.setColor(new Color(0, 53, 153));
+ g.setColor(new Color(255, 255, 0, 100));
+ g.fill(this);
+ }
+
+ protected void draw(Graphics2D g, int maxW, int maxH, Display display, ArrayList labels, int numLines)
+ {
+ if (labels == null || labels.size() == 0)
+ {
+ return;
+ }
+
+ // draw a background box.
+
+ // find max number of chars, very very roughly!
+ int boxW = 50;
+ for (int i = 0; i < labels.size(); i += 2)
+ {
+ if (labels.get(i) instanceof String[])
+ {
+ boxW = 300;
+ } else if (labels.get(i) instanceof String)
+ {
+ boxW = Math.max(boxW, 50 + 50 * ((String) labels.get(i)).length());
+ }
+ }
+
+
+ boxW = Math.min(350, boxW);
+ int boxH = 18 * numLines + 10;
+ int mx = this.x + this.width + 5;
+ int my = this.y + this.height + 35;
+
+ // put box in a place where it does not obscure the data
+ // or go off screen.
+ if (my + boxH > maxH - 10)
+ {
+ my = Math.max(10, this.y - boxH - 5);
+ }
+ if (mx + boxW > maxW - 10)
+ {
+ mx = Math.max(10, this.x - boxW - 10);
+ }
+ int ty = my;
+ g.setColor(new Color(0, 0, 0, 70));
+ g.fillRoundRect(mx - 11, my - 16, boxW, boxH, 12, 12);
+ g.setColor(Color.white);
+ g.fillRoundRect(mx - 15, my - 20, boxW, boxH, 12, 12);
+ g.setColor(Color.darkGray);
+ g.drawRoundRect(mx - 15, my - 20, boxW, boxH, 12, 12);
+
+ // finally, draw the darn labels.
+ for (int i = 0; i < labels.size(); i += 2)
+ {
+ g.setFont(display.bold());
+ String field = (String) labels.get(i);
+ g.drawString(field, mx, ty);
+ int sw = display.boldFontMetrics().stringWidth(field);
+ g.setFont(display.plain());
+ Object o = labels.get(i + 1);
+ if (o instanceof String)
+ {
+ g.drawString((String) o, mx + sw + 9, ty);
+ ty += 18;
+ } else
+ {
+ ArrayList<String> lines = (ArrayList<String>) o;
+ int dx = sw + 9;
+ for (String line : lines)
+ {
+ g.drawString((String) line, mx + dx, ty);
+ ty += 18;
+ dx = 0;
+ }
+ ty += 5;
+ }
+ }
+ }
}
diff --git a/timeflow/vis/VisualAct.java b/timeflow/vis/VisualAct.java
index 4c3569b..1351c06 100755
--- a/timeflow/vis/VisualAct.java
+++ b/timeflow/vis/VisualAct.java
@@ -12,7 +12,6 @@
public class VisualAct implements Comparable
{
-
Color color;
String label;
String mouseOver;
diff --git a/timeflow/vis/timeline/AxisRenderer.java b/timeflow/vis/timeline/AxisRenderer.java
index 7d020cb..0372be6 100755
--- a/timeflow/vis/timeline/AxisRenderer.java
+++ b/timeflow/vis/timeline/AxisRenderer.java
@@ -9,80 +9,83 @@
import timeflow.vis.Mouseover;
import timeflow.vis.TimeScale;
-public class AxisRenderer {
-
- TimelineVisuals visuals;
-
- public AxisRenderer(TimelineVisuals visuals)
- {
- this.visuals=visuals;
- }
-
- public void render(Graphics2D g, Collection<Mouseover> objectLocations)
- {
- TFModel model=visuals.getModel();
- g.setColor(model.getDisplay().getColor("chart.background"));
- Rectangle bounds=visuals.getBounds();
-
- TimeScale scale=visuals.getTimeScale();
- java.util.List<AxisTicMarks> t=AxisTicMarks.allRelevant(scale.getInterval());
-
- int dateLabelH=model.getDisplay().getInt("timeline.datelabel.height");
- int y=bounds.y+bounds.height-dateLabelH;
-
- // draw in reverse order so bigger granularity at top.
- int n=t.size();
- for (int i=0; i<n; i++)
- {
- render(t.get(i), g, bounds.x, y, dateLabelH-1, bounds.y, i==0, objectLocations);
- y-=dateLabelH;
- }
- }
-
- void render(AxisTicMarks t, Graphics2D g, int x, int y, int h, int top, boolean full, Collection<Mouseover> objectLocations)
- {
- TFModel model=visuals.getModel();
+public class AxisRenderer
+{
+ TimelineVisuals visuals;
- int n=t.tics.size();
- for (int i=0; i<n-1; i++)
- {
-
- long start=t.tics.get(i);
- long end=t.tics.get(i+1);
-
- int x0=Math.max(x,visuals.getTimeScale().toInt(start));
- int x1=visuals.getTimeScale().toInt(end);
-
- int dayOfWeek=TimeUtils.cal(start).get(Calendar.DAY_OF_WEEK);
-
- g.setColor(t.unit.isDayOrLess() && (dayOfWeek==1 || dayOfWeek==7) ?
- new Color(245,245,245) : new Color(240,240,240));
+ public AxisRenderer(TimelineVisuals visuals)
+ {
+ this.visuals = visuals;
+ }
- g.fillRect(x0, y, x1-x0-1, h);
- g.setColor(Color.white);
- g.drawLine(x1-1, y, x1-1, y+h);
- g.drawLine(x0,y+h,x1,y+h);
- objectLocations.add(new Mouseover(new Interval(start,end), x0, y, x1-x0-1, h));
-
- g.setFont(model.getDisplay().timeLabel());
- String label=full? t.unit.formatFull(start) : t.unit.format(new Date(start));
- int tx=x0+3;
- int ty=y+h-5;
- g.setColor(full ? Color.darkGray : Color.gray);
- int sw=model.getDisplay().timeLabelFontMetrics().stringWidth(label);
- if (sw<x1-tx-3)
- g.drawString(label, tx,ty);
- else
- {
- int c=label.indexOf(':');
- if (c>0)
- {
- label=label.substring(0,c);
- sw=model.getDisplay().timeLabelFontMetrics().stringWidth(label);
- if (sw<x1-tx-3)
- g.drawString(label, tx,ty);
- }
- }
- }
- }
+ public void render(Graphics2D g, Collection<Mouseover> objectLocations)
+ {
+ TFModel model = visuals.getModel();
+ g.setColor(model.getDisplay().getColor("chart.background"));
+ Rectangle bounds = visuals.getBounds();
+
+ TimeScale scale = visuals.getTimeScale();
+ java.util.List<AxisTicMarks> t = AxisTicMarks.allRelevant(scale.getInterval());
+
+ int dateLabelH = model.getDisplay().getInt("timeline.datelabel.height");
+ int y = bounds.y + bounds.height - dateLabelH;
+
+ // draw in reverse order so bigger granularity at top.
+ int n = t.size();
+ for (int i = 0; i < n; i++)
+ {
+ render(t.get(i), g, bounds.x, y, dateLabelH - 1, bounds.y, i == 0, objectLocations);
+ y -= dateLabelH;
+ }
+ }
+
+ void render(AxisTicMarks t, Graphics2D g, int x, int y, int h, int top, boolean full, Collection<Mouseover> objectLocations)
+ {
+ TFModel model = visuals.getModel();
+
+ int n = t.tics.size();
+ for (int i = 0; i < n - 1; i++)
+ {
+
+ long start = t.tics.get(i);
+ long end = t.tics.get(i + 1);
+
+ int x0 = Math.max(x, visuals.getTimeScale().toInt(start));
+ int x1 = visuals.getTimeScale().toInt(end);
+
+ int dayOfWeek = TimeUtils.cal(start).get(Calendar.DAY_OF_WEEK);
+
+ g.setColor(t.unit.isDayOrLess() && (dayOfWeek == 1 || dayOfWeek == 7)
+ ? new Color(245, 245, 245) : new Color(240, 240, 240));
+
+ g.fillRect(x0, y, x1 - x0 - 1, h);
+ g.setColor(Color.white);
+ g.drawLine(x1 - 1, y, x1 - 1, y + h);
+ g.drawLine(x0, y + h, x1, y + h);
+ objectLocations.add(new Mouseover(new Interval(start, end), x0, y, x1 - x0 - 1, h));
+
+ g.setFont(model.getDisplay().timeLabel());
+ String label = full ? t.unit.formatFull(start) : t.unit.format(new Date(start));
+ int tx = x0 + 3;
+ int ty = y + h - 5;
+ g.setColor(full ? Color.darkGray : Color.gray);
+ int sw = model.getDisplay().timeLabelFontMetrics().stringWidth(label);
+ if (sw < x1 - tx - 3)
+ {
+ g.drawString(label, tx, ty);
+ } else
+ {
+ int c = label.indexOf(':');
+ if (c > 0)
+ {
+ label = label.substring(0, c);
+ sw = model.getDisplay().timeLabelFontMetrics().stringWidth(label);
+ if (sw < x1 - tx - 3)
+ {
+ g.drawString(label, tx, ty);
+ }
+ }
+ }
+ }
+ }
}
diff --git a/timeflow/vis/timeline/AxisTicMarks.java b/timeflow/vis/timeline/AxisTicMarks.java
index 85a16dd..edbd96b 100755
--- a/timeflow/vis/timeline/AxisTicMarks.java
+++ b/timeflow/vis/timeline/AxisTicMarks.java
@@ -4,114 +4,116 @@
import timeflow.data.time.*;
-public class AxisTicMarks {
- public TimeUnit unit;
- public List<Long> tics;
-
- private static final TimeUnit[] units={
- TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.DAY, TimeUnit.HOUR, TimeUnit.MINUTE, TimeUnit.SECOND
- };
-
- private static final TimeUnit[] histUnits={
- TimeUnit.YEAR.times(100), TimeUnit.YEAR.times(50), TimeUnit.YEAR.times(25),
- TimeUnit.YEAR.times(10), TimeUnit.YEAR.times(5), TimeUnit.YEAR.times(2), TimeUnit.YEAR,
- TimeUnit.MONTH.times(6), TimeUnit.MONTH.times(3), TimeUnit.MONTH.times(2), TimeUnit.MONTH,
- TimeUnit.WEEK, TimeUnit.DAY.times(2), TimeUnit.DAY,
+public class AxisTicMarks
+{
+ public TimeUnit unit;
+ public List<Long> tics;
+ private static final TimeUnit[] units =
+ {
+ TimeUnit.YEAR, TimeUnit.MONTH, TimeUnit.DAY, TimeUnit.HOUR, TimeUnit.MINUTE, TimeUnit.SECOND
+ };
+ private static final TimeUnit[] histUnits =
+ {
+ TimeUnit.YEAR.times(100), TimeUnit.YEAR.times(50), TimeUnit.YEAR.times(25),
+ TimeUnit.YEAR.times(10), TimeUnit.YEAR.times(5), TimeUnit.YEAR.times(2), TimeUnit.YEAR,
+ TimeUnit.MONTH.times(6), TimeUnit.MONTH.times(3), TimeUnit.MONTH.times(2), TimeUnit.MONTH,
+ TimeUnit.WEEK, TimeUnit.DAY.times(2), TimeUnit.DAY,
+ TimeUnit.HOUR,
+ TimeUnit.MINUTE,
+ TimeUnit.SECOND
+ };
- TimeUnit.HOUR,
- TimeUnit.MINUTE,
- TimeUnit.SECOND
- };
-
- public AxisTicMarks(TimeUnit unit, long start, long end)
- {
- this.unit=unit;
- tics=new ArrayList<Long>();
- RoughTime r=unit.roundDown(start);
- tics.add(r.getTime());
- do
- {
- unit.addTo(r);
- tics.add(r.getTime());
- } while (r.getTime()<end);
- }
-
-
-
- public static List<AxisTicMarks> allRelevant(Interval interval)
- {
- return allRelevant(interval.start, interval.end);
- }
-
- public static List<AxisTicMarks> allRelevant(long start, long end)
- {
- return allRelevant(start, end, 40);
- }
-
- public static AxisTicMarks histoTics(long start, long end)
- {
- for (int i=histUnits.length-1; i>=0; i--)
- {
- TimeUnit u=histUnits[i];
- long estimate=u.approxNumInRange(start, end);
- if (estimate<200 || i==0)
- {
- AxisTicMarks t=new AxisTicMarks(u, start, end);
- return t;
- }
- }
- return null;
- }
-
- public static List<AxisTicMarks> allRelevant(long start, long end, long maxTics)
- {
- List<AxisTicMarks> list=new ArrayList<AxisTicMarks>();
-
-
- for (int i=0; i<units.length; i++)
- {
- TimeUnit u=units[i];
- long estimate=u.approxNumInRange(start, end);
-
- if (estimate<maxTics)
- {
- AxisTicMarks t=new AxisTicMarks(u, start, end);
- if (list.size()>0)
- {
- AxisTicMarks last=list.get(0);
- if (last.tics.size()==t.tics.size())
- list.remove(0);
- }
- list.add(t);
-
- }
- }
- while (list.size()>2)
- list.remove(0);
-
- if (list.size()==0) // uh oh! must be many years. we will add in bigger increments.
- {
- long length=end-start;
- long size=365*24*60*60*1000L;
- int m=1;
- maxTics=15;
- while (m<2000000000 && length/(m*size)>maxTics)
- {
- if (length/(2*m*size)<=maxTics)
- {
- m*=2;
- break;
- }
- if (length/(5*m*size)<=maxTics)
- {
- m*=5;
- break;
- }
- m*=10;
- }
- AxisTicMarks t=new AxisTicMarks(TimeUnit.multipleYears(m), start, end);
- list.add(t);
- }
- return list;
- }
+ public AxisTicMarks(TimeUnit unit, long start, long end)
+ {
+ this.unit = unit;
+ tics = new ArrayList<Long>();
+ RoughTime r = unit.roundDown(start);
+ tics.add(r.getTime());
+ do
+ {
+ unit.addTo(r);
+ tics.add(r.getTime());
+ } while (r.getTime() < end);
+ }
+
+ public static List<AxisTicMarks> allRelevant(Interval interval)
+ {
+ return allRelevant(interval.start, interval.end);
+ }
+
+ public static List<AxisTicMarks> allRelevant(long start, long end)
+ {
+ return allRelevant(start, end, 40);
+ }
+
+ public static AxisTicMarks histoTics(long start, long end)
+ {
+ for (int i = histUnits.length - 1; i >= 0; i--)
+ {
+ TimeUnit u = histUnits[i];
+ long estimate = u.approxNumInRange(start, end);
+ if (estimate < 200 || i == 0)
+ {
+ AxisTicMarks t = new AxisTicMarks(u, start, end);
+ return t;
+ }
+ }
+ return null;
+ }
+
+ public static List<AxisTicMarks> allRelevant(long start, long end, long maxTics)
+ {
+ List<AxisTicMarks> list = new ArrayList<AxisTicMarks>();
+
+
+ for (int i = 0; i < units.length; i++)
+ {
+ TimeUnit u = units[i];
+ long estimate = u.approxNumInRange(start, end);
+
+ if (estimate < maxTics)
+ {
+ AxisTicMarks t = new AxisTicMarks(u, start, end);
+ if (list.size() > 0)
+ {
+ AxisTicMarks last = list.get(0);
+ if (last.tics.size() == t.tics.size())
+ {
+ list.remove(0);
+ }
+ }
+ list.add(t);
+
+ }
+ }
+ while (list.size() > 2)
+ {
+ list.remove(0);
+ }
+
+ if (list.size() == 0) // uh oh! must be many years. we will add in bigger increments.
+ {
+ long length = end - start;
+ long size = 365 * 24 * 60 * 60 * 1000L;
+ int m = 1;
+ maxTics = 15;
+ while (m < 2000000000 && length / (m * size) > maxTics)
+ {
+ if (length / (2 * m * size) <= maxTics)
+ {
+ m *= 2;
+ break;
+ }
+ if (length / (5 * m * size) <= maxTics)
+ {
+ m *= 5;
+ break;
+ }
+ m *= 10;
+ }
+ AxisTicMarks t = new AxisTicMarks(TimeUnit.multipleYears(m), start, end);
+ list.add(t);
+ }
+ return list;
+ }
}
--
Gitblit v1.6.2