Elapsed time tick formatter

This commit is contained in:
Martin Pernollet 2014-10-05 13:09:01 +02:00
parent 7e8d6e9b8d
commit 2145230aa9
5 changed files with 296 additions and 219 deletions

View File

@ -12,7 +12,7 @@ import org.jzy3d.chart2d.primitives.LineSerie2d;
import org.jzy3d.chart2d.primitives.Serie2d; import org.jzy3d.chart2d.primitives.Serie2d;
import org.jzy3d.maths.BoundingBox3d; import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.plot3d.primitives.axes.layout.IAxeLayout; import org.jzy3d.plot3d.primitives.axes.layout.IAxeLayout;
import org.jzy3d.plot3d.primitives.axes.layout.renderers.DateTickRenderer; import org.jzy3d.plot3d.primitives.axes.layout.renderers.ElapsedTimeTickRenderer;
import org.jzy3d.plot3d.rendering.canvas.Quality; import org.jzy3d.plot3d.rendering.canvas.Quality;
import org.jzy3d.plot3d.rendering.view.View; import org.jzy3d.plot3d.rendering.view.View;
import org.jzy3d.plot3d.rendering.view.ViewportMode; import org.jzy3d.plot3d.rendering.view.ViewportMode;
@ -26,11 +26,43 @@ import org.jzy3d.plot3d.rendering.view.modes.ViewPositionMode;
// Interface de LineSerie fournie par Chart2d package, using x, y float args // Interface de LineSerie fournie par Chart2d package, using x, y float args
public class Chart2d extends AWTChart{ public class Chart2d extends AWTChart{
public Chart2d(){
public Chart2d() { this(new Chart2dComponentFactory(), Quality.Intermediate, Toolkit.newt.toString());
super();
IAxeLayout axe = getAxeLayout();
axe.setZAxeLabelDisplayed(false);
axe.setTickLineDisplayed(false);
View view = getView();
view.setViewPositionMode(ViewPositionMode.TOP);
view.setSquared(true);
view.getCamera().setViewportMode(ViewportMode.STRETCH_TO_FILL);
} }
public void asTimeChart(float timeMax, float ymin, float ymax, String xlabel, String ylabel){
IAxeLayout axe = getAxeLayout();
axe.setYAxeLabel(ylabel);
axe.setXAxeLabel( xlabel );
axe.setXTickRenderer( new ElapsedTimeTickRenderer() );
View view = getView();
view.setBoundManual(new BoundingBox3d(0, timeMax, ymin, ymax, -1, 1));
}
public Serie2d getSerie(String name){
Serie2d s = null;
if(!series.keySet().contains(name)){
s = new LineSerie2d(name);
addDrawable(s.getDrawable());
}
else{
s = series.get(name);
}
return s;
}
/* */
public Chart2d(IChartComponentFactory factory, Quality quality, String windowingToolkit, GLCapabilities capabilities) { public Chart2d(IChartComponentFactory factory, Quality quality, String windowingToolkit, GLCapabilities capabilities) {
super(factory, quality, windowingToolkit, capabilities); super(factory, quality, windowingToolkit, capabilities);
} }
@ -54,38 +86,8 @@ public class Chart2d extends AWTChart{
public Chart2d(String windowingToolkit) { public Chart2d(String windowingToolkit) {
super(windowingToolkit); super(windowingToolkit);
} }
public Chart2d(float timeMax, float ymin, float ymax, String xlabel, String ylabel){
this(new Chart2dComponentFactory(), Quality.Intermediate, Toolkit.newt.toString());
IAxeLayout axe = getAxeLayout();
axe.setYAxeLabel(ylabel);
axe.setXAxeLabel( xlabel );
axe.setZAxeLabelDisplayed(false);
axe.setTickLineDisplayed(false);
axe.setXTickRenderer( new DateTickRenderer( "mm:ss" ) );
View view = getView();
view.setViewPositionMode(ViewPositionMode.TOP);
view.setBoundManual(new BoundingBox3d(0, timeMax, ymin, ymax, -1, 1));
view.setSquared(true);
view.getCamera().setViewportMode(ViewportMode.STRETCH_TO_FILL);
}
public Serie2d getSerie(String name){ /* */
Serie2d s = null;
if(!series.keySet().contains(name)){
s = new LineSerie2d(name);
addDrawable(s.getDrawable());
}
else{
s = series.get(name);
}
return s;
}
Map<String,Serie2d> series = new HashMap<String,Serie2d>(); protected Map<String,Serie2d> series = new HashMap<String,Serie2d>();
} }

View File

@ -4,232 +4,271 @@ import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
public class Utils { public class Utils {
/** Convert a number into a string, with <code>precision</code> number of /**
* meaningfull digits. * Convert a number into a string, with <code>precision</code> number of
* * meaningfull digits.
* 'd' integral The result is formatted as a decimal integer *
* 'o' integral The result is formatted as an octal integer * 'd' integral The result is formatted as a decimal integer 'o' integral
* 'x', 'X' integral The result is formatted as a hexadecimal integer * The result is formatted as an octal integer 'x', 'X' integral The result
* 'e', 'E' floating point The result is formatted as a decimal number in computerized scientific notation * is formatted as a hexadecimal integer 'e', 'E' floating point The result
* 'f' floating point The result is formatted as a decimal number * is formatted as a decimal number in computerized scientific notation 'f'
* 'g', 'G' floating point The result is formatted using computerized scientific notation or decimal format, depending on the precision and the value after rounding. * floating point The result is formatted as a decimal number 'g', 'G'
* * floating point The result is formatted using computerized scientific
* @see http://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax * notation or decimal format, depending on the precision and the value
* @see String.format * after rounding.
*/ *
public static String num2str( char parseMode, double num, int precision ){ * @see http
return String.format( "%." + precision + parseMode, new Double(num) ); * ://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html#syntax
} * @see String.format
*/
/** Same as {@link num2str(char parseMode, double num, int precision)} but public static String num2str(char parseMode, double num, int precision) {
* does not query precision.*/ return String.format("%." + precision + parseMode, new Double(num));
public static String num2str( char parseMode, double num){ }
return String.format( "%" + parseMode, new Double(num) );
/**
* Same as {@link num2str(char parseMode, double num, int precision)} but
* does not query precision.
*/
public static String num2str(char parseMode, double num) {
return String.format("%" + parseMode, new Double(num));
}
public static String num2str(double num, int precision) {
return num2str('g', num, precision);
}
/** Convert a number into a string. */
public static String num2str(double num) {
return Double.toString(num);
}
/*************************************************************/
/** Convert a date to the format "dd/MM/yyyy HH:mm:ss". */
public static String dat2str(Date date) {
return dat2str(date, "dd/MM/yyyy HH:mm:ss");
}
/**
* Some example format dd.MM.yy 09.04.98 yyyy.MM.dd G 'at' hh:mm:ss z
* 1998.04.09 AD at 06:15:55 PDT EEE, MMM d, ''yy Thu, Apr 9, '98 h:mm a
* 6:15 PM H:mm 18:15 H:mm:ss:SSS 18:15:55:624 K:mm a,z 6:15 PM,PDT
* yyyy.MMMMM.dd GGG hh:mm aaa 1998.April.09 AD 06:15 PM
*
* @see http
* ://java.sun.com/docs/books/tutorial/i18n/format/simpleDateFormat.
* html
* @param date
* @param format
* @return
*/
public static String dat2str(Date date, String format) {
if (date == null)
return "";
SimpleDateFormat formatter;
formatter = new SimpleDateFormat(format, Locale.getDefault());
return formatter.format(date);
}
/*************************************************************/
public static long dat2num(Date date) {
if (date == null)
return 0;
return date.getTime();
}
public static Date num2dat(long value) {
return new Date(value);
}
public static String time2str(long milli) {
StringBuilder buf = new StringBuilder(20);
String sgn = "";
if (milli < 0) {
sgn = "-";
milli = Math.abs(milli);
}
append(buf, sgn, 0, (milli / 3600000));
append(buf, ":", 2, ((milli % 3600000) / 60000));
append(buf, ":", 2, ((milli % 60000) / 1000));
append(buf, ".", 3, (milli % 1000));
return buf.toString();
}
/**
* Append a right-aligned and zero-padded numeric value to a
* `StringBuilder`.
*/
private static void append(StringBuilder tgt, String pfx, int dgt, long val) {
tgt.append(pfx);
if (dgt > 1) {
int pad = (dgt - 1);
for (long xa = val; xa > 9 && pad > 0; xa /= 10) {
pad--;
}
for (int xa = 0; xa < pad; xa++) {
tgt.append('0');
}
}
tgt.append(val);
}
public static String blanks(int length) {
String b = "";
for (int i = 0; i < length; i++)
b += " ";
return b;
} }
public static String num2str( double num, int precision ){
return num2str( 'g', num, precision );
}
/** Convert a number into a string.*/
public static String num2str( double num ){
return Double.toString(num);
}
/*************************************************************/
/** Convert a date to the format "dd/MM/yyyy HH:mm:ss".*/
public static String dat2str(Date date){
return dat2str(date, "dd/MM/yyyy HH:mm:ss");
}
/**
* Some example format
* dd.MM.yy 09.04.98
* yyyy.MM.dd G 'at' hh:mm:ss z 1998.04.09 AD at 06:15:55 PDT
* EEE, MMM d, ''yy Thu, Apr 9, '98
* h:mm a 6:15 PM
* H:mm 18:15
* H:mm:ss:SSS 18:15:55:624
* K:mm a,z 6:15 PM,PDT
* yyyy.MMMMM.dd GGG hh:mm aaa 1998.April.09 AD 06:15 PM
*
* @see http://java.sun.com/docs/books/tutorial/i18n/format/simpleDateFormat.html
* @param date
* @param format
* @return
*/
public static String dat2str(Date date, String format){
if(date==null)
return "";
SimpleDateFormat formatter;
formatter = new SimpleDateFormat(format, Locale.getDefault());
return formatter.format(date);
}
/*************************************************************/
public static long dat2num(Date date){
if(date==null)
return 0;
return date.getTime();
}
public static Date num2dat(long value){
return new Date(value);
}
public static String blanks(int length){
String b = "";
for (int i = 0; i < length; i++)
b += " ";
return b;
}
/*****************************************************************************/ /*****************************************************************************/
/**
* Computes the absolute values of an array of doubles.
*
* @param values
* @return the sum of input values
*/
public static double[] abs(double[] values){
double[] output = new double[values.length];
for( int i=0; i<values.length; i++ )
output[i] = Math.abs(values[i]);
return output;
}
/** /**
* Computes the sum of an array of doubles. NaN values are ignored during the computation. * Computes the absolute values of an array of doubles.
* *
* @param values * @param values
* @return the sum of input values * @return the sum of input values
*/ */
public static double sum(double[] values){ public static double[] abs(double[] values) {
if(values.length==0) double[] output = new double[values.length];
throw new IllegalArgumentException("Input array must have a length greater than 0");
double total = 0; for (int i = 0; i < values.length; i++)
output[i] = Math.abs(values[i]);
for( int i=0; i<values.length; i++ ) return output;
if(!Double.isNaN(values[i])) }
total += values[i];
return total;
}
/**
* Computes the sum of an array of doubles. NaN values are ignored during the computation.
*
* @param values
* @return the sum of input values
*/
public static int sum(int[] values){
if(values.length==0)
throw new IllegalArgumentException("Input array must have a length greater than 0");
int total = 0;
for( int i=0; i<values.length; i++ )
total += values[i];
return total;
}
/** /**
* Generate a vector containing regular increasing values from min to max, with * Computes the sum of an array of doubles. NaN values are ignored during
* an offset of nstep. * the computation.
*
* @param values
* @return the sum of input values
*/
public static double sum(double[] values) {
if (values.length == 0)
throw new IllegalArgumentException("Input array must have a length greater than 0");
double total = 0;
for (int i = 0; i < values.length; i++)
if (!Double.isNaN(values[i]))
total += values[i];
return total;
}
/**
* Computes the sum of an array of doubles. NaN values are ignored during
* the computation.
*
* @param values
* @return the sum of input values
*/
public static int sum(int[] values) {
if (values.length == 0)
throw new IllegalArgumentException("Input array must have a length greater than 0");
int total = 0;
for (int i = 0; i < values.length; i++)
total += values[i];
return total;
}
/**
* Generate a vector containing regular increasing values from min to max,
* with an offset of nstep.
* *
* @param min * @param min
* @param max * @param max
* @param nstep * @param nstep
* @return * @return
*/ */
public static double[] vector(double min, double max, int nstep){ public static double[] vector(double min, double max, int nstep) {
double step = (max-min)/(nstep-1); double step = (max - min) / (nstep - 1);
double[] grid = new double[nstep]; double[] grid = new double[nstep];
for (int i = 0; i < grid.length; i++) { for (int i = 0; i < grid.length; i++) {
grid[i] = min + i*step; grid[i] = min + i * step;
} }
return grid; return grid;
} }
/** /**
* Generate a vector containing regular increasing values from min to max, with * Generate a vector containing regular increasing values from min to max,
* an offset 1. * with an offset 1.
* *
* @param min * @param min
* @param max * @param max
* @return * @return
*/ */
public static double[] vector(double min, double max){ public static double[] vector(double min, double max) {
return vector(min, max, (int)Math.abs(max-min)+1); return vector(min, max, (int) Math.abs(max - min) + 1);
} }
/** /**
* Generate a vector containing regular increasing values from min to max, with * Generate a vector containing regular increasing values from min to max,
* an offset of nstep. * with an offset of nstep.
* *
* @param min * @param min
* @param max * @param max
* @param nstep * @param nstep
* @return * @return
*/ */
public static int[] vector(int min, int max, int nstep){ public static int[] vector(int min, int max, int nstep) {
int step = (max-min)/(nstep-1); int step = (max - min) / (nstep - 1);
int[] grid = new int[nstep]; int[] grid = new int[nstep];
for (int i = 0; i < grid.length; i++) { for (int i = 0; i < grid.length; i++) {
grid[i] = min + i*step; grid[i] = min + i * step;
} }
return grid; return grid;
} }
/** /**
* Generate a vector containing regular increasing values from min to max, with * Generate a vector containing regular increasing values from min to max,
* an offset 1. * with an offset 1.
* *
* @param min * @param min
* @param max * @param max
* @return * @return
*/ */
public static int[] vector(int min, int max){ public static int[] vector(int min, int max) {
return vector( min, max, Math.abs(max-min)+1 ); return vector(min, max, Math.abs(max - min) + 1);
} }
/** /**
* Return the minimal date of an array * Return the minimal date of an array
*
* @param dates * @param dates
* @return * @return
*/ */
public static Date min(Date[] dates){ public static Date min(Date[] dates) {
if(dates.length==0) if (dates.length == 0)
throw new RuntimeException("input array is empty"); throw new RuntimeException("input array is empty");
Date min = new Date(Long.MAX_VALUE); Date min = new Date(Long.MAX_VALUE);
for(int i=0; i<dates.length; i++) for (int i = 0; i < dates.length; i++)
if(min.after(dates[i])) if (min.after(dates[i]))
min = dates[i]; min = dates[i];
return min; return min;
} }
/** /**
* Return the maximal date of an array * Return the maximal date of an array
*
* @param dates * @param dates
* @return * @return
*/ */
public static Date max(Date[] dates){ public static Date max(Date[] dates) {
if(dates.length==0) if (dates.length == 0)
throw new RuntimeException("input array is empty"); throw new RuntimeException("input array is empty");
Date max = new Date(-Long.MAX_VALUE); Date max = new Date(-Long.MAX_VALUE);
for(int i=0; i<dates.length; i++) for (int i = 0; i < dates.length; i++)
if(max.before(dates[i])) if (max.before(dates[i]))
max = dates[i]; max = dates[i];
return max; return max;
} }
} }

View File

@ -5,7 +5,8 @@ import java.util.Date;
import org.jzy3d.maths.Utils; import org.jzy3d.maths.Utils;
/** @see {@link Utils.dat2str()} for further details on custom formats. */ /**
* @see {@link Utils.dat2str()} for further details on custom formats. */
public class DateTickRenderer implements ITickRenderer{ public class DateTickRenderer implements ITickRenderer{
public DateTickRenderer(){ public DateTickRenderer(){
this("dd/MM/yyyy HH:mm:ss"); this("dd/MM/yyyy HH:mm:ss");

View File

@ -0,0 +1,23 @@
package org.jzy3d.plot3d.primitives.axes.layout.renderers;
import org.jzy3d.maths.Utils;
/** Input value is expected to be a number of elapsed seconds */
public class ElapsedTimeTickRenderer implements ITickRenderer {
public ElapsedTimeTickRenderer() {
this("mm:ss");
}
public ElapsedTimeTickRenderer(String format) {
this.format = format;
}
@Override
public String format(double value) {
return Utils.time2str((long)value*1000);
}
protected String format;
}

View File

@ -0,0 +1,12 @@
package org.jzy3d.maths;
import static org.junit.Assert.*;
import org.junit.Test;
public class TestUtils {
@Test
public void testElapsedTimeFormatter(){
assertEquals("0:00:01.000", Utils.time2str(1000));
}
}