正在查看: xDrip+ v04633772025.07.16 应用的 LineChartRenderer.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
正在查看: xDrip+ v04633772025.07.16 应用的 LineChartRenderer.java JAVA 源代码文件
本页面展示 JAVA 反编译生成的源代码文件,支持语法高亮显示。 仅供安全研究与技术分析使用,严禁用于任何非法用途。请遵守相关法律法规。
package lecho.lib.hellocharts.renderer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.Log;
import java.util.HashMap;
import java.util.Iterator;
import lecho.lib.hellocharts.computator.ChartComputator;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.model.SelectedValue;
import lecho.lib.hellocharts.model.ValueShape;
import lecho.lib.hellocharts.model.Viewport;
import lecho.lib.hellocharts.provider.LineChartDataProvider;
import lecho.lib.hellocharts.util.ChartUtils;
import lecho.lib.hellocharts.view.Chart;
public class LineChartRenderer extends AbstractChartRenderer {
private double baseValue;
private int checkPrecision;
private LineChartDataProvider dataProvider;
private Paint linePaint;
private final Path path;
private Paint pointPaint;
private Bitmap softwareBitmap;
private Canvas softwareCanvas;
private Viewport tempMaximumViewport;
private int touchToleranceMargin;
public LineChartRenderer(Context context, Chart chart, LineChartDataProvider lineChartDataProvider) {
super(context, chart);
this.path = new Path();
this.linePaint = new Paint();
this.pointPaint = new Paint();
this.softwareCanvas = new Canvas();
this.tempMaximumViewport = new Viewport();
this.dataProvider = lineChartDataProvider;
this.touchToleranceMargin = ChartUtils.dp2px(this.density, 4);
this.linePaint.setAntiAlias(true);
this.linePaint.setStyle(Paint.Style.STROKE);
this.linePaint.setStrokeCap(Paint.Cap.ROUND);
this.linePaint.setStrokeWidth(ChartUtils.dp2px(this.density, 3));
this.pointPaint.setAntiAlias(true);
this.pointPaint.setStyle(Paint.Style.FILL);
this.checkPrecision = ChartUtils.dp2px(this.density, 2);
preScaleBitmaps();
}
private void preScaleBitmaps() {
LineChartData lineChartData = this.dataProvider.getLineChartData();
if (lineChartData != null) {
for (Line line : lineChartData.getLines()) {
if (line.isBitmapLabels()) {
BitmapCacheProvider bitmapCacheProvider = line.getBitmapCacheProvider();
if (bitmapCacheProvider != null) {
for (PointValue pointValue : line.getValues()) {
if (pointValue.getLabelBitMapKey() != null && pointValue.getFinalLabelBitMapKey() == null) {
pointValue.setFinalLabelBitMapKey(bitmapCacheProvider.prepareScaledBitmap(pointValue.getLabelBitMapKey(), line.getBitmapScale() * pointValue.getBitmapScale()));
}
}
} else {
throw new RuntimeException("BitmapLabels set but no BitmapCacheProvider set");
}
}
}
}
}
@Override
public void onChartSizeChanged() {
int calculateContentRectInternalMargin = calculateContentRectInternalMargin();
this.computator.insetContentRectByInternalMargins(calculateContentRectInternalMargin, calculateContentRectInternalMargin, calculateContentRectInternalMargin, calculateContentRectInternalMargin);
try {
if (this.computator.getChartWidth() <= 0 || this.computator.getChartHeight() <= 0) {
return;
}
Bitmap createBitmap = Bitmap.createBitmap(this.computator.getChartWidth(), this.computator.getChartHeight(), Bitmap.Config.ARGB_8888);
this.softwareBitmap = createBitmap;
this.softwareCanvas.setBitmap(createBitmap);
} catch (IllegalArgumentException e) {
Log.e("HELLOCHARTS", "IllegalArgumentException during onChartSizeChanged: " + e);
} catch (NegativeArraySizeException e2) {
Log.e("HELLOCHARTS", "NegativeArraySizeException during onChartSizeChanged: " + e2);
}
}
@Override
public void onChartDataChanged() {
super.onChartDataChanged();
int calculateContentRectInternalMargin = calculateContentRectInternalMargin();
this.computator.insetContentRectByInternalMargins(calculateContentRectInternalMargin, calculateContentRectInternalMargin, calculateContentRectInternalMargin, calculateContentRectInternalMargin);
this.baseValue = this.dataProvider.getLineChartData().getBaseValue();
preScaleBitmaps();
onChartViewportChanged();
}
@Override
public void onChartViewportChanged() {
if (this.isViewportCalculationEnabled) {
calculateMaxViewport();
this.computator.setMaxViewport(this.tempMaximumViewport);
ChartComputator chartComputator = this.computator;
chartComputator.setCurrentViewport(chartComputator.getMaximumViewport());
}
}
@Override
public void drawBackgroundUnclipped(Canvas canvas) {
for (Line line : this.dataProvider.getLineChartData().getLines()) {
if (line.isBackgroundUnclipped() && line.hasLines()) {
if (line.isCubic()) {
drawSmoothPath(canvas, line);
} else if (line.isSquare()) {
drawSquarePath(canvas, line);
} else {
drawPath(canvas, line);
}
}
}
}
@Override
public void draw(Canvas canvas) {
Canvas canvas2;
LineChartData lineChartData = this.dataProvider.getLineChartData();
if (this.softwareBitmap != null) {
canvas2 = this.softwareCanvas;
canvas2.drawColor(0, PorterDuff.Mode.CLEAR);
} else {
canvas2 = canvas;
}
for (Line line : lineChartData.getLines()) {
if (line.hasLines() && !line.isBackgroundUnclipped()) {
if (line.isCubic()) {
drawSmoothPath(canvas2, line);
} else if (line.isSquare()) {
drawSquarePath(canvas2, line);
} else {
drawPath(canvas2, line);
}
}
}
Bitmap bitmap = this.softwareBitmap;
if (bitmap != null) {
canvas.drawBitmap(bitmap, 0.0f, 0.0f, (Paint) null);
}
}
@Override
public void drawUnclipped(Canvas canvas) {
int i = 0;
for (Line line : this.dataProvider.getLineChartData().getLines()) {
if (checkIfShouldDrawPoints(line)) {
drawPoints(canvas, line, i, 0);
}
i++;
}
if (isTouched()) {
highlightPoints(canvas);
}
}
private boolean checkIfShouldDrawPoints(Line line) {
return line.hasPoints() || line.getValues().size() == 1;
}
@Override
public boolean checkTouch(double d, double d2) {
this.selectedValue.clear();
int i = 0;
for (Line line : this.dataProvider.getLineChartData().getLines()) {
if (checkIfShouldDrawPoints(line)) {
int dp2px = ChartUtils.dp2px(this.density, line.getPointRadius());
int i2 = 0;
for (PointValue pointValue : line.getValues()) {
int i3 = i2;
if (isInArea(this.computator.computeRawX(pointValue.getX()), this.computator.computeRawY(pointValue.getY()), d, d2, this.touchToleranceMargin + dp2px)) {
this.selectedValue.set(i, i3, SelectedValue.SelectedValueType.LINE);
}
i2 = i3 + 1;
}
}
i++;
}
return isTouched();
}
private void calculateMaxViewport() {
this.tempMaximumViewport.set(Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE, Double.MAX_VALUE);
Iterator<Line> it = this.dataProvider.getLineChartData().getLines().iterator();
while (it.hasNext()) {
for (PointValue pointValue : it.next().getValues()) {
double x = pointValue.getX();
Viewport viewport = this.tempMaximumViewport;
if (x < viewport.left) {
viewport.left = pointValue.getX();
}
double x2 = pointValue.getX();
Viewport viewport2 = this.tempMaximumViewport;
if (x2 > viewport2.right) {
viewport2.right = pointValue.getX();
}
double y = pointValue.getY();
Viewport viewport3 = this.tempMaximumViewport;
if (y < viewport3.bottom) {
viewport3.bottom = pointValue.getY();
}
double y2 = pointValue.getY();
Viewport viewport4 = this.tempMaximumViewport;
if (y2 > viewport4.top) {
viewport4.top = pointValue.getY();
}
}
}
}
private int calculateContentRectInternalMargin() {
int pointRadius;
int i = 0;
for (Line line : this.dataProvider.getLineChartData().getLines()) {
if (checkIfShouldDrawPoints(line) && (pointRadius = line.getPointRadius() + 4) > i) {
i = pointRadius;
}
}
return ChartUtils.dp2px(this.density, i);
}
private void drawPath(Canvas canvas, Line line) {
prepareLinePaint(line);
boolean isReverseYAxis = line.isReverseYAxis();
int i = 0;
for (PointValue pointValue : line.getValues()) {
double computeRawX = this.computator.computeRawX(pointValue.getX());
ChartComputator chartComputator = this.computator;
double computeReverseRawYNoMargin = isReverseYAxis ? chartComputator.computeReverseRawYNoMargin(pointValue.getY()) : chartComputator.computeRawY(pointValue.getY());
if (i == 0) {
this.path.moveTo((float) computeRawX, (float) computeReverseRawYNoMargin);
} else {
this.path.lineTo((float) computeRawX, (float) computeReverseRawYNoMargin);
}
i++;
}
canvas.drawPath(this.path, this.linePaint);
if (line.isFilled()) {
drawArea(canvas, line);
}
this.path.reset();
}
private void drawSimplePath(Canvas canvas, PointValue pointValue, double d, double d2) {
this.path.moveTo((float) this.computator.computeRawX(pointValue.getX()), (float) this.computator.computeRawY(pointValue.getY()));
this.path.lineTo((float) this.computator.computeRawX(d), (float) this.computator.computeRawY(d2));
canvas.drawPath(this.path, this.linePaint);
this.path.reset();
}
private void drawSquarePath(Canvas canvas, Line line) {
prepareLinePaint(line);
boolean isReverseYAxis = line.isReverseYAxis();
int i = 0;
double d = 0.0d;
for (PointValue pointValue : line.getValues()) {
double computeRawX = this.computator.computeRawX(pointValue.getX());
ChartComputator chartComputator = this.computator;
double computeReverseRawYNoMargin = isReverseYAxis ? chartComputator.computeReverseRawYNoMargin(pointValue.getY()) : chartComputator.computeRawY(pointValue.getY());
if (i == 0) {
this.path.moveTo((float) computeRawX, (float) computeReverseRawYNoMargin);
} else {
float f = (float) computeRawX;
this.path.lineTo(f, (float) d);
this.path.lineTo(f, (float) computeReverseRawYNoMargin);
}
i++;
d = computeReverseRawYNoMargin;
}
canvas.drawPath(this.path, this.linePaint);
if (line.isFilled()) {
drawArea(canvas, line);
}
this.path.reset();
}
private void drawSmoothPath(Canvas canvas, Line line) {
double d;
double d2;
int i;
double d3;
double d4;
double d5;
double d6;
prepareLinePaint(line);
int size = line.getValues().size();
double d7 = Double.NaN;
double d8 = Double.NaN;
double d9 = Double.NaN;
double d10 = Double.NaN;
double d11 = Double.NaN;
int i2 = 0;
double d12 = Double.NaN;
while (i2 < size) {
if (Double.isNaN(d7)) {
PointValue pointValue = line.getValues().get(i2);
double computeRawX = this.computator.computeRawX(pointValue.getX());
d8 = this.computator.computeRawY(pointValue.getY());
d7 = computeRawX;
}
if (!Double.isNaN(d12)) {
d = d12;
d2 = d10;
} else if (i2 > 0) {
PointValue pointValue2 = line.getValues().get(i2 - 1);
d = this.computator.computeRawX(pointValue2.getX());
d2 = this.computator.computeRawY(pointValue2.getY());
} else {
d = d7;
d2 = d8;
}
if (Double.isNaN(d9)) {
if (i2 > 1) {
PointValue pointValue3 = line.getValues().get(i2 - 2);
double computeRawX2 = this.computator.computeRawX(pointValue3.getX());
d11 = this.computator.computeRawY(pointValue3.getY());
d9 = computeRawX2;
} else {
d11 = d2;
d9 = d;
}
}
if (i2 < size - 1) {
PointValue pointValue4 = line.getValues().get(i2 + 1);
i = size;
d3 = this.computator.computeRawX(pointValue4.getX());
d4 = this.computator.computeRawY(pointValue4.getY());
} else {
i = size;
d3 = d7;
d4 = d8;
}
if (i2 == 0) {
this.path.moveTo((float) d7, (float) d8);
d5 = d4;
d6 = d2;
} else {
d5 = d4;
d6 = d2;
this.path.cubicTo((float) (d + ((d7 - d9) * 0.1599999964237213d)), (float) (((d8 - d11) * 0.1599999964237213d) + d2), (float) (d7 - ((d3 - d) * 0.1599999964237213d)), (float) (d8 - ((d4 - d2) * 0.1599999964237213d)), (float) d7, (float) d8);
}
i2++;
d12 = d7;
d10 = d8;
d9 = d;
size = i;
d7 = d3;
d11 = d6;
d8 = d5;
}
canvas.drawPath(this.path, this.linePaint);
if (line.isFilled()) {
drawArea(canvas, line);
}
this.path.reset();
}
private void prepareLinePaint(Line line) {
this.linePaint.setStrokeWidth(ChartUtils.dp2px(this.density, line.getStrokeWidth()));
this.linePaint.setColor(line.getColor());
this.linePaint.setPathEffect(line.getPathEffect());
this.linePaint.setShader(null);
}
private void drawPoints(Canvas canvas, Line line, int i, int i2) {
HashMap hashMap;
this.pointPaint.setColor(line.getPointColor());
int dp2px = ChartUtils.dp2px(this.density, line.getPointRadius());
double dp2px2 = ChartUtils.dp2px(this.density, line.getShadowRadius());
boolean isReverseYAxis = line.isReverseYAxis();
HashMap hashMap2 = new HashMap();
int i3 = 0;
boolean z = false;
for (PointValue pointValue : line.getValues()) {
double computeRawX = this.computator.computeRawX(pointValue.getX());
ChartComputator chartComputator = this.computator;
double computeReverseRawYNoMargin = isReverseYAxis ? chartComputator.computeReverseRawYNoMargin(pointValue.getY()) : chartComputator.computeRawY(pointValue.getY());
if (this.computator.isWithinContentRect(computeRawX, computeReverseRawYNoMargin, this.checkPrecision)) {
if (i2 == 0) {
if (pointValue.getPlumbPos() != -1.0d) {
if (!z) {
prepareLinePaint(line);
z = true;
}
drawSimplePath(canvas, pointValue, pointValue.getX(), pointValue.getPlumbPos());
}
drawPoint(canvas, line, pointValue, computeRawX, computeReverseRawYNoMargin, dp2px);
if (line.hasLabels()) {
drawLabel(canvas, line, pointValue, computeRawX, computeReverseRawYNoMargin, this.labelOffset + dp2px);
}
if (line.isBitmapLabels()) {
String finalLabelBitMapKey = pointValue.getFinalLabelBitMapKey();
Bitmap bitmap = (Bitmap) hashMap2.get(finalLabelBitMapKey);
if (bitmap == null && (bitmap = line.getBitmapCacheProvider().loadScaledBitmap(finalLabelBitMapKey)) != null) {
hashMap2.put(finalLabelBitMapKey, bitmap);
}
Bitmap bitmap2 = bitmap;
if (bitmap2 != null) {
hashMap = hashMap2;
drawLabelBitmap(canvas, line, pointValue, computeRawX, computeReverseRawYNoMargin, dp2px2, bitmap2);
}
}
} else {
hashMap = hashMap2;
if (1 == i2) {
highlightPoint(canvas, line, pointValue, computeRawX, computeReverseRawYNoMargin, i, i3);
} else {
throw new IllegalStateException("Cannot process points in mode: " + i2);
}
}
i3++;
hashMap2 = hashMap;
}
hashMap = hashMap2;
i3++;
hashMap2 = hashMap;
}
}
private void drawPoint(Canvas canvas, Line line, PointValue pointValue, double d, double d2, double d3) {
if (ValueShape.SQUARE.equals(line.getShape())) {
canvas.drawRect((float) (d - d3), (float) (d2 - d3), (float) (d + d3), (float) (d2 + d3), this.pointPaint);
return;
}
if (ValueShape.CIRCLE.equals(line.getShape())) {
canvas.drawCircle((float) d, (float) d2, (float) d3, this.pointPaint);
return;
}
if (ValueShape.DIAMOND.equals(line.getShape())) {
canvas.save();
canvas.rotate(45.0f, (float) d, (float) d2);
canvas.drawRect((float) (d - d3), (float) (d2 - d3), (float) (d + d3), (float) (d2 + d3), this.pointPaint);
canvas.restore();
return;
}
throw new IllegalArgumentException("Invalid point shape: " + line.getShape());
}
private void highlightPoints(Canvas canvas) {
int firstIndex = this.selectedValue.getFirstIndex();
drawPoints(canvas, this.dataProvider.getLineChartData().getLines().get(firstIndex), firstIndex, 1);
}
private void highlightPoint(Canvas canvas, Line line, PointValue pointValue, double d, double d2, int i, int i2) {
if (this.selectedValue.getFirstIndex() == i && this.selectedValue.getSecondIndex() == i2) {
int dp2px = ChartUtils.dp2px(this.density, line.getPointRadius());
this.pointPaint.setColor(line.getDarkenColor());
drawPoint(canvas, line, pointValue, d, d2, this.touchToleranceMargin + dp2px);
if (line.hasLabels() || line.hasLabelsOnlyForSelected()) {
drawLabel(canvas, line, pointValue, d, d2, dp2px + this.labelOffset);
}
}
}
private void drawLabelBitmap(Canvas canvas, Line line, PointValue pointValue, double d, double d2, double d3, Bitmap bitmap) {
Integer bitmapTint = pointValue.getBitmapTint();
double width = bitmap.getWidth() / 2;
double height = bitmap.getHeight() / 2;
Integer bitmapLabelShadowColor = line.getBitmapLabelShadowColor();
if (bitmapLabelShadowColor != null) {
float f = (float) ((d3 + d) - width);
float f2 = (float) ((d3 + d2) - height);
canvas.drawBitmap(bitmap, f, f2, getTintedPaint(bitmapLabelShadowColor.intValue()));
if (line.isFullShadow()) {
double d4 = -d3;
float f3 = (float) ((d4 + d) - width);
float f4 = (float) ((d4 + d2) - height);
canvas.drawBitmap(bitmap, f3, f4, getTintedPaint(bitmapLabelShadowColor.intValue()));
canvas.drawBitmap(bitmap, f3, f2, getTintedPaint(bitmapLabelShadowColor.intValue()));
canvas.drawBitmap(bitmap, f, f4, getTintedPaint(bitmapLabelShadowColor.intValue()));
}
}
canvas.drawBitmap(bitmap, (float) (d - width), (float) (d2 - height), bitmapTint != null ? getTintedPaint(bitmapTint.intValue()) : this.labelPaint);
}
private void drawLabel(Canvas canvas, Line line, PointValue pointValue, double d, double d2, double d3) {
double d4;
double d5;
double d6;
double d7;
Rect contentRectMinusAllMargins = this.computator.getContentRectMinusAllMargins();
int formatChartValue = line.getFormatter().formatChartValue(this.labelBuffer, pointValue);
if (formatChartValue == 0) {
return;
}
Paint paint = this.labelPaint;
char[] cArr = this.labelBuffer;
double measureText = paint.measureText(cArr, cArr.length - formatChartValue, formatChartValue);
int abs = Math.abs(this.fontMetrics.ascent);
double d8 = measureText / 2.0d;
int i = this.labelMargin;
double d9 = (d - d8) - i;
double d10 = d + d8 + i;
if (pointValue.getY() >= this.baseValue) {
d6 = d2 - d3;
d4 = d10;
d5 = (d6 - abs) - (this.labelMargin * 2);
} else {
d4 = d10;
d5 = d2 + d3;
d6 = (this.labelMargin * 2) + abs + d5;
}
if (d5 < contentRectMinusAllMargins.top) {
d5 = d2 + d3;
d6 = (this.labelMargin * 2) + abs + d5;
}
if (d6 > contentRectMinusAllMargins.bottom) {
d6 = d2 - d3;
d5 = (d6 - abs) - (this.labelMargin * 2);
}
if (d9 < contentRectMinusAllMargins.left) {
d7 = (this.labelMargin * 2) + d + measureText;
d9 = d;
} else {
d7 = d4;
}
if (d7 > contentRectMinusAllMargins.right) {
d9 = (d - measureText) - (this.labelMargin * 2);
d7 = d;
}
this.labelBackgroundRect.set((float) d9, (float) d5, (float) d7, (float) d6);
char[] cArr2 = this.labelBuffer;
drawLabelTextAndBackground(canvas, cArr2, cArr2.length - formatChartValue, formatChartValue, line.getDarkenColor());
}
private void drawArea(Canvas canvas, Line line) {
double min;
int size = line.getValues().size();
if (size < 2) {
return;
}
Rect maxContentRect = line.isBackgroundUnclipped() ? this.computator.getMaxContentRect() : this.computator.getContentRectMinusAllMargins();
if (line.isFillFlipped()) {
min = Math.min(maxContentRect.top, Math.min(this.computator.computeRawY(this.baseValue), maxContentRect.bottom));
} else {
min = Math.min(maxContentRect.bottom, Math.max(this.computator.computeRawY(this.baseValue), maxContentRect.top));
}
double max = Math.max(this.computator.computeRawX(line.getValues().get(0).getX()), maxContentRect.left);
float f = (float) min;
this.path.lineTo((float) Math.min(this.computator.computeRawX(line.getValues().get(size - 1).getX()), maxContentRect.right), f);
this.path.lineTo((float) max, f);
this.path.close();
this.linePaint.setStyle(Paint.Style.FILL);
this.linePaint.setAlpha(line.getAreaTransparency());
if (line.isFillFlipped()) {
this.linePaint.setShader(line.getGradientToTransparent() ? new LinearGradient(0.0f, (float) (canvas.getHeight() / line.getGradientDivider()), 0.0f, f, line.getColor(), line.getColor() & 16777215, Shader.TileMode.CLAMP) : null);
} else {
this.linePaint.setShader(line.getGradientToTransparent() ? new LinearGradient(0.0f, 0.0f, 0.0f, (float) (canvas.getHeight() / line.getGradientDivider()), line.getColor(), line.getColor() & 16777215, Shader.TileMode.MIRROR) : null);
}
canvas.drawPath(this.path, this.linePaint);
this.linePaint.setStyle(Paint.Style.STROKE);
}
private boolean isInArea(double d, double d2, double d3, double d4, double d5) {
return Math.pow(d3 - d, 2.0d) + Math.pow(d4 - d2, 2.0d) <= Math.pow(d5, 2.0d) * 2.0d;
}
}