From 437a739898ba0eb782c36a834b0b83c3b27c2be4 Mon Sep 17 00:00:00 2001 From: yu_xh <940151214@qq.com> Date: Fri, 24 Sep 2021 14:25:29 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E5=AD=97=E5=A4=A7=E5=B0=8F=E4=B8=BA=E8=B4=9F=E6=95=B0?= =?UTF-8?q?=E6=97=B6=E5=AF=BC=E8=87=B4=E7=9A=84=E7=A8=8B=E5=BA=8F=E5=B4=A9?= =?UTF-8?q?=E6=BA=83=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jjoe64/graphview/GridLabelRenderer.java | 2704 +++++++++-------- .../com/jjoe64/graphview/LegendRenderer.java | 37 +- 2 files changed, 1378 insertions(+), 1363 deletions(-) diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java b/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java index de79c6b..8e534e8 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java @@ -374,1556 +374,1566 @@ public class GridLabelRenderer { int size; int size2; - color1 = Color.BLACK.getValue(); - color2 = Color.GRAY.getValue(); - size = 20; - size2 = 20; - - mStyles.verticalLabelsColor = color1; - mStyles.verticalLabelsSecondScaleColor = color1; - mStyles.horizontalLabelsColor = color1; - mStyles.gridColor = color2; - mStyles.textSize = size; - mStyles.padding = size2; - mStyles.labelsSpace = (int) mStyles.textSize / 5; - - mStyles.verticalLabelsAlign = 2; - mStyles.verticalLabelsSecondScaleAlign = 0; - mStyles.highlightZeroLines = true; - - mStyles.verticalAxisTitleColor = mStyles.verticalLabelsColor; - mStyles.horizontalAxisTitleColor = mStyles.horizontalLabelsColor; - mStyles.verticalAxisTitleTextSize = mStyles.textSize; - mStyles.horizontalAxisTitleTextSize = mStyles.textSize; - - mStyles.horizontalLabelsVisible = true; - mStyles.verticalLabelsVisible = true; - - mStyles.horizontalLabelsAngle = 0f; - - mStyles.gridStyle = GridStyle.BOTH; - reloadStyles(); - } + color1 = Color.BLACK.getValue(); + color2 = Color.GRAY.getValue(); + size = 20; + size2 = 20; + + mStyles.verticalLabelsColor = color1; + mStyles.verticalLabelsSecondScaleColor = color1; + mStyles.horizontalLabelsColor = color1; + mStyles.gridColor = color2; + mStyles.textSize = size; + mStyles.padding = size2; + mStyles.labelsSpace = (int) mStyles.textSize / 5; + + mStyles.verticalLabelsAlign = 2; + mStyles.verticalLabelsSecondScaleAlign = 0; + mStyles.highlightZeroLines = true; + + mStyles.verticalAxisTitleColor = mStyles.verticalLabelsColor; + mStyles.horizontalAxisTitleColor = mStyles.horizontalLabelsColor; + mStyles.verticalAxisTitleTextSize = mStyles.textSize; + mStyles.horizontalAxisTitleTextSize = mStyles.textSize; + + mStyles.horizontalLabelsVisible = true; + mStyles.verticalLabelsVisible = true; + + mStyles.horizontalLabelsAngle = 0f; + + mStyles.gridStyle = GridStyle.BOTH; + reloadStyles(); + } - /** - * will load the styles to the internal - * paint objects (color, text size, text align) - */ - public void reloadStyles () { - mPaintLine = new Paint(); - mPaintLine.setColor(new Color(mStyles.gridColor)); - mPaintLine.setStrokeWidth(0); - - mPaintLabel = new Paint(); - mPaintLabel.setTextSize((int) getTextSize()); - mPaintLabel.setAntiAlias(true); - - mPaintAxisTitle = new Paint(); - mPaintAxisTitle.setTextSize((int) getTextSize()); - mPaintAxisTitle.setTextAlign(1); - } + /** + * will load the styles to the internal + * paint objects (color, text size, text align) + */ + public void reloadStyles() { + mPaintLine = new Paint(); + mPaintLine.setColor(new Color(mStyles.gridColor)); + mPaintLine.setStrokeWidth(0); + + mPaintLabel = new Paint(); + mPaintLabel.setTextSize((int) getTextSize()); + mPaintLabel.setAntiAlias(true); + + mPaintAxisTitle = new Paint(); + mPaintAxisTitle.setTextSize((int) getTextSize()); + mPaintAxisTitle.setTextAlign(1); + } - /** - * GraphView tries to fit the labels - * to display numbers that can be divided by 1, 2, or 5. - *

- * By default this is enabled. It makes sense to deactivate it - * when using Dates on the x axis. - * - * @return if human rounding is enabled - */ - public boolean isHumanRoundingX () { - return mHumanRoundingX; - } + /** + * GraphView tries to fit the labels + * to display numbers that can be divided by 1, 2, or 5. + *

+ * By default this is enabled. It makes sense to deactivate it + * when using Dates on the x axis. + * + * @return if human rounding is enabled + */ + public boolean isHumanRoundingX() { + return mHumanRoundingX; + } - /** - * GraphView tries to fit the labels - * to display numbers that can be divided by 1, 2, or 5. - * - * @return if human rounding is enabled - */ - public boolean isHumanRoundingY () { - return mHumanRoundingY; - } + /** + * GraphView tries to fit the labels + * to display numbers that can be divided by 1, 2, or 5. + * + * @return if human rounding is enabled + */ + public boolean isHumanRoundingY() { + return mHumanRoundingY; + } - /** - * activate or deactivate human rounding of the - * horizontal axis. GraphView tries to fit the labels - * to display numbers that can be divided by 1, 2, or 5. - *

- * By default this is enabled. It makes sense to deactivate it - * when using Dates on the x axis. - * - * @param humanRoundingX false to deactivate - * @param humanRoundingY false to deactivate - */ - public void setHumanRounding ( boolean humanRoundingX, boolean humanRoundingY){ - this.mHumanRoundingX = humanRoundingX; - this.mHumanRoundingY = humanRoundingY; - } + /** + * activate or deactivate human rounding of the + * horizontal axis. GraphView tries to fit the labels + * to display numbers that can be divided by 1, 2, or 5. + *

+ * By default this is enabled. It makes sense to deactivate it + * when using Dates on the x axis. + * + * @param humanRoundingX false to deactivate + * @param humanRoundingY false to deactivate + */ + public void setHumanRounding(boolean humanRoundingX, boolean humanRoundingY) { + this.mHumanRoundingX = humanRoundingX; + this.mHumanRoundingY = humanRoundingY; + } - /** - * activate or deactivate human rounding of the - * horizontal axis. GraphView tries to fit the labels - * to display numbers that can be divided by 1, 2, or 5. - *

- * By default this is enabled. - * - * @param humanRoundingBoth false to deactivate on both axises - */ - public void setHumanRounding ( boolean humanRoundingBoth){ - this.mHumanRoundingX = humanRoundingBoth; - this.mHumanRoundingY = humanRoundingBoth; - } + /** + * activate or deactivate human rounding of the + * horizontal axis. GraphView tries to fit the labels + * to display numbers that can be divided by 1, 2, or 5. + *

+ * By default this is enabled. + * + * @param humanRoundingBoth false to deactivate on both axises + */ + public void setHumanRounding(boolean humanRoundingBoth) { + this.mHumanRoundingX = humanRoundingBoth; + this.mHumanRoundingY = humanRoundingBoth; + } - /** - * ss - * - * @return the general text size for the axis titles - */ - public float getTextSize () { - return mStyles.textSize; - } + /** + * ss + * + * @return the general text size for the axis titles + */ + public float getTextSize() { + return mStyles.textSize; + } - /** - * ss - * - * @return the font color of the vertical labels - */ - public int getVerticalLabelsColor () { - return mStyles.verticalLabelsColor; - } + /** + * ss + * + * @return the font color of the vertical labels + */ + public int getVerticalLabelsColor() { + return mStyles.verticalLabelsColor; + } - /** - * ss - * - * @return the alignment of the text of the - * vertical labels - */ - public int getVerticalLabelsAlign () { - return mStyles.verticalLabelsAlign; - } + /** + * ss + * + * @return the alignment of the text of the + * vertical labels + */ + public int getVerticalLabelsAlign() { + return mStyles.verticalLabelsAlign; + } - /** - * ss - * - * @return the font color of the horizontal labels - */ - public int getHorizontalLabelsColor () { - return mStyles.horizontalLabelsColor; - } + /** + * ss + * + * @return the font color of the horizontal labels + */ + public int getHorizontalLabelsColor() { + return mStyles.horizontalLabelsColor; + } - /** - * ss - * - * @return the angle of the horizontal labels - */ - public float getHorizontalLabelsAngle () { - return mStyles.horizontalLabelsAngle; - } + /** + * ss + * + * @return the angle of the horizontal labels + */ + public float getHorizontalLabelsAngle() { + return mStyles.horizontalLabelsAngle; + } - /** - * clears the internal cache and forces - * to redraw the grid and labels. - * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)} - * which will call this method. - * - * @param keepLabelsSize true if you don't want - * to recalculate the size of - * the labels. It is recommended - * to use "true" because this will - * improve performance and prevent - * a flickering. - * @param keepViewport true if you don't want that - * the viewport will be recalculated. - * It is recommended to use "true" for - * performance. - */ - public void invalidate ( boolean keepLabelsSize, boolean keepViewport){ - if (!keepViewport) { - mIsAdjusted = false; - } - if (!keepLabelsSize) { - if (!mLabelVerticalWidthFixed) { - mLabelVerticalWidth = null; - } - mLabelVerticalHeight = null; - mLabelVerticalSecondScaleWidth = null; - mLabelVerticalSecondScaleHeight = null; + /** + * clears the internal cache and forces + * to redraw the grid and labels. + * Normally you should always call {@link GraphView#onDataChanged(boolean, boolean)} + * which will call this method. + * + * @param keepLabelsSize true if you don't want + * to recalculate the size of + * the labels. It is recommended + * to use "true" because this will + * improve performance and prevent + * a flickering. + * @param keepViewport true if you don't want that + * the viewport will be recalculated. + * It is recommended to use "true" for + * performance. + */ + public void invalidate(boolean keepLabelsSize, boolean keepViewport) { + if (!keepViewport) { + mIsAdjusted = false; + } + if (!keepLabelsSize) { + if (!mLabelVerticalWidthFixed) { + mLabelVerticalWidth = null; } - //reloadStyles(); + mLabelVerticalHeight = null; + mLabelVerticalSecondScaleWidth = null; + mLabelVerticalSecondScaleHeight = null; } + //reloadStyles(); + } - /** - * calculates the vertical steps of - * the second scale. - * This will not do any automatically update - * of the bounds. - * Use always manual bounds for the second scale. - * - * @return true if it is ready - */ - protected boolean adjustVerticalSecondScale () { - if (mLabelHorizontalHeight == null) { - return false; - } - if (mGraphView.mSecondScale == null) { - return true; - } + /** + * calculates the vertical steps of + * the second scale. + * This will not do any automatically update + * of the bounds. + * Use always manual bounds for the second scale. + * + * @return true if it is ready + */ + protected boolean adjustVerticalSecondScale() { + if (mLabelHorizontalHeight == null) { + return false; + } + if (mGraphView.mSecondScale == null) { + return true; + } - double minY = mGraphView.mSecondScale.getMinY(false); - double maxY = mGraphView.mSecondScale.getMaxY(false); + double minY = mGraphView.mSecondScale.getMinY(false); + double maxY = mGraphView.mSecondScale.getMaxY(false); - // TODO find the number of labels - int numVerticalLabels = mNumVerticalLabels; + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; - double newMinY; - double exactSteps; + double newMinY; + double exactSteps; - if (mGraphView.mSecondScale.isYAxisBoundsManual()) { - // split range into equal steps - exactSteps = (maxY - minY) / (numVerticalLabels - 1); + if (mGraphView.mSecondScale.isYAxisBoundsManual()) { + // split range into equal steps + exactSteps = (maxY - minY) / (numVerticalLabels - 1); - // round because of floating error - exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; - } else { - // TODO auto adjusting - throw new IllegalStateException("Not yet implemented"); - } + // round because of floating error + exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; + } else { + // TODO auto adjusting + throw new IllegalStateException("Not yet implemented"); + } - if (mStepsVerticalSecondScale != null && mStepsVerticalSecondScale.size() > 1) { - // else choose other nice steps that previous - // steps are included (divide to have more, or multiplicate to have less) + if (mStepsVerticalSecondScale != null && mStepsVerticalSecondScale.size() > 1) { + // else choose other nice steps that previous + // steps are included (divide to have more, or multiplicate to have less) - double d1 = 0, d2 = 0; - int i = 0; - for (Double v : mStepsVerticalSecondScale.values()) { - if (i == 0) { - d1 = v; - } else { - d2 = v; - break; - } - i++; + double d1 = 0, d2 = 0; + int i = 0; + for (Double v : mStepsVerticalSecondScale.values()) { + if (i == 0) { + d1 = v; + } else { + d2 = v; + break; + } + i++; + } + double oldSteps = d2 - d1; + if (oldSteps > 0) { + double newSteps = Double.NaN; + + if (oldSteps > exactSteps) { + newSteps = oldSteps / 2; + } else if (oldSteps < exactSteps) { + newSteps = oldSteps * 2; } - double oldSteps = d2 - d1; - if (oldSteps > 0) { - double newSteps = Double.NaN; - - if (oldSteps > exactSteps) { - newSteps = oldSteps / 2; - } else if (oldSteps < exactSteps) { - newSteps = oldSteps * 2; - } - // only if there wont be more than numLabels - // and newSteps will be better than oldSteps - int numStepsOld = (int) ((maxY - minY) / oldSteps); - int numStepsNew = (int) ((maxY - minY) / newSteps); + // only if there wont be more than numLabels + // and newSteps will be better than oldSteps + int numStepsOld = (int) ((maxY - minY) / oldSteps); + int numStepsNew = (int) ((maxY - minY) / newSteps); - boolean shouldChange; + boolean shouldChange; - // avoid switching between 2 steps - if (numStepsOld <= numVerticalLabels && numStepsNew <= numVerticalLabels) { - // both are possible - // only the new if it hows more labels - shouldChange = numStepsNew > numStepsOld; - } else { - shouldChange = true; - } + // avoid switching between 2 steps + if (numStepsOld <= numVerticalLabels && numStepsNew <= numVerticalLabels) { + // both are possible + // only the new if it hows more labels + shouldChange = numStepsNew > numStepsOld; + } else { + shouldChange = true; + } - if (newSteps != Double.NaN && shouldChange && numStepsNew <= numVerticalLabels) { - exactSteps = newSteps; - } else { - // try to stay to the old steps - exactSteps = oldSteps; - } + if (newSteps != Double.NaN && shouldChange && numStepsNew <= numVerticalLabels) { + exactSteps = newSteps; + } else { + // try to stay to the old steps + exactSteps = oldSteps; } - } else { - // first time - LogUtil.debug("find","find"); } + } else { + // first time + LogUtil.debug("find", "find"); + } - // find the first data point that is relevant to display - // starting from 1st datapoint so that the steps have nice numbers - // goal is to start with the minY or 1 step before - newMinY = mGraphView.getSecondScale().mReferenceY; - // must be down-rounded - double count = Math.floor((minY - newMinY) / exactSteps); - newMinY = count * exactSteps + newMinY; + // find the first data point that is relevant to display + // starting from 1st datapoint so that the steps have nice numbers + // goal is to start with the minY or 1 step before + newMinY = mGraphView.getSecondScale().mReferenceY; + // must be down-rounded + double count = Math.floor((minY - newMinY) / exactSteps); + newMinY = count * exactSteps + newMinY; - // it can happen that we need to add some more labels to fill the complete screen - numVerticalLabels = (int) ((mGraphView.getSecondScale().mCurrentViewport.height() * -1 / exactSteps)) + 2; + // it can happen that we need to add some more labels to fill the complete screen + numVerticalLabels = (int) ((mGraphView.getSecondScale().mCurrentViewport.height() * -1 / exactSteps)) + 2; - // ensure that the value is valid (minimum 2) - numVerticalLabels = Math.max(numVerticalLabels, 2); + // ensure that the value is valid (minimum 2) + numVerticalLabels = Math.max(numVerticalLabels, 2); - if (mStepsVerticalSecondScale != null) { - mStepsVerticalSecondScale.clear(); - } else { - mStepsVerticalSecondScale = new LinkedHashMap<>(numVerticalLabels); - } + if (mStepsVerticalSecondScale != null) { + mStepsVerticalSecondScale.clear(); + } else { + mStepsVerticalSecondScale = new LinkedHashMap<>(numVerticalLabels); + } - int height = mGraphView.getGraphContentHeight(); - // convert data-y to pixel-y in current viewport - double pixelPerData = height / mGraphView.getSecondScale().mCurrentViewport.height() * -1; + int height = mGraphView.getGraphContentHeight(); + // convert data-y to pixel-y in current viewport + double pixelPerData = height / mGraphView.getSecondScale().mCurrentViewport.height() * -1; - for (int i = 0; i < numVerticalLabels; i++) { - // dont draw if it is top of visible screen - if (newMinY + (i * exactSteps) > mGraphView.getSecondScale().mCurrentViewport.top) { - continue; - } - // dont draw if it is below of visible screen - if (newMinY + (i * exactSteps) < mGraphView.getSecondScale().mCurrentViewport.bottom) { - continue; - } + for (int i = 0; i < numVerticalLabels; i++) { + // dont draw if it is top of visible screen + if (newMinY + (i * exactSteps) > mGraphView.getSecondScale().mCurrentViewport.top) { + continue; + } + // dont draw if it is below of visible screen + if (newMinY + (i * exactSteps) < mGraphView.getSecondScale().mCurrentViewport.bottom) { + continue; + } - // where is the data point on the current screen - double dataPointPos = newMinY + (i * exactSteps); - double relativeToCurrentViewport = dataPointPos - mGraphView.getSecondScale().mCurrentViewport.bottom; + // where is the data point on the current screen + double dataPointPos = newMinY + (i * exactSteps); + double relativeToCurrentViewport = dataPointPos - mGraphView.getSecondScale().mCurrentViewport.bottom; - double pixelPos = relativeToCurrentViewport * pixelPerData; - mStepsVerticalSecondScale.put((int) pixelPos, dataPointPos); - } + double pixelPos = relativeToCurrentViewport * pixelPerData; + mStepsVerticalSecondScale.put((int) pixelPos, dataPointPos); + } - return true; + return true; + } + + /** + * calculates the vertical steps. This will + * automatically change the bounds to nice + * human-readable min/max. + * + * @param changeBounds str + * @return true if it is ready + */ + protected boolean adjustVertical(boolean changeBounds) { + if (mLabelHorizontalHeight == null) { + return false; } - /** - * calculates the vertical steps. This will - * automatically change the bounds to nice - * human-readable min/max. - * - * @param changeBounds str - * @return true if it is ready - */ - protected boolean adjustVertical ( boolean changeBounds){ - if (mLabelHorizontalHeight == null) { - return false; - } + double minY = mGraphView.getViewport().getMinY(false); + double maxY = mGraphView.getViewport().getMaxY(false); - double minY = mGraphView.getViewport().getMinY(false); - double maxY = mGraphView.getViewport().getMaxY(false); + if (minY == maxY) { + return false; + } - if (minY == maxY) { - return false; - } + // TODO find the number of labels + int numVerticalLabels = mNumVerticalLabels; - // TODO find the number of labels - int numVerticalLabels = mNumVerticalLabels; + double newMinY; + double exactSteps; - double newMinY; - double exactSteps; + // split range into equal steps + exactSteps = (maxY - minY) / (numVerticalLabels - 1); - // split range into equal steps - exactSteps = (maxY - minY) / (numVerticalLabels - 1); + // round because of floating error + exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; - // round because of floating error - exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; + // smallest viewport + if (exactSteps == 0d) { + exactSteps = 0.0000001d; + maxY = minY + exactSteps * (numVerticalLabels - 1); + } - // smallest viewport - if (exactSteps == 0d) { - exactSteps = 0.0000001d; - maxY = minY + exactSteps * (numVerticalLabels - 1); - } + // human rounding to have nice numbers (1, 2, 5, ...) + if (isHumanRoundingY()) { + exactSteps = humanRound(exactSteps, changeBounds); + } else if (mStepsVertical != null && mStepsVertical.size() > 1) { + // else choose other nice steps that previous + // steps are included (divide to have more, or multiplicate to have less) - // human rounding to have nice numbers (1, 2, 5, ...) - if (isHumanRoundingY()) { - exactSteps = humanRound(exactSteps, changeBounds); - } else if (mStepsVertical != null && mStepsVertical.size() > 1) { - // else choose other nice steps that previous - // steps are included (divide to have more, or multiplicate to have less) - - double d1 = 0, d2 = 0; - int i = 0; - for (Double v : mStepsVertical.values()) { - if (i == 0) { - d1 = v; - } else { - d2 = v; - break; - } - i++; + double d1 = 0, d2 = 0; + int i = 0; + for (Double v : mStepsVertical.values()) { + if (i == 0) { + d1 = v; + } else { + d2 = v; + break; + } + i++; + } + double oldSteps = d2 - d1; + if (oldSteps > 0) { + double newSteps = Double.NaN; + + if (oldSteps > exactSteps) { + newSteps = oldSteps / 2; + } else if (oldSteps < exactSteps) { + newSteps = oldSteps * 2; } - double oldSteps = d2 - d1; - if (oldSteps > 0) { - double newSteps = Double.NaN; - - if (oldSteps > exactSteps) { - newSteps = oldSteps / 2; - } else if (oldSteps < exactSteps) { - newSteps = oldSteps * 2; - } - // only if there wont be more than numLabels - // and newSteps will be better than oldSteps - int numStepsOld = (int) ((maxY - minY) / oldSteps); - int numStepsNew = (int) ((maxY - minY) / newSteps); + // only if there wont be more than numLabels + // and newSteps will be better than oldSteps + int numStepsOld = (int) ((maxY - minY) / oldSteps); + int numStepsNew = (int) ((maxY - minY) / newSteps); - boolean shouldChange; + boolean shouldChange; - // avoid switching between 2 steps - if (numStepsOld <= numVerticalLabels && numStepsNew <= numVerticalLabels) { - // both are possible - // only the new if it hows more labels - shouldChange = numStepsNew > numStepsOld; - } else { - shouldChange = true; - } + // avoid switching between 2 steps + if (numStepsOld <= numVerticalLabels && numStepsNew <= numVerticalLabels) { + // both are possible + // only the new if it hows more labels + shouldChange = numStepsNew > numStepsOld; + } else { + shouldChange = true; + } - if (newSteps != Double.NaN && shouldChange && numStepsNew <= numVerticalLabels) { - exactSteps = newSteps; - } else { - // try to stay to the old steps - exactSteps = oldSteps; - } + if (newSteps != Double.NaN && shouldChange && numStepsNew <= numVerticalLabels) { + exactSteps = newSteps; + } else { + // try to stay to the old steps + exactSteps = oldSteps; } - } else { - // first time - LogUtil.debug("find","find"); } + } else { + // first time + LogUtil.debug("find", "find"); + } - // find the first data point that is relevant to display - // starting from 1st datapoint so that the steps have nice numbers - // goal is to start with the minX or 1 step before - newMinY = mGraphView.getViewport().getReferenceY(); - // must be down-rounded - double count = Math.floor((minY - newMinY) / exactSteps); - newMinY = count * exactSteps + newMinY; - - // now we have our labels bounds - if (changeBounds) { - mGraphView.getViewport().setMinY(newMinY); - mGraphView.getViewport().setMaxY(Math.max(maxY, newMinY + (numVerticalLabels - 1) * exactSteps)); - mGraphView.getViewport().mYAxisBoundsStatus = Viewport.AxisBoundsStatus.AUTO_ADJUSTED; - } + // find the first data point that is relevant to display + // starting from 1st datapoint so that the steps have nice numbers + // goal is to start with the minX or 1 step before + newMinY = mGraphView.getViewport().getReferenceY(); + // must be down-rounded + double count = Math.floor((minY - newMinY) / exactSteps); + newMinY = count * exactSteps + newMinY; - // it can happen that we need to add some more labels to fill the complete screen - numVerticalLabels = (int) ((mGraphView.getViewport().mCurrentViewport.height() * -1 / exactSteps)) + 2; + // now we have our labels bounds + if (changeBounds) { + mGraphView.getViewport().setMinY(newMinY); + mGraphView.getViewport().setMaxY(Math.max(maxY, newMinY + (numVerticalLabels - 1) * exactSteps)); + mGraphView.getViewport().mYAxisBoundsStatus = Viewport.AxisBoundsStatus.AUTO_ADJUSTED; + } - if (mStepsVertical != null) { - mStepsVertical.clear(); - } else { - mStepsVertical = new LinkedHashMap<>((int) numVerticalLabels); - } + // it can happen that we need to add some more labels to fill the complete screen + numVerticalLabels = (int) ((mGraphView.getViewport().mCurrentViewport.height() * -1 / exactSteps)) + 2; - int height = mGraphView.getGraphContentHeight(); - // convert data-y to pixel-y in current viewport - double pixelPerData = height / mGraphView.getViewport().mCurrentViewport.height() * -1; + if (mStepsVertical != null) { + mStepsVertical.clear(); + } else { + mStepsVertical = new LinkedHashMap<>((int) numVerticalLabels); + } - for (int i = 0; i < numVerticalLabels; i++) { - // dont draw if it is top of visible screen - if (newMinY + (i * exactSteps) > mGraphView.getViewport().mCurrentViewport.top) { - continue; - } - // dont draw if it is below of visible screen - if (newMinY + (i * exactSteps) < mGraphView.getViewport().mCurrentViewport.bottom) { - continue; - } + int height = mGraphView.getGraphContentHeight(); + // convert data-y to pixel-y in current viewport + double pixelPerData = height / mGraphView.getViewport().mCurrentViewport.height() * -1; + for (int i = 0; i < numVerticalLabels; i++) { + // dont draw if it is top of visible screen + if (newMinY + (i * exactSteps) > mGraphView.getViewport().mCurrentViewport.top) { + continue; + } + // dont draw if it is below of visible screen + if (newMinY + (i * exactSteps) < mGraphView.getViewport().mCurrentViewport.bottom) { + continue; + } - // where is the data point on the current screen - double dataPointPos = newMinY + (i * exactSteps); - double relativeToCurrentViewport = dataPointPos - mGraphView.getViewport().mCurrentViewport.bottom; - double pixelPos = relativeToCurrentViewport * pixelPerData; - mStepsVertical.put((int) pixelPos, dataPointPos); - } + // where is the data point on the current screen + double dataPointPos = newMinY + (i * exactSteps); + double relativeToCurrentViewport = dataPointPos - mGraphView.getViewport().mCurrentViewport.bottom; - return true; + double pixelPos = relativeToCurrentViewport * pixelPerData; + mStepsVertical.put((int) pixelPos, dataPointPos); } - /** - * calculates the horizontal steps. - * - * @param changeBounds This will automatically change the - * bounds to nice human-readable min/max. - * @return true if it is ready - */ - protected boolean adjustHorizontal ( boolean changeBounds){ - if (mLabelVerticalWidth == null) { - return false; - } + return true; + } - double minX = mGraphView.getViewport().getMinX(false); - double maxX = mGraphView.getViewport().getMaxX(false); - if (minX == maxX) return false; + /** + * calculates the horizontal steps. + * + * @param changeBounds This will automatically change the + * bounds to nice human-readable min/max. + * @return true if it is ready + */ + protected boolean adjustHorizontal(boolean changeBounds) { + if (mLabelVerticalWidth == null) { + return false; + } - // TODO find the number of labels - int numHorizontalLabels = mNumHorizontalLabels; + double minX = mGraphView.getViewport().getMinX(false); + double maxX = mGraphView.getViewport().getMaxX(false); + if (minX == maxX) return false; - double newMinX; - double exactSteps; + // TODO find the number of labels + int numHorizontalLabels = mNumHorizontalLabels; - // split range into equal steps - exactSteps = (maxX - minX) / (numHorizontalLabels - 1); + double newMinX; + double exactSteps; - // round because of floating error - exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; + // split range into equal steps + exactSteps = (maxX - minX) / (numHorizontalLabels - 1); - // smallest viewport - if (exactSteps == 0d) { - exactSteps = 0.0000001d; - maxX = minX + exactSteps * (numHorizontalLabels - 1); - } + // round because of floating error + exactSteps = Math.round(exactSteps * 1000000d) / 1000000d; - // human rounding to have nice numbers (1, 2, 5, ...) - if (isHumanRoundingX()) { - exactSteps = humanRound(exactSteps, false); - } else if (mStepsHorizontal != null && mStepsHorizontal.size() > 1) { - // else choose other nice steps that previous - // steps are included (divide to have more, or multiplicate to have less) - - double d1 = 0, d2 = 0; - int i = 0; - for (Double v : mStepsHorizontal.values()) { - if (i == 0) { - d1 = v; - } else { - d2 = v; - break; - } - i++; + // smallest viewport + if (exactSteps == 0d) { + exactSteps = 0.0000001d; + maxX = minX + exactSteps * (numHorizontalLabels - 1); + } + + // human rounding to have nice numbers (1, 2, 5, ...) + if (isHumanRoundingX()) { + exactSteps = humanRound(exactSteps, false); + } else if (mStepsHorizontal != null && mStepsHorizontal.size() > 1) { + // else choose other nice steps that previous + // steps are included (divide to have more, or multiplicate to have less) + + double d1 = 0, d2 = 0; + int i = 0; + for (Double v : mStepsHorizontal.values()) { + if (i == 0) { + d1 = v; + } else { + d2 = v; + break; + } + i++; + } + double oldSteps = d2 - d1; + if (oldSteps > 0) { + double newSteps = Double.NaN; + + if (oldSteps > exactSteps) { + newSteps = oldSteps / 2; + } else if (oldSteps < exactSteps) { + newSteps = oldSteps * 2; } - double oldSteps = d2 - d1; - if (oldSteps > 0) { - double newSteps = Double.NaN; - - if (oldSteps > exactSteps) { - newSteps = oldSteps / 2; - } else if (oldSteps < exactSteps) { - newSteps = oldSteps * 2; - } - // only if there wont be more than numLabels - // and newSteps will be better than oldSteps - int numStepsOld = (int) ((maxX - minX) / oldSteps); - int numStepsNew = (int) ((maxX - minX) / newSteps); + // only if there wont be more than numLabels + // and newSteps will be better than oldSteps + int numStepsOld = (int) ((maxX - minX) / oldSteps); + int numStepsNew = (int) ((maxX - minX) / newSteps); - boolean shouldChange; + boolean shouldChange; - // avoid switching between 2 steps - if (numStepsOld <= numHorizontalLabels && numStepsNew <= numHorizontalLabels) { - // both are possible - // only the new if it hows more labels - shouldChange = numStepsNew > numStepsOld; - } else { - shouldChange = true; - } + // avoid switching between 2 steps + if (numStepsOld <= numHorizontalLabels && numStepsNew <= numHorizontalLabels) { + // both are possible + // only the new if it hows more labels + shouldChange = numStepsNew > numStepsOld; + } else { + shouldChange = true; + } - if (newSteps != Double.NaN && shouldChange && numStepsNew <= numHorizontalLabels) { - exactSteps = newSteps; - } else { - // try to stay to the old steps - exactSteps = oldSteps; - } + if (newSteps != Double.NaN && shouldChange && numStepsNew <= numHorizontalLabels) { + exactSteps = newSteps; + } else { + // try to stay to the old steps + exactSteps = oldSteps; } - } else { - // first time - LogUtil.debug("find","find"); } + } else { + // first time + LogUtil.debug("find", "find"); + } - // starting from 1st datapoint - // goal is to start with the minX or 1 step before - newMinX = mGraphView.getViewport().getReferenceX(); - // must be down-rounded - double count = Math.floor((minX - newMinX) / exactSteps); - newMinX = count * exactSteps + newMinX; + // starting from 1st datapoint + // goal is to start with the minX or 1 step before + newMinX = mGraphView.getViewport().getReferenceX(); + // must be down-rounded + double count = Math.floor((minX - newMinX) / exactSteps); + newMinX = count * exactSteps + newMinX; - // now we have our labels bounds - if (changeBounds) { - mGraphView.getViewport().setMinX(newMinX); - mGraphView.getViewport().setMaxX(newMinX + (numHorizontalLabels - 1) * exactSteps); - mGraphView.getViewport().mXAxisBoundsStatus = Viewport.AxisBoundsStatus.AUTO_ADJUSTED; - } + // now we have our labels bounds + if (changeBounds) { + mGraphView.getViewport().setMinX(newMinX); + mGraphView.getViewport().setMaxX(newMinX + (numHorizontalLabels - 1) * exactSteps); + mGraphView.getViewport().mXAxisBoundsStatus = Viewport.AxisBoundsStatus.AUTO_ADJUSTED; + } + + // it can happen that we need to add some more labels to fill the complete screen + numHorizontalLabels = (int) ((mGraphView.getViewport().mCurrentViewport.width() / exactSteps)) + 1; + + if (mStepsHorizontal != null) { + mStepsHorizontal.clear(); + } else { + mStepsHorizontal = new LinkedHashMap<>((int) numHorizontalLabels); + } - // it can happen that we need to add some more labels to fill the complete screen - numHorizontalLabels = (int) ((mGraphView.getViewport().mCurrentViewport.width() / exactSteps)) + 1; + int width = mGraphView.getGraphContentWidth(); + // convert data-x to pixel-x in current viewport + double pixelPerData = width / mGraphView.getViewport().mCurrentViewport.width(); - if (mStepsHorizontal != null) { - mStepsHorizontal.clear(); - } else { - mStepsHorizontal = new LinkedHashMap<>((int) numHorizontalLabels); + for (int i = 0; i < numHorizontalLabels; i++) { + // dont draw if it is left of visible screen + if (newMinX + (i * exactSteps) < mGraphView.getViewport().mCurrentViewport.left) { + continue; } - int width = mGraphView.getGraphContentWidth(); - // convert data-x to pixel-x in current viewport - double pixelPerData = width / mGraphView.getViewport().mCurrentViewport.width(); + // where is the data point on the current screen + double dataPointPos = newMinX + (i * exactSteps); + double relativeToCurrentViewport = dataPointPos - mGraphView.getViewport().mCurrentViewport.left; - for (int i = 0; i < numHorizontalLabels; i++) { - // dont draw if it is left of visible screen - if (newMinX + (i * exactSteps) < mGraphView.getViewport().mCurrentViewport.left) { - continue; - } + double pixelPos = relativeToCurrentViewport * pixelPerData; + mStepsHorizontal.put((int) pixelPos, dataPointPos); + } - // where is the data point on the current screen - double dataPointPos = newMinX + (i * exactSteps); - double relativeToCurrentViewport = dataPointPos - mGraphView.getViewport().mCurrentViewport.left; + return true; + } - double pixelPos = relativeToCurrentViewport * pixelPerData; - mStepsHorizontal.put((int) pixelPos, dataPointPos); - } + /** + * adjusts the grid and labels to match to the data + * this will automatically change the bounds to + * nice human-readable values, except the bounds + * are manual. + */ + protected void adjustSteps() { + mIsAdjusted = adjustVertical(!Viewport.AxisBoundsStatus.FIX.equals(mGraphView.getViewport().mYAxisBoundsStatus)); + mIsAdjusted &= adjustVerticalSecondScale(); + mIsAdjusted &= adjustHorizontal(!Viewport.AxisBoundsStatus.FIX.equals(mGraphView.getViewport().mXAxisBoundsStatus)); + } - return true; - } + /** + * calculates the vertical label size + * + * @param canvas canvas + */ + protected void calcLabelVerticalSize(Canvas canvas) { + // test label with first and last label + String testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMaxY(false), false); + if (testLabel == null) testLabel = ""; + LogUtil.error("calcLabelVerticalSize--1->", testLabel); + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel); + mLabelVerticalWidth = textBounds.getWidth(); + mLabelVerticalHeight = textBounds.getHeight(); + + testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMinY(false), false); + if (testLabel == null) testLabel = ""; + LogUtil.error("calcLabelVerticalSize--2->", testLabel); + mPaintLabel.getTextBounds(testLabel); + mLabelVerticalWidth = Math.max(mLabelVerticalWidth, textBounds.getWidth()); + + // add some pixel to get a margin + mLabelVerticalWidth += 6; + + // space between text and graph content + mLabelVerticalWidth += mStyles.labelsSpace; + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalHeight *= lines; + } - /** - * adjusts the grid and labels to match to the data - * this will automatically change the bounds to - * nice human-readable values, except the bounds - * are manual. - */ - protected void adjustSteps () { - mIsAdjusted = adjustVertical(!Viewport.AxisBoundsStatus.FIX.equals(mGraphView.getViewport().mYAxisBoundsStatus)); - mIsAdjusted &= adjustVerticalSecondScale(); - mIsAdjusted &= adjustHorizontal(!Viewport.AxisBoundsStatus.FIX.equals(mGraphView.getViewport().mXAxisBoundsStatus)); + /** + * calculates the vertical second scale + * label size + * + * @param canvas canvas + */ + protected void calcLabelVerticalSecondScaleSize(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + mLabelVerticalSecondScaleWidth = 0; + mLabelVerticalSecondScaleHeight = 0; + return; + } + + // test label + double testY = ((mGraphView.mSecondScale.getMaxY(false) - mGraphView.mSecondScale.getMinY(false)) * 0.783) + mGraphView.mSecondScale.getMinY(false); + String testLabel = mGraphView.mSecondScale.getLabelFormatter().formatLabel(testY, false); + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel); + mLabelVerticalSecondScaleWidth = textBounds.getWidth(); + mLabelVerticalSecondScaleHeight = textBounds.getHeight(); + + // multiline + int lines = 1; + for (byte c : testLabel.getBytes()) { + if (c == '\n') lines++; + } + mLabelVerticalSecondScaleHeight *= lines; + } + + /** + * calculates the horizontal label size + * + * @param canvas canvas + */ + protected void calcLabelHorizontalSize(Canvas canvas) { + // test label + double testX = ((mGraphView.getViewport().getMaxX(false) - mGraphView.getViewport().getMinX(false)) * 0.783) + mGraphView.getViewport().getMinX(false); + String testLabel = mLabelFormatter.formatLabel(testX, true); + if (testLabel == null) { + testLabel = ""; } + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(testLabel); + mLabelHorizontalWidth = textBounds.getWidth(); - /** - * calculates the vertical label size - * - * @param canvas canvas - */ - protected void calcLabelVerticalSize (Canvas canvas){ - // test label with first and last label - String testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMaxY(false), false); - if (testLabel == null) testLabel = ""; - LogUtil.error("calcLabelVerticalSize--1->",testLabel); - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel); - mLabelVerticalWidth = textBounds.getWidth(); - mLabelVerticalHeight = textBounds.getHeight(); - - testLabel = mLabelFormatter.formatLabel(mGraphView.getViewport().getMinY(false), false); - if (testLabel == null) testLabel = ""; - LogUtil.error("calcLabelVerticalSize--2->",testLabel); - mPaintLabel.getTextBounds(testLabel); - mLabelVerticalWidth = Math.max(mLabelVerticalWidth, textBounds.getWidth()); - - // add some pixel to get a margin - mLabelVerticalWidth += 6; - - // space between text and graph content - mLabelVerticalWidth += mStyles.labelsSpace; + if (!mLabelHorizontalHeightFixed) { + mLabelHorizontalHeight = textBounds.getHeight(); // multiline int lines = 1; for (byte c : testLabel.getBytes()) { if (c == '\n') lines++; } - mLabelVerticalHeight *= lines; - } + mLabelHorizontalHeight *= lines; - /** - * calculates the vertical second scale - * label size - * - * @param canvas canvas - */ - protected void calcLabelVerticalSecondScaleSize (Canvas canvas){ - if (mGraphView.mSecondScale == null) { - mLabelVerticalSecondScaleWidth = 0; - mLabelVerticalSecondScaleHeight = 0; - return; - } + mLabelHorizontalHeight = (int) Math.max(mLabelHorizontalHeight, mStyles.textSize); + } - // test label - double testY = ((mGraphView.mSecondScale.getMaxY(false) - mGraphView.mSecondScale.getMinY(false)) * 0.783) + mGraphView.mSecondScale.getMinY(false); - String testLabel = mGraphView.mSecondScale.getLabelFormatter().formatLabel(testY, false); - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel); - mLabelVerticalSecondScaleWidth = textBounds.getWidth(); - mLabelVerticalSecondScaleHeight = textBounds.getHeight(); + if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { + int adjHorizontalHeightH = (int) Math.round(Math.abs(mLabelHorizontalHeight * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle)))); + int adjHorizontalHeightW = (int) Math.round(Math.abs(mLabelHorizontalWidth * Math.sin(Math.toRadians(mStyles.horizontalLabelsAngle)))); + int adjHorizontalWidthH = (int) Math.round(Math.abs(mLabelHorizontalHeight * Math.sin(Math.toRadians(mStyles.horizontalLabelsAngle)))); + int adjHorizontalWidthW = (int) Math.round(Math.abs(mLabelHorizontalWidth * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle)))); - // multiline - int lines = 1; - for (byte c : testLabel.getBytes()) { - if (c == '\n') lines++; - } - mLabelVerticalSecondScaleHeight *= lines; + mLabelHorizontalHeight = adjHorizontalHeightH + adjHorizontalHeightW; + mLabelHorizontalWidth = adjHorizontalWidthH + adjHorizontalWidthW; } - /** - * calculates the horizontal label size - * - * @param canvas canvas - */ - protected void calcLabelHorizontalSize (Canvas canvas){ - // test label - double testX = ((mGraphView.getViewport().getMaxX(false) - mGraphView.getViewport().getMinX(false)) * 0.783) + mGraphView.getViewport().getMinX(false); - String testLabel = mLabelFormatter.formatLabel(testX, true); - if (testLabel == null) { - testLabel = ""; - } - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(testLabel); - mLabelHorizontalWidth = textBounds.getWidth(); + // space between text and graph content + mLabelHorizontalHeight += mStyles.labelsSpace; + } - if (!mLabelHorizontalHeightFixed) { - mLabelHorizontalHeight = textBounds.getHeight(); + /** + * do the drawing of the grid + * and labels + * + * @param width str + * @param height str + * @param canvas canvas + */ + public void draw(Canvas canvas, int width, int height) { - // multiline - int lines = 1; - for (byte c : testLabel.getBytes()) { - if (c == '\n') lines++; - } - mLabelHorizontalHeight *= lines; + boolean labelSizeChanged = false; + if (mLabelHorizontalWidth == null) { + calcLabelHorizontalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalWidth == null) { + calcLabelVerticalSize(canvas); + labelSizeChanged = true; + } + if (mLabelVerticalSecondScaleWidth == null) { + calcLabelVerticalSecondScaleSize(canvas); + labelSizeChanged = true; + } + if (labelSizeChanged) { + // redraw directly + mGraphView.drawGraphElements(canvas); + return; + } - mLabelHorizontalHeight = (int) Math.max(mLabelHorizontalHeight, mStyles.textSize); - } - - if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { - int adjHorizontalHeightH = (int) Math.round(Math.abs(mLabelHorizontalHeight * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle)))); - int adjHorizontalHeightW = (int) Math.round(Math.abs(mLabelHorizontalWidth * Math.sin(Math.toRadians(mStyles.horizontalLabelsAngle)))); - int adjHorizontalWidthH = (int) Math.round(Math.abs(mLabelHorizontalHeight * Math.sin(Math.toRadians(mStyles.horizontalLabelsAngle)))); - int adjHorizontalWidthW = (int) Math.round(Math.abs(mLabelHorizontalWidth * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle)))); - - mLabelHorizontalHeight = adjHorizontalHeightH + adjHorizontalHeightW; - mLabelHorizontalWidth = adjHorizontalWidthH + adjHorizontalWidthW; - } - - // space between text and graph content - mLabelHorizontalHeight += mStyles.labelsSpace; + if (!mIsAdjusted) { + adjustSteps(); } - /** - * do the drawing of the grid - * and labels - * - * @param width str - * @param height str - * @param canvas canvas - */ - public void draw (Canvas canvas,int width,int height){ - - boolean labelSizeChanged = false; - if (mLabelHorizontalWidth == null) { - calcLabelHorizontalSize(canvas); - labelSizeChanged = true; - } - if (mLabelVerticalWidth == null) { - calcLabelVerticalSize(canvas); - labelSizeChanged = true; - } - if (mLabelVerticalSecondScaleWidth == null) { - calcLabelVerticalSecondScaleSize(canvas); - labelSizeChanged = true; - } - if (labelSizeChanged) { - // redraw directly - mGraphView.drawGraphElements(canvas); - return; - } - - if (!mIsAdjusted) { - adjustSteps(); - } - - if (mIsAdjusted) { - //Y轴数据 - drawVerticalSteps(canvas); - drawVerticalStepsSecondScale(canvas); - //X轴数据 - drawHorizontalSteps(canvas,width,height); - } else { - // we can not draw anything - return; - } + if (mIsAdjusted) { + //Y轴数据 + drawVerticalSteps(canvas); + drawVerticalStepsSecondScale(canvas); + //X轴数据 + drawHorizontalSteps(canvas, width, height); + } else { + // we can not draw anything + return; + } - drawHorizontalAxisTitle(canvas,width,height); - drawVerticalAxisTitle(canvas,width,height); + drawHorizontalAxisTitle(canvas, width, height); + drawVerticalAxisTitle(canvas, width, height); - // draw second scale axis title if it exists - if (mGraphView.mSecondScale != null) { - mGraphView.mSecondScale.drawVerticalAxisTitle(canvas,width,height); - } + // draw second scale axis title if it exists + if (mGraphView.mSecondScale != null) { + mGraphView.mSecondScale.drawVerticalAxisTitle(canvas, width, height); } + } - /** - * draws the horizontal axis title if - * it is set - * - * @param canvas canvas - * @param width str - * @param height str - */ - protected void drawHorizontalAxisTitle (Canvas canvas,int width,int height){ - if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { - mPaintAxisTitle.setColor(new Color(getHorizontalAxisTitleColor())); - mPaintAxisTitle.setTextSize((int) getHorizontalAxisTitleTextSize()); - float x = width / 2; - float y = height - mStyles.padding; - canvas.drawText(mPaintAxisTitle, mHorizontalAxisTitle, x, y); - } + /** + * draws the horizontal axis title if + * it is set + * + * @param canvas canvas + * @param width str + * @param height str + */ + protected void drawHorizontalAxisTitle(Canvas canvas, int width, int height) { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(new Color(getHorizontalAxisTitleColor())); + mPaintAxisTitle.setTextSize((int) getHorizontalAxisTitleTextSize()); + float x = width / 2; + float y = height - mStyles.padding; + canvas.drawText(mPaintAxisTitle, mHorizontalAxisTitle, x, y); } + } - /** - * draws the vertical axis title if - * it is set - * - * @param canvas canvas - * @param width str - * @param height str - */ - protected void drawVerticalAxisTitle (Canvas canvas,int width,int height){ - if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { - mPaintAxisTitle.setColor(new Color(getVerticalAxisTitleColor())); - mPaintAxisTitle.setTextSize((int) getVerticalAxisTitleTextSize()); - float x = getVerticalAxisTitleWidth(); - float y = height / 2; - canvas.save(); - canvas.rotate(-90, x, y); - canvas.drawText(mPaintAxisTitle, mVerticalAxisTitle, x, y); - canvas.restore(); - } + /** + * draws the vertical axis title if + * it is set + * + * @param canvas canvas + * @param width str + * @param height str + */ + protected void drawVerticalAxisTitle(Canvas canvas, int width, int height) { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + mPaintAxisTitle.setColor(new Color(getVerticalAxisTitleColor())); + mPaintAxisTitle.setTextSize((int) getVerticalAxisTitleTextSize()); + float x = getVerticalAxisTitleWidth(); + float y = height / 2; + canvas.save(); + canvas.rotate(-90, x, y); + canvas.drawText(mPaintAxisTitle, mVerticalAxisTitle, x, y); + canvas.restore(); } + } - /** - * ss - * - * @return the horizontal axis title height - * or 0 if there is no title - */ - public int getHorizontalAxisTitleHeight () { - if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { - return (int) getHorizontalAxisTitleTextSize(); - } else { - return 0; - } + /** + * ss + * + * @return the horizontal axis title height + * or 0 if there is no title + */ + public int getHorizontalAxisTitleHeight() { + if (mHorizontalAxisTitle != null && mHorizontalAxisTitle.length() > 0) { + return (int) getHorizontalAxisTitleTextSize(); + } else { + return 0; } + } - /** - * ss - * - * @return the vertical axis title width - * or 0 if there is no title - */ - public int getVerticalAxisTitleWidth () { - if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { - return (int) getVerticalAxisTitleTextSize(); - } else { - return 0; - } + /** + * ss + * + * @return the vertical axis title width + * or 0 if there is no title + */ + public int getVerticalAxisTitleWidth() { + if (mVerticalAxisTitle != null && mVerticalAxisTitle.length() > 0) { + return (int) getVerticalAxisTitleTextSize(); + } else { + return 0; } + } - /** - * draws the horizontal steps - * vertical lines and horizontal labels - * TODO 画X轴数据 - * - * @param canvas canvas - * @param height str - * @param width str - */ - protected void drawHorizontalSteps (Canvas canvas,int width,int height){ - // draw horizontal steps (vertical lines and horizontal labels) - mPaintLabel.setColor(new Color(getHorizontalLabelsColor())); - int i = 0; - for (Map.Entry e : mStepsHorizontal.entrySet()) { - // draw line - if (mStyles.highlightZeroLines) { - if (e.getValue() == 0d) { - mPaintLine.setStrokeWidth(5); - } else { - mPaintLine.setStrokeWidth(0); - } + /** + * draws the horizontal steps + * vertical lines and horizontal labels + * TODO 画X轴数据 + * + * @param canvas canvas + * @param height str + * @param width str + */ + protected void drawHorizontalSteps(Canvas canvas, int width, int height) { + // draw horizontal steps (vertical lines and horizontal labels) + mPaintLabel.setColor(new Color(getHorizontalLabelsColor())); + int i = 0; + for (Map.Entry e : mStepsHorizontal.entrySet()) { + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); } - if (mStyles.gridStyle.drawVertical()) { - // dont draw if it is right of visible screen - if (e.getKey() <= mGraphView.getGraphContentWidth()) { - canvas.drawLine(new Point(mGraphView.getGraphContentLeft() + e.getKey(), mGraphView.getGraphContentTop()), new Point(mGraphView.getGraphContentLeft() + e.getKey(), mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight()), mPaintLine); - } + } + if (mStyles.gridStyle.drawVertical()) { + // dont draw if it is right of visible screen + if (e.getKey() <= mGraphView.getGraphContentWidth()) { + canvas.drawLine(new Point(mGraphView.getGraphContentLeft() + e.getKey(), mGraphView.getGraphContentTop()), new Point(mGraphView.getGraphContentLeft() + e.getKey(), mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight()), mPaintLine); } + } - // draw label - if (isHorizontalLabelsVisible()) { - if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { - if (mStyles.horizontalLabelsAngle < 90f) { - mPaintLabel.setTextAlign((2)); - } else if (mStyles.horizontalLabelsAngle <= 180f) { - mPaintLabel.setTextAlign((0)); - } - } else { - mPaintLabel.setTextAlign(1); - if (i == mStepsHorizontal.size() - 1) - mPaintLabel.setTextAlign(2); - if (i == 0) - mPaintLabel.setTextAlign(0); + // draw label + if (isHorizontalLabelsVisible()) { + if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { + if (mStyles.horizontalLabelsAngle < 90f) { + mPaintLabel.setTextAlign((2)); + } else if (mStyles.horizontalLabelsAngle <= 180f) { + mPaintLabel.setTextAlign((0)); } + } else { + mPaintLabel.setTextAlign(1); + if (i == mStepsHorizontal.size() - 1) + mPaintLabel.setTextAlign(2); + if (i == 0) + mPaintLabel.setTextAlign(0); + } - // multiline labels - String label = mLabelFormatter.formatLabel(e.getValue(), true); - LogUtil.error("yuxh--horizontalLabel--->",label+"~~~"+e.getValue()); - if (label == null) { - label = ""; - } - String[] lines = label.split("\n"); - - // If labels are angled, calculate adjustment to line them up with the grid - int labelWidthAdj = 0; - if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { - Rect textBounds = new Rect(); - mPaintLabel.getTextBounds(lines[0]); - labelWidthAdj = (int) Math.abs(textBounds.getWidth() * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle))); - } - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y = (height - mStyles.padding - getHorizontalAxisTitleHeight()) - (lines.length - li - 1) * getTextSize() * 1.1f + mStyles.labelsSpace; - float x = mGraphView.getGraphContentLeft() + e.getKey(); - if (mStyles.horizontalLabelsAngle > 0 && mStyles.horizontalLabelsAngle < 90f) { - canvas.save(); - canvas.rotate(mStyles.horizontalLabelsAngle, x + labelWidthAdj, y); - canvas.drawText(mPaintLabel, lines[li], x + labelWidthAdj-20, y); - canvas.restore(); - } else if (mStyles.horizontalLabelsAngle > 0 && mStyles.horizontalLabelsAngle <= 180f) { - canvas.save(); - canvas.rotate(mStyles.horizontalLabelsAngle - 180f, x - labelWidthAdj, y); - canvas.drawText(mPaintLabel, lines[li], x - labelWidthAdj-20, y); - canvas.restore(); - } else { - canvas.drawText(mPaintLabel, lines[li], x-20, y); - } + // multiline labels + String label = mLabelFormatter.formatLabel(e.getValue(), true); + LogUtil.error("yuxh--horizontalLabel--->", label + "~~~" + e.getValue()); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + + // If labels are angled, calculate adjustment to line them up with the grid + int labelWidthAdj = 0; + if (mStyles.horizontalLabelsAngle > 0f && mStyles.horizontalLabelsAngle <= 180f) { + Rect textBounds = new Rect(); + mPaintLabel.getTextBounds(lines[0]); + labelWidthAdj = (int) Math.abs(textBounds.getWidth() * Math.cos(Math.toRadians(mStyles.horizontalLabelsAngle))); + } + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y = (height - mStyles.padding - getHorizontalAxisTitleHeight()) - (lines.length - li - 1) * getTextSize() * 1.1f + mStyles.labelsSpace; + float x = mGraphView.getGraphContentLeft() + e.getKey(); + if (mStyles.horizontalLabelsAngle > 0 && mStyles.horizontalLabelsAngle < 90f) { + canvas.save(); + canvas.rotate(mStyles.horizontalLabelsAngle, x + labelWidthAdj, y); + canvas.drawText(mPaintLabel, lines[li], x + labelWidthAdj - 20, y); + canvas.restore(); + } else if (mStyles.horizontalLabelsAngle > 0 && mStyles.horizontalLabelsAngle <= 180f) { + canvas.save(); + canvas.rotate(mStyles.horizontalLabelsAngle - 180f, x - labelWidthAdj, y); + canvas.drawText(mPaintLabel, lines[li], x - labelWidthAdj - 20, y); + canvas.restore(); + } else { + canvas.drawText(mPaintLabel, lines[li], x - 20, y); } } - i++; } + i++; } + } - /** - * draws the vertical steps for the - * second scale on the right side - * - * @param canvas canvas - */ - protected void drawVerticalStepsSecondScale (Canvas canvas){ - if (mGraphView.mSecondScale == null) { - return; + /** + * draws the vertical steps for the + * second scale on the right side + * + * @param canvas canvas + */ + protected void drawVerticalStepsSecondScale(Canvas canvas) { + if (mGraphView.mSecondScale == null) { + return; + } + + // draw only the vertical labels on the right + float startLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth(); + mPaintLabel.setColor(new Color(getVerticalLabelsSecondScaleColor())); + //Y轴第二刻度文案颜色 + mPaintLabel.setTextAlign(getVerticalLabelsSecondScaleAlign()); + for (Map.Entry e : mStepsVerticalSecondScale.entrySet()) { + float posY = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - e.getKey(); + + // draw label + int labelsWidth = mLabelVerticalSecondScaleWidth; + int labelsOffset = (int) startLeft; + if (getVerticalLabelsSecondScaleAlign() == 2) { + labelsOffset += labelsWidth; + } else if (getVerticalLabelsSecondScaleAlign() == 1) { + labelsOffset += labelsWidth / 2; } - // draw only the vertical labels on the right - float startLeft = mGraphView.getGraphContentLeft() + mGraphView.getGraphContentWidth(); - mPaintLabel.setColor(new Color(getVerticalLabelsSecondScaleColor())); - //Y轴第二刻度文案颜色 - mPaintLabel.setTextAlign(getVerticalLabelsSecondScaleAlign()); - for (Map.Entry e : mStepsVerticalSecondScale.entrySet()) { - float posY = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - e.getKey(); - - // draw label - int labelsWidth = mLabelVerticalSecondScaleWidth; - int labelsOffset = (int) startLeft; - if (getVerticalLabelsSecondScaleAlign() == 2) { - labelsOffset += labelsWidth; - } else if (getVerticalLabelsSecondScaleAlign() == 1) { - labelsOffset += labelsWidth / 2; - } + float y = posY; - float y = posY; - - String[] lines = mGraphView.mSecondScale.mLabelFormatter.formatLabel(e.getValue(), false).split("\n"); - y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; - canvas.drawText(mPaintLabel, lines[li], labelsOffset, y2); - } + String[] lines = mGraphView.mSecondScale.mLabelFormatter.formatLabel(e.getValue(), false).split("\n"); + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(mPaintLabel, lines[li], labelsOffset, y2); } } + } - /** - * draws the vertical steps - * horizontal lines and vertical labels - * - * @param canvas canvas - * TODO 画Y轴数据 - */ - protected void drawVerticalSteps (Canvas canvas){ - // draw vertical steps (horizontal lines and vertical labels) - float startLeft = mGraphView.getGraphContentLeft(); - mPaintLabel.setColor(new Color(getVerticalLabelsColor())); - mPaintLabel.setTextAlign(getVerticalLabelsAlign()); - - int numberOfLine = mStepsVertical.size(); - int currentLine = 1; - - for (Map.Entry e : mStepsVertical.entrySet()) { - float posY = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - e.getKey(); - - // draw line - if (mStyles.highlightZeroLines) { - if (e.getValue() == 0d) { - mPaintLine.setStrokeWidth(5); - } else { - mPaintLine.setStrokeWidth(0); - } - } - if (mStyles.gridStyle.drawHorizontal()) { - canvas.drawLine(new Point(startLeft, posY), new Point(startLeft + mGraphView.getGraphContentWidth(), posY), mPaintLine); - } - - //if draw the label above or below the line, we mustn't draw the first for last label, for beautiful design. - boolean isDrawLabel = true; - if ((mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.ABOVE && currentLine == 1) - || (mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.BELOW && currentLine == numberOfLine)) { - isDrawLabel = false; + /** + * draws the vertical steps + * horizontal lines and vertical labels + * + * @param canvas canvas + * TODO 画Y轴数据 + */ + protected void drawVerticalSteps(Canvas canvas) { + // draw vertical steps (horizontal lines and vertical labels) + float startLeft = mGraphView.getGraphContentLeft(); + mPaintLabel.setColor(new Color(getVerticalLabelsColor())); + mPaintLabel.setTextAlign(getVerticalLabelsAlign()); + + int numberOfLine = mStepsVertical.size(); + int currentLine = 1; + + for (Map.Entry e : mStepsVertical.entrySet()) { + float posY = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - e.getKey(); + + // draw line + if (mStyles.highlightZeroLines) { + if (e.getValue() == 0d) { + mPaintLine.setStrokeWidth(5); + } else { + mPaintLine.setStrokeWidth(0); } + } + if (mStyles.gridStyle.drawHorizontal()) { + canvas.drawLine(new Point(startLeft, posY), new Point(startLeft + mGraphView.getGraphContentWidth(), posY), mPaintLine); + } - // draw label - if (isVerticalLabelsVisible() && isDrawLabel) { - int labelsWidth = mLabelVerticalWidth; - int labelsOffset = 0; - if (getVerticalLabelsAlign() == 2) { - labelsOffset = labelsWidth; - labelsOffset -= mStyles.labelsSpace; - } else if (getVerticalLabelsAlign() == 1) { - labelsOffset = labelsWidth / 2; - } - labelsOffset += mStyles.padding + getVerticalAxisTitleWidth(); - - float y = posY; + //if draw the label above or below the line, we mustn't draw the first for last label, for beautiful design. + boolean isDrawLabel = true; + if ((mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.ABOVE && currentLine == 1) + || (mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.BELOW && currentLine == numberOfLine)) { + isDrawLabel = false; + } - String label = mLabelFormatter.formatLabel(e.getValue().intValue(), false); - LogUtil.error("yuxh--verticalLabel--->",label+"~~~"+e.getValue().intValue()); - if (label == null) { - label = ""; - } - String[] lines = label.split("\n"); - switch (mStyles.verticalLabelsVAlign) { - case MID: - y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically - break; - case ABOVE: - y -= 5; - break; - case BELOW: - y += (lines.length * getTextSize() * 1.1f) + 5; - break; - } - for (int li = 0; li < lines.length; li++) { - // for the last line y = height - float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; - canvas.drawText(mPaintLabel, lines[li], labelsOffset-20, y2); - } + // draw label + if (isVerticalLabelsVisible() && isDrawLabel) { + int labelsWidth = mLabelVerticalWidth; + int labelsOffset = 0; + if (getVerticalLabelsAlign() == 2) { + labelsOffset = labelsWidth; + labelsOffset -= mStyles.labelsSpace; + } else if (getVerticalLabelsAlign() == 1) { + labelsOffset = labelsWidth / 2; } + labelsOffset += mStyles.padding + getVerticalAxisTitleWidth(); - currentLine++; - } - } + float y = posY; - /** - * this will do rounding to generate - * nice human-readable bounds. - * - * @param in the raw value that is to be rounded - * @param roundAlwaysUp true if it shall always round up (ceil) - * @return the rounded number - */ - protected double humanRound ( double in, boolean roundAlwaysUp){ - // round-up to 1-steps, 2-steps or 5-steps - int ten = 0; - while (Math.abs(in) >= 10d) { - in /= 10d; - ten++; - } - while (Math.abs(in) < 1d) { - in *= 10d; - ten--; - } - if (roundAlwaysUp) { - if (in == 1d) { - LogUtil.debug("find","find"); - } else if (in <= 2d) { - in = 2d; - } else if (in <= 5d) { - in = 5d; - } else if (in < 10d) { - in = 10d; + String label = mLabelFormatter.formatLabel(e.getValue().intValue(), false); + LogUtil.error("yuxh--verticalLabel--->", label + "~~~" + e.getValue().intValue()); + if (label == null) { + label = ""; + } + String[] lines = label.split("\n"); + switch (mStyles.verticalLabelsVAlign) { + case MID: + y += (lines.length * getTextSize() * 1.1f) / 2; // center text vertically + break; + case ABOVE: + y -= 5; + break; + case BELOW: + y += (lines.length * getTextSize() * 1.1f) + 5; + break; } - } else { // always round down - if (in == 1d) { - LogUtil.debug("find","find"); - } else if (in <= 4.9d) { - in = 2d; - } else if (in <= 9.9d) { - in = 5d; - } else if (in < 15d) { - in = 10d; + for (int li = 0; li < lines.length; li++) { + // for the last line y = height + float y2 = y - (lines.length - li - 1) * getTextSize() * 1.1f; + canvas.drawText(mPaintLabel, lines[li], labelsOffset - 20, y2); } } - return in * Math.pow(10d, ten); - } - /** - * ss - * - * @return the wrapped styles - */ - public Styles getStyles () { - return mStyles; + currentLine++; } + } - /** - * ss - * - * @return the vertical label width - * 0 if there are no vertical labels - */ - public int getLabelVerticalWidth () { - if (mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.ABOVE - || mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.BELOW) { - return 0; + /** + * this will do rounding to generate + * nice human-readable bounds. + * + * @param in the raw value that is to be rounded + * @param roundAlwaysUp true if it shall always round up (ceil) + * @return the rounded number + */ + protected double humanRound(double in, boolean roundAlwaysUp) { + // round-up to 1-steps, 2-steps or 5-steps + int ten = 0; + while (Math.abs(in) >= 10d) { + in /= 10d; + ten++; + } + while (Math.abs(in) < 1d) { + in *= 10d; + ten--; + } + if (roundAlwaysUp) { + if (in == 1d) { + LogUtil.debug("find", "find"); + } else if (in <= 2d) { + in = 2d; + } else if (in <= 5d) { + in = 5d; + } else if (in < 10d) { + in = 10d; + } + } else { // always round down + if (in == 1d) { + LogUtil.debug("find", "find"); + } else if (in <= 4.9d) { + in = 2d; + } else if (in <= 9.9d) { + in = 5d; + } else if (in < 15d) { + in = 10d; } - return mLabelVerticalWidth == null || !isVerticalLabelsVisible() ? 0 : mLabelVerticalWidth; } + return in * Math.pow(10d, ten); + } - /** - * sets a manual and fixed with of the space for - * the vertical labels. This will prevent GraphView to - * calculate the width automatically. - * - * @param width the width of the space for the vertical labels. - * Use null to let GraphView automatically calculate the width. - */ - public void setLabelVerticalWidth (Integer width){ - mLabelVerticalWidth = width; - mLabelVerticalWidthFixed = mLabelVerticalWidth != null; - } + /** + * ss + * + * @return the wrapped styles + */ + public Styles getStyles() { + return mStyles; + } - /** - * ss - * - * @return the horizontal label height - * 0 if there are no horizontal labels - */ - public int getLabelHorizontalHeight () { - return mLabelHorizontalHeight == null || !isHorizontalLabelsVisible() ? 0 : mLabelHorizontalHeight; + /** + * ss + * + * @return the vertical label width + * 0 if there are no vertical labels + */ + public int getLabelVerticalWidth() { + if (mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.ABOVE + || mStyles.verticalLabelsVAlign == VerticalLabelsVAlign.BELOW) { + return 0; } + return mLabelVerticalWidth == null || !isVerticalLabelsVisible() ? 0 : mLabelVerticalWidth; + } - /** - * sets a manual and fixed height of the space for - * the horizontal labels. This will prevent GraphView to - * calculate the height automatically. - * - * @param height the height of the space for the horizontal labels. - * Use null to let GraphView automatically calculate the height. - */ - public void setLabelHorizontalHeight (Integer height){ - mLabelHorizontalHeight = height; - mLabelHorizontalHeightFixed = mLabelHorizontalHeight != null; - } + /** + * sets a manual and fixed with of the space for + * the vertical labels. This will prevent GraphView to + * calculate the width automatically. + * + * @param width the width of the space for the vertical labels. + * Use null to let GraphView automatically calculate the width. + */ + public void setLabelVerticalWidth(Integer width) { + mLabelVerticalWidth = width; + mLabelVerticalWidthFixed = mLabelVerticalWidth != null; + } - /** - * ss - * - * @return the grid line color - */ - public int getGridColor () { - return mStyles.gridColor; - } + /** + * ss + * + * @return the horizontal label height + * 0 if there are no horizontal labels + */ + public int getLabelHorizontalHeight() { + return mLabelHorizontalHeight == null || !isHorizontalLabelsVisible() ? 0 : mLabelHorizontalHeight; + } - /** - * ss - * - * @return whether the line at 0 are highlighted - */ - public boolean isHighlightZeroLines () { - return mStyles.highlightZeroLines; - } + /** + * sets a manual and fixed height of the space for + * the horizontal labels. This will prevent GraphView to + * calculate the height automatically. + * + * @param height the height of the space for the horizontal labels. + * Use null to let GraphView automatically calculate the height. + */ + public void setLabelHorizontalHeight(Integer height) { + mLabelHorizontalHeight = height; + mLabelHorizontalHeightFixed = mLabelHorizontalHeight != null; + } - /** - * ss - * - * @return the padding around the grid and labels - */ - public int getPadding () { - return mStyles.padding; - } + /** + * ss + * + * @return the grid line color + */ + public int getGridColor() { + return mStyles.gridColor; + } - /** - * ss - * - * @param textSize the general text size of the axis titles. - * can be overwritten with {@link #setVerticalAxisTitleTextSize(float)} - * and {@link #setHorizontalAxisTitleTextSize(float)} - */ - public void setTextSize ( float textSize){ - mStyles.textSize = textSize; - reloadStyles(); - } + /** + * ss + * + * @return whether the line at 0 are highlighted + */ + public boolean isHighlightZeroLines() { + return mStyles.highlightZeroLines; + } - /** - * ss - * - * @param verticalLabelsAlign the alignment of the vertical labels - */ - public void setVerticalLabelsAlign ( int verticalLabelsAlign){ - mStyles.verticalLabelsAlign = verticalLabelsAlign; - } + /** + * ss + * + * @return the padding around the grid and labels + */ + public int getPadding() { + return mStyles.padding; + } - /** - * ss - * - * @param verticalLabelsColor the color of the vertical labels - */ - public void setVerticalLabelsColor ( int verticalLabelsColor){ - mStyles.verticalLabelsColor = verticalLabelsColor; - } + /** + * ss + * + * @param textSize the general text size of the axis titles. + * can be overwritten with {@link #setVerticalAxisTitleTextSize(float)} + * and {@link #setHorizontalAxisTitleTextSize(float)} + */ + public void setTextSize(float textSize) { + mStyles.textSize = textSize; + reloadStyles(); + } - /** - * ss - * - * @param horizontalLabelsColor the color of the horizontal labels - */ - public void setHorizontalLabelsColor ( int horizontalLabelsColor){ - mStyles.horizontalLabelsColor = horizontalLabelsColor; - } + /** + * ss + * + * @param verticalLabelsAlign the alignment of the vertical labels + */ + public void setVerticalLabelsAlign(int verticalLabelsAlign) { + mStyles.verticalLabelsAlign = verticalLabelsAlign; + } - /** - * ss - * - * @param horizontalLabelsAngle the angle of the horizontal labels in degrees - */ - public void setHorizontalLabelsAngle ( int horizontalLabelsAngle){ - mStyles.horizontalLabelsAngle = horizontalLabelsAngle; - } + /** + * ss + * + * @param verticalLabelsColor the color of the vertical labels + */ + public void setVerticalLabelsColor(int verticalLabelsColor) { + mStyles.verticalLabelsColor = verticalLabelsColor; + } - /** - * ss - * - * @param gridColor the color of the grid lines - */ - public void setGridColor ( int gridColor){ - mStyles.gridColor = gridColor; - reloadStyles(); - } + /** + * ss + * + * @param horizontalLabelsColor the color of the horizontal labels + */ + public void setHorizontalLabelsColor(int horizontalLabelsColor) { + mStyles.horizontalLabelsColor = horizontalLabelsColor; + } - /** - * ss - * - * @param highlightZeroLines flag whether the zero-lines (vertical+ - * horizontal) shall be highlighted - */ - public void setHighlightZeroLines ( boolean highlightZeroLines){ - mStyles.highlightZeroLines = highlightZeroLines; - } + /** + * ss + * + * @param horizontalLabelsAngle the angle of the horizontal labels in degrees + */ + public void setHorizontalLabelsAngle(int horizontalLabelsAngle) { + mStyles.horizontalLabelsAngle = horizontalLabelsAngle; + } - /** - * ss - * - * @param padding the padding around the graph and labels - */ - public void setPadding ( int padding){ - mStyles.padding = padding; - } + /** + * ss + * + * @param gridColor the color of the grid lines + */ + public void setGridColor(int gridColor) { + mStyles.gridColor = gridColor; + reloadStyles(); + } - /** - * ss - * - * @return the label formatter, that converts - * the raw numbers to strings - */ - public LabelFormatter getLabelFormatter () { - return mLabelFormatter; - } + /** + * ss + * + * @param highlightZeroLines flag whether the zero-lines (vertical+ + * horizontal) shall be highlighted + */ + public void setHighlightZeroLines(boolean highlightZeroLines) { + mStyles.highlightZeroLines = highlightZeroLines; + } - /** - * ss - * - * @param mLabelFormatter the label formatter, that converts - * the raw numbers to strings - */ - public void setLabelFormatter (LabelFormatter mLabelFormatter){ - this.mLabelFormatter = mLabelFormatter; - mLabelFormatter.setViewport(mGraphView.getViewport()); - } + /** + * ss + * + * @param padding the padding around the graph and labels + */ + public void setPadding(int padding) { + mStyles.padding = padding; + } - /** - * ss - * - * @return the title of the horizontal axis - */ - public String getHorizontalAxisTitle () { - return mHorizontalAxisTitle; - } + /** + * ss + * + * @return the label formatter, that converts + * the raw numbers to strings + */ + public LabelFormatter getLabelFormatter() { + return mLabelFormatter; + } - /** - * ss - * - * @param mHorizontalAxisTitle the title of the horizontal axis - */ - public void setHorizontalAxisTitle (String mHorizontalAxisTitle){ - this.mHorizontalAxisTitle = mHorizontalAxisTitle; - } + /** + * ss + * + * @param mLabelFormatter the label formatter, that converts + * the raw numbers to strings + */ + public void setLabelFormatter(LabelFormatter mLabelFormatter) { + this.mLabelFormatter = mLabelFormatter; + mLabelFormatter.setViewport(mGraphView.getViewport()); + } - /** - * ss - * - * @return the title of the vertical axis - */ - public String getVerticalAxisTitle () { - return mVerticalAxisTitle; - } + /** + * ss + * + * @return the title of the horizontal axis + */ + public String getHorizontalAxisTitle() { + return mHorizontalAxisTitle; + } - /** - * ss - * - * @param mVerticalAxisTitle the title of the vertical axis - */ - public void setVerticalAxisTitle (String mVerticalAxisTitle){ - this.mVerticalAxisTitle = mVerticalAxisTitle; - } + /** + * ss + * + * @param mHorizontalAxisTitle the title of the horizontal axis + */ + public void setHorizontalAxisTitle(String mHorizontalAxisTitle) { + this.mHorizontalAxisTitle = mHorizontalAxisTitle; + } - /** - * ss - * - * @return font size of the vertical axis title - */ - public float getVerticalAxisTitleTextSize () { - return mStyles.verticalAxisTitleTextSize; - } + /** + * ss + * + * @return the title of the vertical axis + */ + public String getVerticalAxisTitle() { + return mVerticalAxisTitle; + } - /** - * ss - * - * @param verticalAxisTitleTextSize font size of the vertical axis title - */ - public void setVerticalAxisTitleTextSize ( float verticalAxisTitleTextSize){ - mStyles.verticalAxisTitleTextSize = verticalAxisTitleTextSize; - } + /** + * ss + * + * @param mVerticalAxisTitle the title of the vertical axis + */ + public void setVerticalAxisTitle(String mVerticalAxisTitle) { + this.mVerticalAxisTitle = mVerticalAxisTitle; + } - /** - * ss - * - * @return font color of the vertical axis title - */ - public int getVerticalAxisTitleColor () { - return mStyles.verticalAxisTitleColor; - } + /** + * ss + * + * @return font size of the vertical axis title + */ + public float getVerticalAxisTitleTextSize() { + return mStyles.verticalAxisTitleTextSize; + } - /** - * ss - * - * @param verticalAxisTitleColor font color of the vertical axis title - */ - public void setVerticalAxisTitleColor ( int verticalAxisTitleColor){ - mStyles.verticalAxisTitleColor = verticalAxisTitleColor; - } + /** + * ss + * + * @param verticalAxisTitleTextSize font size of the vertical axis title + */ + public void setVerticalAxisTitleTextSize(float verticalAxisTitleTextSize) { + mStyles.verticalAxisTitleTextSize = verticalAxisTitleTextSize; + } - /** - * ss - * - * @return font size of the horizontal axis title - */ - public float getHorizontalAxisTitleTextSize () { - return mStyles.horizontalAxisTitleTextSize; - } + /** + * ss + * + * @return font color of the vertical axis title + */ + public int getVerticalAxisTitleColor() { + return mStyles.verticalAxisTitleColor; + } - /** - * ss - * - * @param horizontalAxisTitleTextSize font size of the horizontal axis title - */ - public void setHorizontalAxisTitleTextSize ( float horizontalAxisTitleTextSize){ + /** + * ss + * + * @param verticalAxisTitleColor font color of the vertical axis title + */ + public void setVerticalAxisTitleColor(int verticalAxisTitleColor) { + mStyles.verticalAxisTitleColor = verticalAxisTitleColor; + } + + /** + * ss + * + * @return font size of the horizontal axis title + */ + public float getHorizontalAxisTitleTextSize() { + return mStyles.horizontalAxisTitleTextSize; + } + + /** + * ss + * + * @param horizontalAxisTitleTextSize font size of the horizontal axis title + */ + public void setHorizontalAxisTitleTextSize(float horizontalAxisTitleTextSize) { + if (horizontalAxisTitleTextSize > 0) { mStyles.horizontalAxisTitleTextSize = horizontalAxisTitleTextSize; + } else { + mStyles.horizontalAxisTitleTextSize = 20; } - /** - * ss - * - * @return font color of the horizontal axis title - */ - public int getHorizontalAxisTitleColor () { - return mStyles.horizontalAxisTitleColor; - } + } - /** - * ss - * - * @param horizontalAxisTitleColor font color of the horizontal axis title - */ - public void setHorizontalAxisTitleColor ( int horizontalAxisTitleColor){ - mStyles.horizontalAxisTitleColor = horizontalAxisTitleColor; - } + /** + * ss + * + * @return font color of the horizontal axis title + */ + public int getHorizontalAxisTitleColor() { + return mStyles.horizontalAxisTitleColor; + } - /** - * ss - * - * @return the alignment of the labels on the right side - */ - public int getVerticalLabelsSecondScaleAlign () { - return mStyles.verticalLabelsSecondScaleAlign; - } + /** + * ss + * + * @param horizontalAxisTitleColor font color of the horizontal axis title + */ + public void setHorizontalAxisTitleColor(int horizontalAxisTitleColor) { + mStyles.horizontalAxisTitleColor = horizontalAxisTitleColor; + } - /** - * ss - * - * @param verticalLabelsSecondScaleAlign the alignment of the labels on the right side - */ - public void setVerticalLabelsSecondScaleAlign ( int verticalLabelsSecondScaleAlign){ - mStyles.verticalLabelsSecondScaleAlign = verticalLabelsSecondScaleAlign; - } + /** + * ss + * + * @return the alignment of the labels on the right side + */ + public int getVerticalLabelsSecondScaleAlign() { + return mStyles.verticalLabelsSecondScaleAlign; + } - /** - * ss - * - * @return the color of the labels on the right side - */ - public int getVerticalLabelsSecondScaleColor () { - return mStyles.verticalLabelsSecondScaleColor; - } + /** + * ss + * + * @param verticalLabelsSecondScaleAlign the alignment of the labels on the right side + */ + public void setVerticalLabelsSecondScaleAlign(int verticalLabelsSecondScaleAlign) { + mStyles.verticalLabelsSecondScaleAlign = verticalLabelsSecondScaleAlign; + } - /** - * ss - * - * @param verticalLabelsSecondScaleColor the color of the labels on the right side - */ - public void setVerticalLabelsSecondScaleColor ( int verticalLabelsSecondScaleColor){ - mStyles.verticalLabelsSecondScaleColor = verticalLabelsSecondScaleColor; - } + /** + * ss + * + * @return the color of the labels on the right side + */ + public int getVerticalLabelsSecondScaleColor() { + return mStyles.verticalLabelsSecondScaleColor; + } - /** - * ss - * - * @return the width of the vertical labels - * of the second scale - */ - public int getLabelVerticalSecondScaleWidth () { - return mLabelVerticalSecondScaleWidth == null ? 0 : mLabelVerticalSecondScaleWidth; - } + /** + * ss + * + * @param verticalLabelsSecondScaleColor the color of the labels on the right side + */ + public void setVerticalLabelsSecondScaleColor(int verticalLabelsSecondScaleColor) { + mStyles.verticalLabelsSecondScaleColor = verticalLabelsSecondScaleColor; + } - /** - * ss - * - * @return flag whether the horizontal labels are - * visible - */ - public boolean isHorizontalLabelsVisible () { - return mStyles.horizontalLabelsVisible; - } + /** + * ss + * + * @return the width of the vertical labels + * of the second scale + */ + public int getLabelVerticalSecondScaleWidth() { + return mLabelVerticalSecondScaleWidth == null ? 0 : mLabelVerticalSecondScaleWidth; + } - /** - * ss - * - * @param horizontalTitleVisible flag whether the horizontal labels are - * visible - */ - public void setHorizontalLabelsVisible ( boolean horizontalTitleVisible){ - mStyles.horizontalLabelsVisible = horizontalTitleVisible; - } + /** + * ss + * + * @return flag whether the horizontal labels are + * visible + */ + public boolean isHorizontalLabelsVisible() { + return mStyles.horizontalLabelsVisible; + } - /** - * ss - * - * @return flag whether the vertical labels are - * visible - */ - public boolean isVerticalLabelsVisible () { - return mStyles.verticalLabelsVisible; - } + /** + * ss + * + * @param horizontalTitleVisible flag whether the horizontal labels are + * visible + */ + public void setHorizontalLabelsVisible(boolean horizontalTitleVisible) { + mStyles.horizontalLabelsVisible = horizontalTitleVisible; + } - /** - * ss - * - * @param verticalTitleVisible flag whether the vertical labels are - * visible - */ - public void setVerticalLabelsVisible ( boolean verticalTitleVisible){ - mStyles.verticalLabelsVisible = verticalTitleVisible; - } + /** + * ss + * + * @return flag whether the vertical labels are + * visible + */ + public boolean isVerticalLabelsVisible() { + return mStyles.verticalLabelsVisible; + } - /** - * ss - * - * @return count of the vertical labels, that - * will be shown at one time. - */ - public int getNumVerticalLabels () { - return mNumVerticalLabels; - } + /** + * ss + * + * @param verticalTitleVisible flag whether the vertical labels are + * visible + */ + public void setVerticalLabelsVisible(boolean verticalTitleVisible) { + mStyles.verticalLabelsVisible = verticalTitleVisible; + } - /** - * ss - * - * @param mNumVerticalLabels count of the vertical labels, that - * will be shown at one time. - */ - public void setNumVerticalLabels ( int mNumVerticalLabels){ - this.mNumVerticalLabels = mNumVerticalLabels; - } + /** + * ss + * + * @return count of the vertical labels, that + * will be shown at one time. + */ + public int getNumVerticalLabels() { + return mNumVerticalLabels; + } - /** - * ss - * - * @return count of the horizontal labels, that - * will be shown at one time. - */ - public int getNumHorizontalLabels () { - return mNumHorizontalLabels; - } + /** + * ss + * + * @param mNumVerticalLabels count of the vertical labels, that + * will be shown at one time. + */ + public void setNumVerticalLabels(int mNumVerticalLabels) { + this.mNumVerticalLabels = mNumVerticalLabels; + } - /** - * ss - * - * @param mNumHorizontalLabels count of the horizontal labels, that - * will be shown at one time. - */ - public void setNumHorizontalLabels ( int mNumHorizontalLabels){ + /** + * ss + * + * @return count of the horizontal labels, that + * will be shown at one time. + */ + public int getNumHorizontalLabels() { + return mNumHorizontalLabels; + } + + /** + * ss + * + * @param mNumHorizontalLabels count of the horizontal labels, that + * will be shown at one time. + */ + public void setNumHorizontalLabels(int mNumHorizontalLabels) { + if (mNumHorizontalLabels > 0) { this.mNumHorizontalLabels = mNumHorizontalLabels; + } else { + this.mNumHorizontalLabels = 20; } - /** - * ss - * - * @return the grid style - */ - public GridStyle getGridStyle () { - return mStyles.gridStyle; - } + } - /** - * Define which grid lines shall be drawn - * - * @param gridStyle the grid style - */ - public void setGridStyle (GridStyle gridStyle){ - mStyles.gridStyle = gridStyle; - } + /** + * ss + * + * @return the grid style + */ + public GridStyle getGridStyle() { + return mStyles.gridStyle; + } - /** - * ss - * - * @return the space between the labels text and the graph content - */ - public int getLabelsSpace () { - return mStyles.labelsSpace; - } + /** + * Define which grid lines shall be drawn + * + * @param gridStyle the grid style + */ + public void setGridStyle(GridStyle gridStyle) { + mStyles.gridStyle = gridStyle; + } - /** - * the space between the labels text and the graph content - * - * @param labelsSpace the space between the labels text and the graph content - */ - public void setLabelsSpace ( int labelsSpace){ - mStyles.labelsSpace = labelsSpace; - } + /** + * ss + * + * @return the space between the labels text and the graph content + */ + public int getLabelsSpace() { + return mStyles.labelsSpace; + } + /** + * the space between the labels text and the graph content + * + * @param labelsSpace the space between the labels text and the graph content + */ + public void setLabelsSpace(int labelsSpace) { + mStyles.labelsSpace = labelsSpace; + } - /** - * set horizontal label align - * - * @param align - */ - public void setVerticalLabelsVAlign (VerticalLabelsVAlign align){ - mStyles.verticalLabelsVAlign = align; - } - /** - * Get horizontal label align - * - * @return align - */ - public VerticalLabelsVAlign getVerticalLabelsVAlign () { - return mStyles.verticalLabelsVAlign; - } + /** + * set horizontal label align + * + * @param align + */ + public void setVerticalLabelsVAlign(VerticalLabelsVAlign align) { + mStyles.verticalLabelsVAlign = align; + } + + /** + * Get horizontal label align + * + * @return align + */ + public VerticalLabelsVAlign getVerticalLabelsVAlign() { + return mStyles.verticalLabelsVAlign; } +} diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java b/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java index a016196..cf0f961 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java @@ -1,13 +1,13 @@ /** * GraphView * Copyright 2016 Jonas Gehring - * + *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + *

* http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -153,7 +153,7 @@ public class LegendRenderer { mPaint.setTextSize((int) mStyles.textSize); - int shapeSize = (int) (mStyles.textSize*0.8d); + int shapeSize = (int) (mStyles.textSize * 0.8d); List allSeries = getAllSeries(); @@ -174,13 +174,13 @@ public class LegendRenderer { if (legendWidth == 0) legendWidth = 1; // add shape size - legendWidth += shapeSize+mStyles.padding*2 + mStyles.spacing; + legendWidth += shapeSize + mStyles.padding * 2 + mStyles.spacing; cachedLegendWidth = legendWidth; } } // rect - float legendHeight = (mStyles.textSize+mStyles.spacing)*allSeries.size() -mStyles.spacing; + float legendHeight = (mStyles.textSize + mStyles.spacing) * allSeries.size() - mStyles.spacing; float lLeft; float lTop; if (mStyles.fixedPosition != null) { @@ -197,25 +197,25 @@ public class LegendRenderer { lTop = mGraphView.getHeight() / 2 - legendHeight / 2; break; default: - lTop = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - mStyles.margin - legendHeight - 2*mStyles.padding; + lTop = mGraphView.getGraphContentTop() + mGraphView.getGraphContentHeight() - mStyles.margin - legendHeight - 2 * mStyles.padding; } } - float lRight = lLeft+legendWidth; - float lBottom = lTop+legendHeight+2*mStyles.padding; + float lRight = lLeft + legendWidth; + float lBottom = lTop + legendHeight + 2 * mStyles.padding; mPaint.setColor(new Color(mStyles.backgroundColor)); RectFloat rectF = new RectFloat(lLeft, lTop, lRight, lBottom); canvas.drawRoundRect(rectF, 8, 8, mPaint); - int i=0; + int i = 0; for (Series series : allSeries) { mPaint.setColor(new Color(series.getColor())); - canvas.drawRect(new RectFloat(lLeft+mStyles.padding, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing)), lLeft+mStyles.padding+shapeSize, lTop+mStyles.padding+(i*(mStyles.textSize+mStyles.spacing))+shapeSize), mPaint); + canvas.drawRect(new RectFloat(lLeft + mStyles.padding, lTop + mStyles.padding + (i * (mStyles.textSize + mStyles.spacing)), lLeft + mStyles.padding + shapeSize, lTop + mStyles.padding + (i * (mStyles.textSize + mStyles.spacing)) + shapeSize), mPaint); if (series.getTitle() != null) { mPaint.setColor(new Color(mStyles.textColor)); //右侧提示语 - canvas.drawText(mPaint,series.getTitle(),lLeft+mStyles.padding+shapeSize+mStyles.spacing,lTop+mStyles.padding+mStyles.textSize+(i*(mStyles.textSize+mStyles.spacing))-5); + canvas.drawText(mPaint, series.getTitle(), lLeft + mStyles.padding + shapeSize + mStyles.spacing, lTop + mStyles.padding + mStyles.textSize + (i * (mStyles.textSize + mStyles.spacing)) - 5); } i++; } @@ -255,7 +255,12 @@ public class LegendRenderer { * @param textSize font size */ public void setTextSize(float textSize) { - mStyles.textSize = textSize; + if (textSize > 0) { + mStyles.textSize = textSize; + } else { + mStyles.textSize = 20; + } + cachedLegendWidth = 0; } @@ -300,7 +305,7 @@ public class LegendRenderer { /** * the width of the box exclusive padding * - * @return the width of the box + * @return the width of the box * 0 => auto */ public int getWidth() { @@ -320,7 +325,7 @@ public class LegendRenderer { /** * ss * - * @return background color of the box + * @return background color of the box * it is recommended to use semi-transparent * color. */ @@ -342,7 +347,7 @@ public class LegendRenderer { /** * ss * - * @return margin from the edge of the box + * @return margin from the edge of the box * to the corner of the graphview */ public int getMargin() { -- Gitee From aeefe8e16fd78a4f3b72927633e12ab9ed095fcf Mon Sep 17 00:00:00 2001 From: yu_xh <940151214@qq.com> Date: Fri, 24 Sep 2021 15:52:27 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=9C=A8=E5=9B=BE?= =?UTF-8?q?=E5=88=97=E4=B8=AD=E6=B8=B2=E6=9F=93=E4=B8=80=E6=AC=A1=E5=85=B7?= =?UTF-8?q?=E6=9C=89=E7=9B=B8=E5=90=8C=E5=90=8D=E7=A7=B0=E5=92=8C=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E4=B8=8D=E8=B5=B7=E4=BD=9C=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jjoe64/graphview/LegendRenderer.java | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java b/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java index cf0f961..3fef46d 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/LegendRenderer.java @@ -21,6 +21,7 @@ import com.jjoe64.graphview.utils.Point; import ohos.agp.render.Canvas; import ohos.agp.render.Paint; import ohos.agp.utils.Color; +import ohos.agp.utils.Rect; import ohos.agp.utils.RectFloat; @@ -180,7 +181,7 @@ public class LegendRenderer { } // rect - float legendHeight = (mStyles.textSize + mStyles.spacing) * allSeries.size() - mStyles.spacing; + float legendHeight = (mStyles.textSize + mStyles.spacing) * removeDuplicate(allSeries).size()- mStyles.spacing; float lLeft; float lTop; if (mStyles.fixedPosition != null) { @@ -209,7 +210,9 @@ public class LegendRenderer { canvas.drawRoundRect(rectF, 8, 8, mPaint); int i = 0; - for (Series series : allSeries) { + + + for (Series series : removeDuplicate(allSeries)) { mPaint.setColor(new Color(series.getColor())); canvas.drawRect(new RectFloat(lLeft + mStyles.padding, lTop + mStyles.padding + (i * (mStyles.textSize + mStyles.spacing)), lLeft + mStyles.padding + shapeSize, lTop + mStyles.padding + (i * (mStyles.textSize + mStyles.spacing)) + shapeSize), mPaint); if (series.getTitle() != null) { @@ -221,6 +224,23 @@ public class LegendRenderer { } } + /** + * 去重 + * @param allSeries + * @return + */ + private List removeDuplicate(List allSeries) { + for (int l = 0; l < allSeries.size() - 1; l++) { + for (int i = allSeries.size() - 1; i > l; i--) { + if (allSeries.get(i).getTitle().equals(allSeries.get(l).getTitle())) { + allSeries.remove(i); + } + } + } + return allSeries; + } + + /** * ss * @@ -306,7 +326,7 @@ public class LegendRenderer { * the width of the box exclusive padding * * @return the width of the box - * 0 => auto + * 0 => auto */ public int getWidth() { return mStyles.width; @@ -315,8 +335,8 @@ public class LegendRenderer { /** * the width of the box exclusive padding * - * @param width the width of the box exclusive padding - * 0 => auto + * @param width the width of the box exclusive padding + * 0 => auto */ public void setWidth(int width) { mStyles.width = width; @@ -326,8 +346,8 @@ public class LegendRenderer { * ss * * @return background color of the box - * it is recommended to use semi-transparent - * color. + * it is recommended to use semi-transparent + * color. */ public int getBackgroundColor() { return mStyles.backgroundColor; @@ -336,9 +356,9 @@ public class LegendRenderer { /** * ss * - * @param backgroundColor background color of the box - * it is recommended to use semi-transparent - * color. + * @param backgroundColor background color of the box + * it is recommended to use semi-transparent + * color. */ public void setBackgroundColor(int backgroundColor) { mStyles.backgroundColor = backgroundColor; @@ -348,7 +368,7 @@ public class LegendRenderer { * ss * * @return margin from the edge of the box - * to the corner of the graphview + * to the corner of the graphview */ public int getMargin() { return mStyles.margin; @@ -357,8 +377,8 @@ public class LegendRenderer { /** * ss * - * @param margin margin from the edge of the box - * to the corner of the graphview + * @param margin margin from the edge of the box + * to the corner of the graphview */ public void setMargin(int margin) { mStyles.margin = margin; -- Gitee From 078e9d2defc962a9466748f346d298f47dd98091 Mon Sep 17 00:00:00 2001 From: yu_xh <940151214@qq.com> Date: Sun, 26 Sep 2021 16:41:09 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../graphview_os/slice/MainAbilitySlice.java | 178 +++++++++++++++++- .../graphview/series/BarGraphSeries.java | 2 +- 2 files changed, 172 insertions(+), 8 deletions(-) diff --git a/entry/src/main/java/com/jjoe64/graphview_os/slice/MainAbilitySlice.java b/entry/src/main/java/com/jjoe64/graphview_os/slice/MainAbilitySlice.java index bdf9999..f34d72a 100644 --- a/entry/src/main/java/com/jjoe64/graphview_os/slice/MainAbilitySlice.java +++ b/entry/src/main/java/com/jjoe64/graphview_os/slice/MainAbilitySlice.java @@ -1,7 +1,9 @@ package com.jjoe64.graphview_os.slice; import com.jjoe64.graphview.GraphView; +import com.jjoe64.graphview.UniqueLegendRenderer; import com.jjoe64.graphview.helper.GraphViewXML; +import com.jjoe64.graphview.helper.StaticLabelsFormatter; import com.jjoe64.graphview.series.BarGraphSeries; import com.jjoe64.graphview.series.DataPoint; import com.jjoe64.graphview.series.DataPointInterface; @@ -32,7 +34,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { @Override protected void initView() { graphView = (GraphView) findComponentById(ResourceTable.Id_graphView); - graphViewXml = (GraphViewXML) findComponentById(ResourceTable.Id_graphViewXml); +// graphViewXml = (GraphViewXML) findComponentById(ResourceTable.Id_graphViewXml); componentById = (Button) findComponentById(ResourceTable.Id_tvButton); @@ -84,7 +86,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { // } // // mIndex += 1; - test9(); + test15(); } }); @@ -95,7 +97,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { } - private void test1(){ + private void test1() { BarGraphSeries series = new BarGraphSeries<>(new DataPoint[]{ new DataPoint(0, 520.5), new DataPoint(492.9, 525), @@ -183,7 +185,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { } - private void test7(){ + private void test7() { LineGraphSeries seriesNew2 = new LineGraphSeries<>(new DataPoint[]{ new DataPoint(3, 20), new DataPoint(4, 50) @@ -204,7 +206,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { graphView.getSecondScale().setVerticalAxisTitleTextSize(-1); } - private void test8(){ + private void test8() { PointsGraphSeries seriesNew = new PointsGraphSeries<>(new DataPoint[]{ new DataPoint(0, 1), new DataPoint(1, 5), @@ -218,7 +220,7 @@ public class MainAbilitySlice extends BaseAbilitySlice { graphView.getGridLabelRenderer().setTextSize(35.5f); } - private void test9(){ + private void test9() { BarGraphSeries series = new BarGraphSeries<>(new DataPoint[]{ new DataPoint(0, 1), new DataPoint(1, 5), @@ -229,7 +231,169 @@ public class MainAbilitySlice extends BaseAbilitySlice { graphView.addSeries(series); series.setTitle("Bar"); graphView.getLegendRenderer().setVisible(true); - graphView.getLegendRenderer().setFixedPosition(583,90); + graphView.getLegendRenderer().setFixedPosition(583, 90); graphView.getLegendRenderer().setMargin(30); } + + private void test10() { + LineGraphSeries lineGraph = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 1), + new DataPoint(1, 5), + new DataPoint(2, 3), + new DataPoint(3, 2), + new DataPoint(4, 6) + }); + lineGraph.setDrawAsPath(true); + PointsGraphSeries pointsGraph = new PointsGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 2), + new DataPoint(2, 5), + new DataPoint(4, 1), + new DataPoint(6, 4), + new DataPoint(8, 6) + }); + graphView.addSeries(lineGraph); + graphView.addSeries(pointsGraph); + StaticLabelsFormatter staticLabelsFormatter = new StaticLabelsFormatter(graphView, new String[]{"old", "new"}, new String[]{"high", "low"}); + graphView.getGridLabelRenderer().setLabelFormatter(staticLabelsFormatter); + } + + private void test11() { + PointsGraphSeries pointsGraphSeries = new PointsGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 1), + new DataPoint(1, 5), + new DataPoint(2, 3), + new DataPoint(3, 2), + new DataPoint(4, 6) + }); + graphView.addSeries(pointsGraphSeries); + graphView.getGridLabelRenderer().setPadding(4); + } + + private void test12() { + PointsGraphSeries pointsGraphSeries = new PointsGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 2), + new DataPoint(2, 5), + new DataPoint(4, 1), + new DataPoint(6, 4), + new DataPoint(8, 6) + }); + graphView.addSeries(pointsGraphSeries); + graphView.getGridLabelRenderer().setLabelsSpace(104); + } + + private void test13() { + BarGraphSeries series = new BarGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 1), + new DataPoint(1, 5), + new DataPoint(2, 3), + new DataPoint(3, 2), + new DataPoint(4, 6) + }); + graphView.addSeries(series); + } + + private void test14() { + LineGraphSeries lineGraph = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(0.0, 1.0), + new DataPoint(2.0, -51.0), + new DataPoint(2.0, -51.0), + }); + lineGraph.setTitle("Air"); + lineGraph.setColor(Color.rgb(115,211,230)); + graphView.addSeries(lineGraph); + + LineGraphSeries lineGraph2 = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(2.0, -51.0), + new DataPoint(5.0, -110.0), + new DataPoint(15.0, -110.0), + new DataPoint(21.0, -51.0), + new DataPoint(21.0, -51.0) + }); + lineGraph2.setTitle("TMX12/50"); + lineGraph2.setColor(Color.getIntColor("#000000")); + graphView.addSeries(lineGraph2); + + LineGraphSeries lineGraph4 = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(34.3, -21.0), + new DataPoint(37.0, -21.0), + new DataPoint(37.3, -18.0), + new DataPoint(41.0, -18.0), + new DataPoint(41.3, -15.0), + new DataPoint(46.0, -15.0), + new DataPoint(46.3, -12.0), + new DataPoint(54.0, -12.0), + new DataPoint(54.3, -9.0), + new DataPoint(65.0, -9.0), + new DataPoint(65.3, -6.0), + new DataPoint(84.0, -6.0), + new DataPoint(84.3, -3.0), + new DataPoint(124.0, -3.0), + new DataPoint(124.3, 0.0) + }); + lineGraph4.setTitle("NTX50"); + lineGraph4.setColor(Color.rgb(115,230,115)); + graphView.addSeries(lineGraph4); + + LineGraphSeries lineGraph3 = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(21.0, -51.0), + new DataPoint(22.0, -51.0), + new DataPoint(22.3, -48.0), + new DataPoint(23.0, -48.0), + new DataPoint(23.3, -45.0), + new DataPoint(24.0, -45.0), + new DataPoint(24.3, -45.0), + new DataPoint(25.0, -42.0), + new DataPoint(25.3, -39.0), + new DataPoint(26.3, -36.0), + new DataPoint(27.0, -36.0), + new DataPoint(27.3, -33.0), + new DataPoint(28.0, -33.0), + new DataPoint(28.3, -30.0), + new DataPoint(29.0, -30.0), + new DataPoint(29.3, -27.0), + new DataPoint(31.0, -27.0), + new DataPoint(31.3, -24.0), + new DataPoint(34.0, -24.0), + new DataPoint(34.3, -21.0) + }); + lineGraph3.setTitle("Air"); + lineGraph3.setColor(Color.rgb(115,211,230)); + graphView.addSeries(lineGraph3); + + graphView.getViewport().setMinX(0); + graphView.getViewport().setMaxX(130); + graphView.getViewport().setXAxisBoundsManual(true); + graphView.getViewport().setMinY(-115); + graphView.getViewport().setMaxY(0); + graphView.getViewport().setXAxisBoundsManual(true); + graphView.getGridLabelRenderer().setHighlightZeroLines(false); + + graphView.setLegendRenderer(new UniqueLegendRenderer(graphView)); + graphView.getLegendRenderer().setVisible(true); + + } + + private void test15(){ + LineGraphSeries lineGraph = new LineGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 1), + new DataPoint(1, 5), + new DataPoint(2, 3), + new DataPoint(3, 2), + new DataPoint(4, 6) + }); + graphView.addSeries(lineGraph); + + PointsGraphSeries pointsGraphSeries = new PointsGraphSeries<>(new DataPoint[]{ + new DataPoint(0, 120), + new DataPoint(1, -30), + new DataPoint(2, 60), + new DataPoint(3, 20), + new DataPoint(4, 50) + }); + graphView.getSecondScale().setMinY(20.6f); + graphView.getSecondScale().setMaxY(100.8f); + graphView.getSecondScale().addSeries(pointsGraphSeries); + graphView.getGridLabelRenderer().setVerticalLabelsSecondScaleColor(Color.RED.getValue()); + + } } diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java b/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java index 14938d8..d7dd3f6 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java @@ -157,7 +157,7 @@ public class BarGraphSeries extends BaseSeries if (mValuesOnTopSize == 0) { mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize(); } - mPaint.setTextSize((int) (mValuesOnTopSize >= 0 ? mValuesOnTopSize : 0)); + mPaint.setTextSize((int) (mValuesOnTopSize >= 0 ? mValuesOnTopSize : 20)); resetDataPoints(); -- Gitee From 5f82526077690567e922d4b867231dfb5f9a6c57 Mon Sep 17 00:00:00 2001 From: yu_xh <940151214@qq.com> Date: Wed, 29 Sep 2021 16:10:47 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=BE=B9=E8=B7=9D?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E9=BB=98=E8=AE=A4=E5=80=BC=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 27 ++++++++++++++++++- .../jjoe64/graphview/GridLabelRenderer.java | 10 ++++--- .../graphview/series/BarGraphSeries.java | 2 +- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index af3e763..b5e77be 100644 --- a/changelog.md +++ b/changelog.md @@ -1,2 +1,27 @@ # GraphView -v3.1.0支持原有组件的所有效果 \ No newline at end of file +v1.1.0 + + +不支持功能 +1.滑动功能 ,缩放功能 + + +不支持功能具体API如下 + +1. BaseSeries --> public void appendData(E dataPoint,boolean scrollToEnd,int maxDataPoints,boolean silent); +2. BaseSeries --> public void appendData(E dataPoint,boolean scrollToEnd,int maxDataPoints); +3. LineGraphSeries --> public void appendData(E dataPoint,boolean scrollToEnd,int maxDataPoints,boolean silent); +4. Viewport --> public boolean isScrollable(); +5. Viewport --> public boolean setScrollable(boolean mIsScrollable); +6. Viewport --> public boolean isScalable(); +7. Viewport --> public boolean setScalable(boolean mIsScalable); +8. Viewport --> public boolean scalableTOEnd(); +9. Viewport --> public OnXAxisBoundsChangedListener getOnXAxisBoundsChangedListener (); +10. Viewport --> public void setOnXAxisBoundListener(OnXAxisBoundsChangedListener l); +11. Viewport --> public void setScrollableY(boolean scrollableY); +12. Viewport --> public void setScalableY(boolean scalableY); +13. Viewport --> public double getMaxXAxisSize(); +14. Viewport --> public double getMaxYAxisSize(); +15. Viewport --> public double setMaxXAxisSize(double mMaxXAxisViewportSize); +16. Viewport --> public double setMaxYAxisSize(double mMaxYAxisViewportSize); +16. Viewport --> public double setMinimalViewport(double minX,double maxX,double minY,double maxY); \ No newline at end of file diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java b/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java index 8e534e8..da460dc 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/GridLabelRenderer.java @@ -376,8 +376,8 @@ public class GridLabelRenderer { color1 = Color.BLACK.getValue(); color2 = Color.GRAY.getValue(); - size = 20; - size2 = 20; + size = 25; + size2 = 25; mStyles.verticalLabelsColor = color1; mStyles.verticalLabelsSecondScaleColor = color1; @@ -1614,7 +1614,11 @@ public class GridLabelRenderer { * @param padding the padding around the graph and labels */ public void setPadding(int padding) { - mStyles.padding = padding; + if (padding < 15) { + mStyles.padding = 15; + } else { + mStyles.padding = padding; + } } /** diff --git a/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java b/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java index d7dd3f6..4689cb4 100644 --- a/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java +++ b/graphveiw/src/main/java/com/jjoe64/graphview/series/BarGraphSeries.java @@ -154,7 +154,7 @@ public class BarGraphSeries extends BaseSeries @Override public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) { mPaint.setTextAlign(1); - if (mValuesOnTopSize == 0) { + if (mValuesOnTopSize == 0) { mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize(); } mPaint.setTextSize((int) (mValuesOnTopSize >= 0 ? mValuesOnTopSize : 20)); -- Gitee