ChartView: improve performance.

This commit is contained in:
Dennis Guse
2021-05-09 21:54:01 +02:00
parent 18dd1de1f9
commit 1fc0a552c7
@@ -40,8 +40,8 @@ import androidx.core.view.GestureDetectorCompat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.time.Duration; import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Optional;
import de.dennisguse.opentracks.MarkerDetailActivity; import de.dennisguse.opentracks.MarkerDetailActivity;
import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.R;
@@ -424,7 +424,7 @@ public class ChartView extends View {
} }
} }
updateDimensions(); updateDimensions();
updatePaths(); updateSeries();
} }
} }
@@ -471,7 +471,7 @@ public class ChartView extends View {
private void zoomIn() { private void zoomIn() {
if (canZoomIn()) { if (canZoomIn()) {
zoomLevel++; zoomLevel++;
updatePaths(); updateSeries();
invalidate(); invalidate();
} }
} }
@@ -486,7 +486,7 @@ public class ChartView extends View {
scrollX = maxWidth; scrollX = maxWidth;
scrollTo(scrollX, 0); scrollTo(scrollX, 0);
} }
updatePaths(); updateSeries();
invalidate(); invalidate();
} }
} }
@@ -853,63 +853,49 @@ public class ChartView extends View {
} }
/** /**
* Updates paths.
* The path needs to be updated any time after the data or the dimensions change. * The path needs to be updated any time after the data or the dimensions change.
*/ */
private void updatePaths() { private void updateSeries() {
synchronized (chartPoints) { synchronized (chartPoints) {
for (ChartValueSeries chartValueSeries : seriesList) { seriesList.stream().forEach(this::updateSerie);
chartValueSeries.getPath().reset();
}
drawPaths();
closePaths();
} }
} }
private void drawPaths() { private void updateSerie(ChartValueSeries series) {
boolean[] hasMoved = new boolean[seriesList.size()]; final int yCorner = topBorder + effectiveHeight;
final Path path = series.getPath();
for (ChartPoint dataPoint : chartPoints) { boolean drawFirstPoint = false;
for (int i = 0; i < seriesList.size(); i++) { path.rewind();
ChartValueSeries chartValueSeries = seriesList.get(i);
if (!chartValueSeries.isChartPointValid(dataPoint)) { Iterator<ChartPoint> iterator = chartPoints.iterator();
continue; while (iterator.hasNext()) {
} ChartPoint point = iterator.next();
if (!series.isChartPointValid(point)) {
continue;
}
double value = chartValueSeries.extractDataFromChartPoint(dataPoint); double value = series.extractDataFromChartPoint(point);
Path path = chartValueSeries.getPath(); int x = getX(point.getTimeOrDistance());
int x = getX(dataPoint.getTimeOrDistance()); int y = getY(series, value);
int y = getY(chartValueSeries, value);
if (!hasMoved[i]) { // start from lower left corner
hasMoved[i] = true; if (!drawFirstPoint) {
path.moveTo(x, y); path.moveTo(x, yCorner);
} else { drawFirstPoint = true;
path.lineTo(x, y); }
}
// draw graph
path.lineTo(x, y);
// last point: move to lower right
if (!iterator.hasNext()) {
path.lineTo(x, yCorner);
} }
} }
}
private void closePaths() { // back to lower left corner
for (ChartValueSeries chartValueSeries : seriesList) { path.close();
Optional<ChartPoint> firstValid = chartPoints.stream().filter(chartValueSeries::isChartPointValid)
.findFirst();
Optional<ChartPoint> lastValid = chartPoints.stream().filter(chartValueSeries::isChartPointValid)
.reduce((first, second) -> second);
if (firstValid.isPresent() && lastValid.isPresent()) {
Path path = chartValueSeries.getPath();
int yCorner = topBorder + effectiveHeight;
path.lineTo(getX(lastValid.get().getTimeOrDistance()), yCorner);
path.lineTo(getX(firstValid.get().getTimeOrDistance()), yCorner);
double value = chartValueSeries.extractDataFromChartPoint(firstValid.get());
path.lineTo(getX(firstValid.get().getTimeOrDistance()), getY(chartValueSeries, value));
}
}
} }
/** /**
@@ -961,7 +947,7 @@ public class ChartView extends View {
width = newWidth; width = newWidth;
height = newHeight; height = newHeight;
updateEffectiveDimensions(); updateEffectiveDimensions();
updatePaths(); updateSeries();
} }
} }