more compact chart titles

titles need to take less vertical space for charts to be legible
 in landscape mode when more channels (data series) are available
 Fixes #1807
This commit is contained in:
Peter Hercek
2024-01-02 15:31:54 +01:00
committed by Dennis Guse
parent 5de2012452
commit c6b4e738b9
2 changed files with 32 additions and 17 deletions
@@ -80,7 +80,7 @@ abstract class ChartValueSeries {
// Make copies of the stroke paint with the default thickness // Make copies of the stroke paint with the default thickness
titlePaint = new Paint(strokePaint); titlePaint = new Paint(strokePaint);
titlePaint.setTextSize(fontSizeMedium); titlePaint.setTextSize(fontSizeMedium);
titlePaint.setTextAlign(Align.CENTER); titlePaint.setTextAlign(Align.LEFT);
titlePaint.setStyle(Style.FILL_AND_STROKE); titlePaint.setStyle(Style.FILL_AND_STROKE);
markerPaint = new Paint(strokePaint); markerPaint = new Paint(strokePaint);
@@ -43,6 +43,7 @@ import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Iterator;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Marker;
@@ -666,24 +667,31 @@ public class ChartView extends View {
} }
} }
private record TitlePosition(
int line, // line number (starts at 1, top to bottom numbering)
int xPos // x position in points (starts at 0, left to right indexing)
) {};
private record TitleDimensions(
int lineCount, // number of lines the titles will take
int lineHeight, // height of a line (all lines have the same height)
List<TitlePosition> titlePositions // positions of visible titles (the order corresponds to seriesList)
) {};
/** /**
* Draws series titles. * Draws series titles.
* *
* @param canvas the canvas * @param canvas the canvas
*/ */
private void drawSeriesTitles(Canvas canvas) { private void drawSeriesTitles(Canvas canvas) {
int[] titleDimensions = getTitleDimensions(); TitleDimensions td = getTitleDimensions();
int lines = titleDimensions[0]; Iterator<TitlePosition> tpI = td.titlePositions.iterator();
int lineHeight = titleDimensions[1];
int count = 0;
for (ChartValueSeries chartValueSeries : seriesList) { for (ChartValueSeries chartValueSeries : seriesList) {
if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(chartValueSeries)) { if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(chartValueSeries)) {
count++;
String title = getContext().getString(chartValueSeries.getTitleId(unitSystem)); String title = getContext().getString(chartValueSeries.getTitleId(unitSystem));
Paint paint = chartValueSeries.getTitlePaint(); Paint paint = chartValueSeries.getTitlePaint();
int x = (int) (0.5 * width) + getScrollX(); TitlePosition tp = tpI.next();
int y = topBorder - spacer - (lines - count) * (lineHeight + spacer); int y = topBorder - spacer - (td.lineCount - tp.line) * (td.lineHeight + spacer);
canvas.drawText(title, x, y, paint); canvas.drawText(title, tp.xPos + getScrollX(), y, paint);
} }
} }
} }
@@ -692,20 +700,27 @@ public class ChartView extends View {
* Gets the title dimensions. * Gets the title dimensions.
* Returns an array of 2 integers, first element is the number of lines and the second element is the line height. * Returns an array of 2 integers, first element is the number of lines and the second element is the line height.
*/ */
private int[] getTitleDimensions() { private TitleDimensions getTitleDimensions() {
int lines = 0; int lineCnt = 1;
int lineHeight = 0; int lineHeight = 0;
List<TitlePosition> tps = new ArrayList<TitlePosition>();
int xPosInLine = spacer;
for (ChartValueSeries chartValueSeries : seriesList) { for (ChartValueSeries chartValueSeries : seriesList) {
if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(chartValueSeries)) { if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(chartValueSeries)) {
lines++;
String title = getContext().getString(chartValueSeries.getTitleId(unitSystem)); String title = getContext().getString(chartValueSeries.getTitleId(unitSystem));
Rect rect = getRect(chartValueSeries.getTitlePaint(), title); Rect rect = getRect(chartValueSeries.getTitlePaint(), title);
if (rect.height() > lineHeight) { if (rect.height() > lineHeight) lineHeight = rect.height();
lineHeight = rect.height(); int xNextPosInLine = xPosInLine + rect.width() + 2*spacer;
// if second or later title does not fully fit on this line then print it on the next line
if (xPosInLine > spacer && xNextPosInLine-spacer > width) {
lineCnt++;
xPosInLine = spacer;
} }
tps.add(new TitlePosition(lineCnt, xPosInLine));
xPosInLine += rect.width() + 2*spacer;
} }
} }
return new int[]{lines, lineHeight}; return new TitleDimensions(lineCnt, lineHeight, tps);
} }
/** /**
@@ -932,8 +947,8 @@ public class ChartView extends View {
} }
leftBorder = (int) (density * BORDER + markerLength); leftBorder = (int) (density * BORDER + markerLength);
int[] titleDimensions = getTitleDimensions(); TitleDimensions td = getTitleDimensions();
topBorder = (int) (density * BORDER + titleDimensions[0] * (titleDimensions[1] + spacer)); topBorder = (int) (density * BORDER + td.lineCount * (td.lineHeight + spacer));
Rect xAxisLabelRect = getRect(axisPaint, getXAxisLabel()); Rect xAxisLabelRect = getRect(axisPaint, getXAxisLabel());
// border + x axis marker + spacer + .5 x axis label // border + x axis marker + spacer + .5 x axis label
bottomBorder = (int) (density * BORDER + getRect(xAxisMarkerPaint, "1").height() + spacer + (xAxisLabelRect.height() / 2)); bottomBorder = (int) (density * BORDER + getRect(xAxisMarkerPaint, "1").height() + spacer + (xAxisLabelRect.height() / 2));