diff --git a/chartLib/src/main/kotlin/info/appdev/charting/components/Legend.kt b/chartLib/src/main/kotlin/info/appdev/charting/components/Legend.kt index aba13720b..1e61679cb 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/components/Legend.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/components/Legend.kt @@ -4,10 +4,13 @@ import android.graphics.DashPathEffect import android.graphics.Paint import info.appdev.charting.utils.ColorTemplate import info.appdev.charting.utils.FSize -import info.appdev.charting.utils.Utils import info.appdev.charting.utils.ViewPortHandler import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextWidth import info.appdev.charting.utils.convertDpToPixel +import info.appdev.charting.utils.calcTextSize +import info.appdev.charting.utils.getLineHeight +import info.appdev.charting.utils.getLineSpacing import kotlin.Array import kotlin.Boolean import kotlin.IntArray @@ -203,7 +206,7 @@ class Legend() : ComponentBase() { val label = entry.label ?: continue - val length = Utils.calcTextWidth(p, label).toFloat() + val length = p.calcTextWidth(label).toFloat() if (length > max) max = length } @@ -309,16 +312,13 @@ class Legend() : ComponentBase() { /** * the total width of the legend (needed width space) */ - @JvmField var neededWidth: Float = 0f /** * the total height of the legend (needed height space) */ - @JvmField var neededHeight: Float = 0f - @JvmField var mTextHeightMax: Float = 0f var mTextWidthMax: Float = 0f @@ -375,7 +375,7 @@ class Legend() : ComponentBase() { var maxWidth = 0f var maxHeight = 0f var width = 0f - val labelLineHeight = Utils.getLineHeight(labelpaint) + val labelLineHeight = labelpaint.getLineHeight() var wasStacked = false var i = 0 @@ -407,7 +407,7 @@ class Legend() : ComponentBase() { wasStacked = false } - width += Utils.calcTextWidth(labelpaint, label).toFloat() + width += labelpaint.calcTextWidth(label).toFloat() maxHeight += labelLineHeight + yEntrySpace } else { @@ -425,8 +425,8 @@ class Legend() : ComponentBase() { } LegendOrientation.HORIZONTAL -> { - val labelLineHeight = Utils.getLineHeight(labelpaint) - val labelLineSpacing = Utils.getLineSpacing(labelpaint) + yEntrySpace + val labelLineHeight = labelpaint.getLineHeight() + val labelLineSpacing = labelpaint.getLineSpacing() + yEntrySpace val contentWidth = viewPortHandler.contentWidth() * this.maxSizePercent // Start calculating layout @@ -462,7 +462,7 @@ class Legend() : ComponentBase() { // grouped forms have null labels if (label != null) { - calculatedLabelSizes.add(Utils.calcTextSize(labelpaint, label)) + calculatedLabelSizes.add(labelpaint.calcTextSize(label)) requiredWidth += if (drawingForm) formToTextSpace + formSize else 0f requiredWidth += calculatedLabelSizes.get(i)!!.width } else { diff --git a/chartLib/src/main/kotlin/info/appdev/charting/components/YAxis.kt b/chartLib/src/main/kotlin/info/appdev/charting/components/YAxis.kt index ff5b5e0a5..763d831e8 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/components/YAxis.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/components/YAxis.kt @@ -2,8 +2,8 @@ package info.appdev.charting.components import android.graphics.Color import android.graphics.Paint -import info.appdev.charting.utils.Utils import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextWidth import info.appdev.charting.utils.convertDpToPixel import kotlin.math.abs import kotlin.math.max @@ -52,30 +52,18 @@ class YAxis : AxisBase { var isDrawZeroLineEnabled: Boolean = false protected set - /** - * Returns true if autoscale restriction for axis min value is enabled - */ - /** - * Sets autoscale restriction for axis min value as enabled/disabled - */ /** * flag indicating that auto scale min restriction should be used */ - @get:Deprecated("") - @set:Deprecated("") + @get:Deprecated("flag indicating that auto scale min restriction should be used") + @set:Deprecated("flag indicating that auto scale min restriction should be used") var isUseAutoScaleMinRestriction: Boolean = false - /** - * Returns true if autoscale restriction for axis max value is enabled - */ - /** - * Sets autoscale restriction for axis max value as enabled/disabled - */ /** * flag indicating that auto scale max restriction should be used */ - @get:Deprecated("") - @set:Deprecated("") + @get:Deprecated("flag indicating that auto scale max restriction should be used") + @set:Deprecated("flag indicating that auto scale max restriction should be used") var isUseAutoScaleMaxRestriction: Boolean = false /** @@ -240,7 +228,7 @@ class YAxis : AxisBase { p.textSize = mTextSize val label = getLongestLabel(p) - var width = Utils.calcTextWidth(p, label).toFloat() + xOffset * 2f + var width = p.calcTextWidth(label).toFloat() + xOffset * 2f var minWidth = this.minWidth var maxWidth = this.maxWidth diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/HorizontalBarChartRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/HorizontalBarChartRenderer.kt index fa74372f5..d18ebca1a 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/HorizontalBarChartRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/HorizontalBarChartRenderer.kt @@ -15,6 +15,7 @@ import info.appdev.charting.utils.Transformer import info.appdev.charting.utils.Utils import info.appdev.charting.utils.ViewPortHandler import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextWidth import info.appdev.charting.utils.convertDpToPixel import kotlin.math.ceil import kotlin.math.min @@ -225,7 +226,7 @@ open class HorizontalBarChartRenderer( val valueY = barEntry.y val formattedValue = formatter.getFormattedValue(valueY, barEntry, i, viewPortHandler) // calculate the correct offset depending on the draw position of the value - val valueTextWidth = Utils.calcTextWidth(paintValues, formattedValue).toFloat() + val valueTextWidth = paintValues.calcTextWidth(formattedValue).toFloat() posOffset = (if (drawValueAboveBar) valueOffsetPlus else -(valueTextWidth + valueOffsetPlus)) negOffset = ((if (drawValueAboveBar) -(valueTextWidth + valueOffsetPlus) else valueOffsetPlus) - (buffer.buffer[j + 2] - buffer.buffer[j])) @@ -302,7 +303,7 @@ open class HorizontalBarChartRenderer( ) // calculate the correct offset depending on the draw position of the value - val valueTextWidth = Utils.calcTextWidth(paintValues, formattedValue).toFloat() + val valueTextWidth = paintValues.calcTextWidth(formattedValue).toFloat() posOffset = (if (drawValueAboveBar) valueOffsetPlus else -(valueTextWidth + valueOffsetPlus)) negOffset = (if (drawValueAboveBar) -(valueTextWidth + valueOffsetPlus) else valueOffsetPlus) @@ -380,7 +381,7 @@ open class HorizontalBarChartRenderer( ) // calculate the correct offset depending on the draw position of the value - val valueTextWidth = Utils.calcTextWidth(paintValues, formattedValue).toFloat() + val valueTextWidth = paintValues.calcTextWidth(formattedValue).toFloat() posOffset = (if (drawValueAboveBar) valueOffsetPlus else -(valueTextWidth + valueOffsetPlus)) negOffset = (if (drawValueAboveBar) -(valueTextWidth + valueOffsetPlus) else valueOffsetPlus) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LegendRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LegendRenderer.kt index 555a1254d..f015af03c 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/LegendRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/LegendRenderer.kt @@ -17,10 +17,12 @@ import info.appdev.charting.interfaces.datasets.IBarDataSet import info.appdev.charting.interfaces.datasets.ICandleDataSet import info.appdev.charting.interfaces.datasets.IPieDataSet import info.appdev.charting.utils.ColorTemplate -import info.appdev.charting.utils.Utils import info.appdev.charting.utils.ViewPortHandler import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextWidth import info.appdev.charting.utils.convertDpToPixel +import info.appdev.charting.utils.getLineHeight +import info.appdev.charting.utils.getLineSpacing import java.util.Collections import kotlin.math.min @@ -207,8 +209,8 @@ open class LegendRenderer( labelPaint.textSize = legend.textSize labelPaint.color = legend.textColor - val labelLineHeight = Utils.getLineHeight(labelPaint, legendFontMetrics) - val labelLineSpacing = (Utils.getLineSpacing(labelPaint, legendFontMetrics) + val labelLineHeight = labelPaint.getLineHeight(legendFontMetrics) + val labelLineSpacing = (labelPaint.getLineSpacing(legendFontMetrics) + legend.yEntrySpace.convertDpToPixel()) val formYOffset = labelLineHeight - labelPaint.calcTextHeight("ABC") / 2f @@ -391,7 +393,7 @@ open class LegendRenderer( -formToTextSpace else if (wasStacked) posX = originPosX - if (direction == LegendDirection.RIGHT_TO_LEFT) posX -= Utils.calcTextWidth(labelPaint, entry.label).toFloat() + if (direction == LegendDirection.RIGHT_TO_LEFT) posX -= labelPaint.calcTextWidth(entry.label).toFloat() if (!wasStacked) { drawLabel(canvas, posX, posY + labelLineHeight, entry.label) diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRenderer.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRenderer.kt index de9b1785c..16db12229 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRenderer.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRenderer.kt @@ -19,6 +19,8 @@ import info.appdev.charting.utils.Transformer import info.appdev.charting.utils.Utils import info.appdev.charting.utils.ViewPortHandler import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextSize +import info.appdev.charting.utils.calcTextWidth import info.appdev.charting.utils.convertDpToPixel import info.appdev.charting.utils.drawXAxisValue import kotlin.math.roundToInt @@ -71,7 +73,7 @@ open class XAxisRenderer( paintAxisLabels.typeface = xAxis.typeface paintAxisLabels.textSize = xAxis.textSize - val labelSize = Utils.calcTextSize(paintAxisLabels, longest) + val labelSize = paintAxisLabels.calcTextSize(longest) val labelWidth = labelSize.width val labelHeight = paintAxisLabels.calcTextHeight("Q").toFloat() @@ -208,7 +210,7 @@ open class XAxisRenderer( // avoid clipping of the last if (i / 2 == xAxis.entryCount - 1 && xAxis.entryCount > 1) { - val width = Utils.calcTextWidth(paintAxisLabels, label).toFloat() + val width = paintAxisLabels.calcTextWidth(label).toFloat() if (width > viewPortHandler.offsetRight() * 2 && x + width > viewPortHandler.chartWidth @@ -216,7 +218,7 @@ open class XAxisRenderer( // avoid clipping of the first } else if (i == 0) { - val width = Utils.calcTextWidth(paintAxisLabels, label).toFloat() + val width = paintAxisLabels.calcTextWidth(label).toFloat() x += width / 2 } } diff --git a/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRendererHorizontalBarChart.kt b/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRendererHorizontalBarChart.kt index bc0e75e9a..e4884e42b 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRendererHorizontalBarChart.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/renderer/XAxisRendererHorizontalBarChart.kt @@ -16,6 +16,7 @@ import info.appdev.charting.utils.Transformer import info.appdev.charting.utils.Utils import info.appdev.charting.utils.ViewPortHandler import info.appdev.charting.utils.calcTextHeight +import info.appdev.charting.utils.calcTextSize import info.appdev.charting.utils.convertDpToPixel import kotlin.math.roundToInt @@ -58,7 +59,7 @@ open class XAxisRendererHorizontalBarChart( val longest = xAxis.longestLabel - val labelSize = Utils.calcTextSize(paintAxisLabels, longest) + val labelSize = paintAxisLabels.calcTextSize(longest) val labelWidth = (labelSize.width + xAxis.xOffset * 3.5f).toInt().toFloat() val labelHeight = labelSize.height diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/CanvasUtils.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/CanvasUtils.kt index a20452956..31194b383 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/CanvasUtils.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/CanvasUtils.kt @@ -113,6 +113,14 @@ fun Canvas.drawXAxisValue( paint.textAlign = originalTextAlign } +/** + * calculates the approximate width of a text, depending on a demo text + * avoid repeated calls (e.g. inside drawing methods) + */ +fun Paint.calcTextWidth(demoText: String?): Int { + return measureText(demoText).toInt() +} + /** * Returns a recyclable FSize instance. * Represents size of a rotated rectangle by degrees. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt index 4e4c860e2..10b639d29 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/Utils.kt @@ -2,7 +2,6 @@ package info.appdev.charting.utils import android.content.Context import android.graphics.Canvas -import android.graphics.Paint import android.graphics.Rect import android.graphics.drawable.Drawable import android.view.MotionEvent @@ -13,7 +12,6 @@ import info.appdev.charting.formatter.IValueFormatter import info.appdev.charting.utils.MPPointF.Companion.instance import kotlin.Int import kotlin.IntArray -import kotlin.String import kotlin.Suppress import kotlin.intArrayOf import kotlin.math.abs @@ -43,67 +41,6 @@ object Utils { maximumFlingVelocity = viewConfiguration.scaledMaximumFlingVelocity } - /** - * calculates the approximate width of a text, depending on a demo text - * avoid repeated calls (e.g. inside drawing methods) - */ - fun calcTextWidth(paint: Paint, demoText: String?): Int { - return paint.measureText(demoText).toInt() - } - - private val mFontMetrics = Paint.FontMetrics() - - fun getLineHeight(paint: Paint): Float { - return getLineHeight(paint, mFontMetrics) - } - - fun getLineHeight(paint: Paint, fontMetrics: Paint.FontMetrics): Float { - paint.getFontMetrics(fontMetrics) - return fontMetrics.descent - fontMetrics.ascent - } - - fun getLineSpacing(paint: Paint): Float { - return getLineSpacing(paint, mFontMetrics) - } - - fun getLineSpacing(paint: Paint, fontMetrics: Paint.FontMetrics): Float { - paint.getFontMetrics(fontMetrics) - return fontMetrics.ascent - fontMetrics.top + fontMetrics.bottom - } - - /** - * Returns a recyclable FSize instance. - * calculates the approximate size of a text, depending on a demo text - * avoid repeated calls (e.g. inside drawing methods) - * - * @param paint - * @param demoText - * @return A Recyclable FSize instance - */ - fun calcTextSize(paint: Paint, demoText: String): FSize { - val result = FSize.getInstance(0f, 0f) - calcTextSize(paint, demoText, result) - return result - } - - private val mCalcTextSizeRect = Rect() - - /** - * calculates the approximate size of a text, depending on a demo text - * avoid repeated calls (e.g. inside drawing methods) - * - * @param paint - * @param demoText - * @param outputFSize An output variable, modified by the function. - */ - fun calcTextSize(paint: Paint, demoText: String, outputFSize: FSize) { - val r = mCalcTextSizeRect - r.set(0, 0, 0, 0) - paint.getTextBounds(demoText, 0, demoText.length, r) - outputFSize.width = r.width().toFloat() - outputFSize.height = r.height().toFloat() - } - /** * Math.pow(...) is very expensive, so avoid calling it and create it * yourself. diff --git a/chartLib/src/main/kotlin/info/appdev/charting/utils/UtilsKt.kt b/chartLib/src/main/kotlin/info/appdev/charting/utils/UtilsKt.kt index 2045e17c7..b6760d4d2 100644 --- a/chartLib/src/main/kotlin/info/appdev/charting/utils/UtilsKt.kt +++ b/chartLib/src/main/kotlin/info/appdev/charting/utils/UtilsKt.kt @@ -47,7 +47,7 @@ fun Float.getDecimals(): Int { /** * rounds the given number to the next significant number */ -fun kotlin.Double.roundToNextSignificant(): Float { +fun Double.roundToNextSignificant(): Float { if (this.isInfinite() || this.isNaN() || this == 0.0 ) { @@ -65,7 +65,7 @@ fun kotlin.Double.roundToNextSignificant(): Float { * This method converts dp unit to equivalent pixels, depending on device * density. NEEDS UTILS TO BE INITIALIZED BEFORE USAGE. * - * @param dp A value in dp (density independent pixels) unit. Which we need + * dp A value in dp (density independent pixels) unit. Which we need * to convert into pixels * @return A float value to represent px equivalent to dp depending on * device density @@ -167,3 +167,52 @@ fun Paint.calcTextHeight(demoText: String): Int { this.getTextBounds(demoText, 0, demoText.length, r) return r.height() } + +private val mFontMetrics = Paint.FontMetrics() + +fun Paint.getLineHeight(): Float { + return this.getLineHeight(mFontMetrics) +} + +fun Paint.getLineHeight(fontMetrics: Paint.FontMetrics): Float { + this.getFontMetrics(fontMetrics) + return fontMetrics.descent - fontMetrics.ascent +} + +fun Paint.getLineSpacing(): Float { + return this.getLineSpacing(mFontMetrics) +} + +fun Paint.getLineSpacing(fontMetrics: Paint.FontMetrics): Float { + this.getFontMetrics(fontMetrics) + return fontMetrics.ascent - fontMetrics.top + fontMetrics.bottom +} + +/** + * Returns a recyclable FSize instance. + * calculates the approximate size of a text, depending on a demo text + * avoid repeated calls (e.g. inside drawing methods) + * + * @return A Recyclable FSize instance + */ +fun Paint.calcTextSize(demoText: String): FSize { + val result = FSize.getInstance(0f, 0f) + calcTextSize(demoText, result) + return result +} + +private val mCalcTextSizeRect = Rect() + +/** + * calculates the approximate size of a text, depending on a demo text + * avoid repeated calls (e.g. inside drawing methods) + * + * @param outputFSize An output variable, modified by the function. + */ +fun Paint.calcTextSize(demoText: String, outputFSize: FSize) { + val r = mCalcTextSizeRect + r.set(0, 0, 0, 0) + this.getTextBounds(demoText, 0, demoText.length, r) + outputFSize.width = r.width().toFloat() + outputFSize.height = r.height().toFloat() +}