Skip to content

Commit

Permalink
more compact formating in charts
Browse files Browse the repository at this point in the history
  • Loading branch information
dzmipt committed Dec 13, 2024
1 parent 51976cd commit 865e618
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 78 deletions.
70 changes: 60 additions & 10 deletions src/studio/kdb/K.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,26 @@ public class K {
private final static SimpleDateFormat timestampFormatter = new SimpleDateFormat("yyyy.MM.dd'D'HH:mm:ss.");
private static final java.text.DecimalFormat i2Formatter = new java.text.DecimalFormat("00");
private static final java.text.DecimalFormat i3Formatter = new java.text.DecimalFormat("000");
private static final java.text.DecimalFormat i4Formatter = new java.text.DecimalFormat("0000");

private static String i2(int i) {
return i2Formatter.format(i);
}
private static String i3(int i) {
return i3Formatter.format(i);
}
private static String i4(int i) {
return i4Formatter.format(i);
}
private static String l2(long i) {
return i2Formatter.format(i);
}

public final static int JAVA_DAY_OFFSET = 10957;
public final static long NS_IN_SEC = 1_000_000_000;
public final static long NS_IN_MLS = 1_000_000;
public final static long NS_IN_MIN = 60 * NS_IN_SEC;
public final static long NS_IN_HOUR = 60 * NS_IN_MIN;
public final static long SEC_IN_DAY = 24 * 60 * 60;
public final static long MS_IN_DAY = 1000 * SEC_IN_DAY;
public final static long NS_IN_DAY = NS_IN_SEC * SEC_IN_DAY;
Expand Down Expand Up @@ -943,7 +949,7 @@ public StringBuilder format(StringBuilder builder, KFormatContext context) {
}

public Date toDate() {
return new Date(MS_IN_DAY * (value + 10957));
return new Date(MS_IN_DAY * (value + JAVA_DAY_OFFSET));
}

public KTimestamp toTimestamp() {
Expand Down Expand Up @@ -1029,13 +1035,14 @@ public Time toTime() {

// Artificial class need to represent time in the charts.
public static class KTimeLong extends KLongBase {

public KTimeLong(long value) {
super(KType.TimeLong, value);
}

@Override
public StringBuilder format(StringBuilder builder, KFormatContext context) {
KFormatContext.Rounding rounding = context.getRounding();

builder = super.format(builder, context);
long ns = Math.abs(value % NS_IN_SEC);
long v = Math.abs(value / NS_IN_SEC);
Expand All @@ -1045,9 +1052,18 @@ public StringBuilder format(StringBuilder builder, KFormatContext context) {
long hh = v / 60;
if (value < 0) builder.append('-');
builder.append(l2(hh))
.append(':').append(i2((int)min))
.append(':').append(i2((int)sec))
.append(".").append(nsFormatter.format(ns));
.append(':').append(l2(min));

if (rounding.minutes() && sec == 0 && ns == 0) return builder;
builder.append(':').append(l2(sec));

if (rounding.seconds() && ns == 0) return builder;

if (rounding.millis() && ns % NS_IN_MLS == 0) {
builder.append(".").append(i3Formatter.format(ns/NS_IN_MLS));
} else {
builder.append(".").append(nsFormatter.format(ns));
}
return builder;
}
}
Expand All @@ -1069,7 +1085,7 @@ public StringBuilder format(StringBuilder builder, KFormatContext context) {
}

public Timestamp toTimestamp() {
return new Timestamp(Math.round(8.64e7 * (value + 10957)));
return new Timestamp(Math.round(8.64e7 * (value + JAVA_DAY_OFFSET)));
}
}

Expand Down Expand Up @@ -1119,20 +1135,54 @@ public KTimestamp(long time) {

@Override
public StringBuilder format(StringBuilder builder, KFormatContext context) {
KFormatContext.Rounding rounding = context.getRounding();

builder = super.format(builder, context);
if (isNull()) builder.append("0Np");
else if (value == Long.MAX_VALUE) builder.append("0Wp");
else if (value == -Long.MAX_VALUE) builder.append("-0Wp");
else {
Timestamp ts = toJavaTimestamp();
builder.append(timestampFormatter.format(ts))
.append(nsFormatter.format(ts.getNanos()));
long v = value % NS_IN_DAY;
long epochDays = JAVA_DAY_OFFSET + value / NS_IN_DAY;
if (v < 0) {
v += NS_IN_DAY;
epochDays--;
}
LocalDate localDate = LocalDate.ofEpochDay(epochDays);

builder.append(i4(localDate.getYear()))
.append('.').append(i2(localDate.getMonthValue()))
.append('.').append(i2(localDate.getDayOfMonth()));

if (rounding.days() && v == 0) return builder;

long hh = v / NS_IN_HOUR;
v = v % NS_IN_HOUR;
long mm = v / NS_IN_MIN;
v = v % NS_IN_MIN;

builder.append('D').append(l2(hh))
.append(':').append(l2(mm));

if (rounding.minutes() && v == 0) return builder;
long ss = v / NS_IN_SEC;
long ns = v % NS_IN_SEC;

builder.append(':').append(l2(ss));

if(rounding.seconds() && ns == 0) return builder;

if (rounding.millis() && ns % NS_IN_MLS == 0) {
builder.append('.').append(i3Formatter.format(ns / NS_IN_MLS));
} else {
builder.append('.').append(nsFormatter.format(ns));
}
}
return builder;
}

public Timestamp toJavaTimestamp() {
long k = MS_IN_DAY * 10957;
long k = MS_IN_DAY * JAVA_DAY_OFFSET;
long n = 1000000000L;
long d = value < 0 ? (value + 1) / n - 1 : value / n;
long ltime = value == Long.MIN_VALUE ? value : (k + 1000 * d);
Expand Down
10 changes: 9 additions & 1 deletion src/studio/kdb/KFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public KFormat(KType type) {
}

public static String format(KType type, double value) {
KFormatContext fmtContext = KFormatContext.NO_TYPE;

K.KBase kValue;
if (type == KType.Int ||
type == KType.Double ||
Expand All @@ -23,6 +25,7 @@ public static String format(KType type, double value) {
type == KType.Long) {
kValue = new K.KDouble(value);
} else if (type == KType.Datetime) {
fmtContext = KFormatContext.MILLIS;
kValue = new K.KDatetime(value);
} else if (type == KType.Timestamp) {
kValue = new K.KTimestamp(getLong(value));
Expand All @@ -34,11 +37,13 @@ public static String format(KType type, double value) {
boolean hasFraction = Math.abs(fraction) >= 1e-5;

if (type == KType.Date) {
fmtContext = KFormatContext.DAY;
kValue = new K.KDate(intValue);
if (hasFraction) {
kValue = ((K.KDate)kValue).toTimestamp(fraction);
}
} else if (type == KType.Month) {
fmtContext = KFormatContext.DAY;
kValue = new K.Month(intValue);
if (hasFraction) {
LocalDateTime dateTime = ((K.Month)kValue).toLocalDateTime();
Expand All @@ -50,19 +55,22 @@ public static String format(KType type, double value) {
}

} else if (type == KType.Time) {
fmtContext = KFormatContext.MILLIS;
if (hasFraction) {
kValue = new K.KTimeLong((long) (value * K.NS_IN_MLS));
} else {
kValue = new K.KTime(intValue);
}
System.out.printf("KFormat KTime: value: %f, hasFraction: %b; kValue: %s\n", value, hasFraction, kValue);
} else if (type == KType.Second) {
fmtContext = KFormatContext.SECOND;
if (hasFraction) {
kValue = new K.KTimeLong((long) (value * K.NS_IN_SEC));
} else {
kValue = new K.Second(intValue);
}
} else if (type == KType.Minute) {
fmtContext = KFormatContext.MINUTE;
if (hasFraction) {
kValue = new K.KTimeLong((long) (value * K.NS_IN_MIN));
} else {
Expand All @@ -73,7 +81,7 @@ public static String format(KType type, double value) {
}
}

return kValue.toString(KFormatContext.NO_TYPE);
return kValue.toString(fmtContext);
}

@Override
Expand Down
54 changes: 53 additions & 1 deletion src/studio/kdb/KFormatContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,66 @@ public class KFormatContext {

private boolean showType;
private boolean showThousandsComma;
private final Rounding rounding;

public enum Rounding {
NO (false, false, false, false),
DAY (true, true, true, true),
MINUTE (false, true, true, true),
SECOND (false, false, true, true),
MILLIS (false, false, false, true);

private final boolean dd, mm, ss, ms;

Rounding(boolean dd, boolean mm, boolean ss, boolean ms) {
this.dd = dd;
this.mm = mm;
this.ss = ss;
this.ms = ms;
}
public boolean days() {
return dd;
}

public boolean minutes() {
return mm;
}

public boolean seconds() {
return ss;
}

public boolean millis() {
return ms;
}
};


public final static KFormatContext DEFAULT = new KFormatContext();
public final static KFormatContext NO_TYPE = new KFormatContext(false, false);

public final static KFormatContext DAY = new KFormatContext(Rounding.DAY);
public final static KFormatContext MINUTE = new KFormatContext(Rounding.MINUTE);
public final static KFormatContext SECOND = new KFormatContext(Rounding.SECOND);
public final static KFormatContext MILLIS = new KFormatContext(Rounding.MILLIS);

public static void setMaxFractionDigits(int maxFractionDigits) {
RAW_FORMAT.setMaximumFractionDigits(maxFractionDigits);
COMMA_FORMAT.setMaximumFractionDigits(maxFractionDigits);
}

public KFormatContext(boolean showType, boolean showThousandsComma) {
public KFormatContext(boolean showType, boolean showThousandsComma, Rounding rounding) {
this.showType = showType;
this.showThousandsComma = showThousandsComma;
this.rounding = rounding;
}

public KFormatContext(Rounding rounding) {
this(false, false, rounding);
}

public KFormatContext(boolean showType, boolean showThousandsComma) {
this(showType, showThousandsComma, Rounding.NO);
}

public KFormatContext(KFormatContext formatContext) {
Expand All @@ -36,6 +84,10 @@ public KFormatContext() {
this(true, false);
}

public Rounding getRounding() {
return rounding;
}

public NumberFormat getNumberFormat() {
return showThousandsComma ? COMMA_FORMAT : RAW_FORMAT;
}
Expand Down
Loading

0 comments on commit 865e618

Please sign in to comment.