diff --git a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/axis/AxisComponents.kt b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/axis/AxisComponents.kt
index 67ae84459..0f32541ac 100644
--- a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/axis/AxisComponents.kt
+++ b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/axis/AxisComponents.kt
@@ -18,6 +18,7 @@ package com.patrykandpatrick.vico.compose.axis
import android.graphics.Paint
import android.graphics.Typeface
+import android.text.Layout
import android.text.TextUtils
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Brush
@@ -43,19 +44,19 @@ import com.patrykandpatrick.vico.core.dimensions.emptyDimensions
public typealias ChartShape = com.patrykandpatrick.vico.core.component.shape.Shape
/**
- * Creates a label to be displayed on chart axes.
+ * Creates a [TextComponent] to be used for axis labels.
*
* @param color the text color.
* @param textSize the text size.
* @param background a [ShapeComponent] to be displayed behind the text.
* @param ellipsize the text truncation behavior.
* @param lineCount the line count.
- * @param verticalPadding the vertical padding between the text and the background.
- * @param horizontalPadding the horizontal padding between the text and the background.
- * @param verticalMargin the vertical margin around the background.
- * @param horizontalMargin the horizontal margin around the background.
+ * @param verticalPadding the amount of top and bottom padding between the text and the background.
+ * @param horizontalPadding the amount of start and end padding between the text and the background.
+ * @param verticalMargin the size of the top and bottom margins around the background.
+ * @param horizontalMargin the size of the start and end margins around the background.
* @param typeface the typeface used for the label.
- * @param textAlign the text alignment.
+ * @param textAlignment the text alignment.
*/
@Composable
public fun axisLabelComponent(
@@ -69,25 +70,64 @@ public fun axisLabelComponent(
verticalMargin: Dp = currentChartStyle.axis.axisLabelVerticalMargin,
horizontalMargin: Dp = currentChartStyle.axis.axisLabelHorizontalMargin,
typeface: Typeface = currentChartStyle.axis.axisLabelTypeface,
- textAlign: Paint.Align = currentChartStyle.axis.axisLabelTextAlign,
+ textAlignment: Layout.Alignment = currentChartStyle.axis.axisLabelTextAlignment,
): TextComponent = textComponent(
- color = color,
- textSize = textSize,
- background = background,
- ellipsize = ellipsize,
- lineCount = lineCount,
- padding = dimensionsOf(
- vertical = verticalPadding,
- horizontal = horizontalPadding,
- ),
- margins = dimensionsOf(
- vertical = verticalMargin,
- horizontal = horizontalMargin,
- ),
- typeface = typeface,
- textAlign = textAlign,
+ color,
+ textSize,
+ background,
+ ellipsize,
+ lineCount,
+ dimensionsOf(verticalPadding, horizontalPadding),
+ dimensionsOf(verticalMargin, horizontalMargin),
+ typeface,
+ textAlignment,
)
+/**
+ * Creates a [TextComponent] to be used for axis labels.
+ *
+ * @param color the text color.
+ * @param textSize the text size.
+ * @param background a [ShapeComponent] to be displayed behind the text.
+ * @param ellipsize the text truncation behavior.
+ * @param lineCount the line count.
+ * @param verticalPadding the amount of top and bottom padding between the text and the background.
+ * @param horizontalPadding the amount of start and end padding between the text and the background.
+ * @param verticalMargin the size of the top and bottom margins around the background.
+ * @param horizontalMargin the size of the start and end margins around the background.
+ * @param verticalMargin the size of the vertical margins around the background.
+ * @param horizontalMargin the size of the horizontal margins around the background.
+ * @param typeface the typeface used for the label.
+ * @param textAlign the text alignment.
+ */
+@Composable
+@Deprecated("Instead of `textAlign`, use `textAlignment`.")
+public fun axisLabelComponent(
+ color: Color = currentChartStyle.axis.axisLabelColor,
+ textSize: TextUnit = currentChartStyle.axis.axisLabelTextSize,
+ background: ShapeComponent? = currentChartStyle.axis.axisLabelBackground,
+ ellipsize: TextUtils.TruncateAt = TextUtils.TruncateAt.END,
+ lineCount: Int = currentChartStyle.axis.axisLabelLineCount,
+ verticalPadding: Dp = currentChartStyle.axis.axisLabelVerticalPadding,
+ horizontalPadding: Dp = currentChartStyle.axis.axisLabelHorizontalPadding,
+ verticalMargin: Dp = currentChartStyle.axis.axisLabelVerticalMargin,
+ horizontalMargin: Dp = currentChartStyle.axis.axisLabelHorizontalMargin,
+ typeface: Typeface = currentChartStyle.axis.axisLabelTypeface,
+ textAlign: Paint.Align,
+): TextComponent =
+ @Suppress("DEPRECATION")
+ textComponent(
+ color,
+ textSize,
+ background,
+ ellipsize,
+ lineCount,
+ dimensionsOf(verticalPadding, horizontalPadding),
+ dimensionsOf(verticalMargin, horizontalMargin),
+ typeface,
+ textAlign,
+ )
+
/**
* Creates a [LineComponent] styled as an axis line.
*
diff --git a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/component/Components.kt b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/component/Components.kt
index 66875679c..51dea44a1 100644
--- a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/component/Components.kt
+++ b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/component/Components.kt
@@ -18,6 +18,7 @@ package com.patrykandpatrick.vico.compose.component
import android.graphics.Paint
import android.graphics.Typeface
+import android.text.Layout
import android.text.TextUtils
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@@ -229,6 +230,45 @@ public fun overlayingComponent(
innerPaddingEnd = innerPaddingAll,
)
+/**
+ * Creates a [TextComponent].
+ *
+ * @param color the text color.
+ * @param textSize the text size.
+ * @param background an optional [ShapeComponent] to display behind the text.
+ * @param ellipsize the text truncation behavior.
+ * @param lineCount the line count.
+ * @param padding the padding between the text and the background.
+ * @param margins the margins around the background.
+ * @param typeface the [Typeface] for the text.
+ * @param textAlignment the text alignment.
+ */
+@Composable
+public fun textComponent(
+ color: Color = Color.Black,
+ textSize: TextUnit = DefaultDimens.TEXT_COMPONENT_TEXT_SIZE.sp,
+ background: ShapeComponent? = null,
+ ellipsize: TextUtils.TruncateAt = TextUtils.TruncateAt.END,
+ lineCount: Int = DEF_LABEL_LINE_COUNT,
+ padding: MutableDimensions = emptyDimensions(),
+ margins: MutableDimensions = emptyDimensions(),
+ typeface: Typeface? = null,
+ textAlignment: Layout.Alignment = Layout.Alignment.ALIGN_NORMAL,
+): TextComponent =
+ remember(color, textSize, background, ellipsize, lineCount, padding, margins, typeface, textAlignment) {
+ textComponent {
+ this.color = color.toArgb()
+ textSizeSp = textSize.pixelSize()
+ this.ellipsize = ellipsize
+ this.lineCount = lineCount
+ this.background = background
+ this.padding = padding
+ this.margins = margins
+ this.typeface = typeface
+ this.textAlignment = textAlignment
+ }
+ }
+
/**
* Creates a [TextComponent].
*
@@ -243,6 +283,7 @@ public fun overlayingComponent(
* @param textAlign the text alignment.
*/
@Composable
+@Deprecated("Instead of `textAlign`, use `textAlignment`.")
public fun textComponent(
color: Color = Color.Black,
textSize: TextUnit = DefaultDimens.TEXT_COMPONENT_TEXT_SIZE.sp,
@@ -252,18 +293,8 @@ public fun textComponent(
padding: MutableDimensions = emptyDimensions(),
margins: MutableDimensions = emptyDimensions(),
typeface: Typeface? = null,
- textAlign: Paint.Align = Paint.Align.LEFT,
-): TextComponent = remember(
- color,
- textSize,
- background,
- ellipsize,
- lineCount,
- padding,
- margins,
- typeface,
- textAlign,
-) {
+ textAlign: Paint.Align,
+): TextComponent = remember(color, textSize, background, ellipsize, lineCount, padding, margins, typeface, textAlign) {
textComponent {
this.color = color.toArgb()
textSizeSp = textSize.pixelSize()
@@ -273,6 +304,7 @@ public fun textComponent(
this.padding = padding
this.margins = margins
this.typeface = typeface
+ @Suppress("DEPRECATION")
this.textAlign = textAlign
}
}
diff --git a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/style/ChartStyle.kt b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/style/ChartStyle.kt
index 87888cdae..704fbcfbe 100644
--- a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/style/ChartStyle.kt
+++ b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/style/ChartStyle.kt
@@ -18,6 +18,7 @@ package com.patrykandpatrick.vico.compose.style
import android.graphics.Paint
import android.graphics.Typeface
+import android.text.Layout
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
@@ -83,6 +84,7 @@ public data class ChartStyle(
* @property axisLabelRotationDegrees the number of degrees by which axis labels are rotated.
* @property axisLabelTypeface the typeface used for axis labels.
* @property axisLabelTextAlign the text alignment for axis labels.
+ * @property axisLabelTextAlignment the text alignment for axis labels.
* @property axisGuidelineColor the color of axis guidelines.
* @property axisGuidelineWidth the width of axis guidelines.
* @property axisGuidelineShape the [Shape] used for axis guidelines.
@@ -106,7 +108,9 @@ public data class ChartStyle(
val axisLabelHorizontalMargin: Dp = DefaultDimens.AXIS_LABEL_HORIZONTAL_MARGIN.dp,
val axisLabelRotationDegrees: Float = DefaultDimens.AXIS_LABEL_ROTATION_DEGREES,
val axisLabelTypeface: Typeface = Typeface.MONOSPACE,
+ @Deprecated("Use `axisLabelTextAlignment` instead.")
val axisLabelTextAlign: Paint.Align = Paint.Align.LEFT,
+ val axisLabelTextAlignment: Layout.Alignment = Layout.Alignment.ALIGN_NORMAL,
val axisGuidelineColor: Color,
val axisGuidelineWidth: Dp = DefaultDimens.AXIS_GUIDELINE_WIDTH.dp,
val axisGuidelineShape: Shape = Shapes.dashedShape(
diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/component/text/TextComponent.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/component/text/TextComponent.kt
index 8f6ede345..a6d26996f 100644
--- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/component/text/TextComponent.kt
+++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/component/text/TextComponent.kt
@@ -108,7 +108,15 @@ public open class TextComponent protected constructor() : Padding, Margins {
/**
* The text alignment.
*/
- public var textAlign: Paint.Align by textPaint::textAlign
+ @Deprecated("Use `textAlignment` instead.")
+ public var textAlign: Paint.Align
+ get() = textAlignment.equivLtrPaintAlign
+ set(value) { textAlignment = value.equivLtrLayoutAlignment }
+
+ /**
+ * The text alignment.
+ */
+ public var textAlignment: Layout.Alignment = Layout.Alignment.ALIGN_NORMAL
/**
* The padding between the text and the background. This is applied even if [background] is null.
@@ -167,7 +175,7 @@ public open class TextComponent protected constructor() : Padding, Margins {
save()
val bounds = layout.getBounds(tempMeasureBounds)
- val textAlignCorrection = textAlign.getXCorrection(width = bounds.width())
+ val textAlignmentCorrection = getTextAlignmentCorrection(bounds.width())
with(receiver = bounds) {
left -= padding.getLeftDp(isLtr).pixels
@@ -215,7 +223,7 @@ public open class TextComponent protected constructor() : Padding, Margins {
)
translate(
- bounds.left + padding.getLeftDp(isLtr).pixels + textAlignCorrection,
+ bounds.left + padding.getLeftDp(isLtr).pixels + textAlignmentCorrection,
bounds.top + padding.topDp.pixels,
)
@@ -247,10 +255,21 @@ public open class TextComponent protected constructor() : Padding, Margins {
width: Float,
): Float = baseXPosition - padding.getRightDp(isLtr).pixels - margins.getRightDp(isLtr).pixels - width
- private fun Paint.Align.getXCorrection(width: Float): Float = when (this) {
- Paint.Align.LEFT -> 0f
- Paint.Align.CENTER -> width.half
- Paint.Align.RIGHT -> width
+ private fun getTextAlignmentCorrection(width: Float): Float {
+ val ltrAlignment = if (layout.getParagraphDirection(0) == Layout.DIR_LEFT_TO_RIGHT) {
+ textAlignment
+ } else {
+ when (textAlignment) {
+ Layout.Alignment.ALIGN_NORMAL -> Layout.Alignment.ALIGN_OPPOSITE
+ Layout.Alignment.ALIGN_OPPOSITE -> Layout.Alignment.ALIGN_NORMAL
+ Layout.Alignment.ALIGN_CENTER -> Layout.Alignment.ALIGN_CENTER
+ }
+ }
+ return when (ltrAlignment) {
+ Layout.Alignment.ALIGN_NORMAL -> 0f
+ Layout.Alignment.ALIGN_OPPOSITE -> width - layout.width
+ Layout.Alignment.ALIGN_CENTER -> (width - layout.width).half
+ }
}
@JvmName("getTextTopPositionExt")
@@ -366,6 +385,7 @@ public open class TextComponent protected constructor() : Padding, Margins {
width = correctedWidth,
maxLines = lineCount,
ellipsize = ellipsize,
+ align = textAlignment,
)
}
}
@@ -409,7 +429,15 @@ public open class TextComponent protected constructor() : Padding, Margins {
/**
* @see [TextComponent.textAlign]
*/
- public var textAlign: Paint.Align = Paint.Align.LEFT
+ @Deprecated("Use `textAlignment` instead.")
+ public var textAlign: Paint.Align
+ get() = textAlignment.equivLtrPaintAlign
+ set(value) { textAlignment = value.equivLtrLayoutAlignment }
+
+ /**
+ * The text alignment.
+ */
+ public var textAlignment: Layout.Alignment = Layout.Alignment.ALIGN_NORMAL
/**
* @see [TextComponent.padding]
@@ -431,7 +459,7 @@ public open class TextComponent protected constructor() : Padding, Margins {
ellipsize = this@Builder.ellipsize
lineCount = this@Builder.lineCount
background = this@Builder.background
- textAlign = this@Builder.textAlign
+ textAlignment = this@Builder.textAlignment
padding.set(this@Builder.padding)
margins.set(this@Builder.margins)
}
@@ -452,3 +480,17 @@ public open class TextComponent protected constructor() : Padding, Margins {
*/
public inline fun textComponent(block: TextComponent.Builder.() -> Unit = {}): TextComponent =
TextComponent.Builder().apply(block).build()
+
+private val Paint.Align.equivLtrLayoutAlignment
+ get() = when (this) {
+ Paint.Align.LEFT -> Layout.Alignment.ALIGN_NORMAL
+ Paint.Align.CENTER -> Layout.Alignment.ALIGN_CENTER
+ Paint.Align.RIGHT -> Layout.Alignment.ALIGN_OPPOSITE
+ }
+
+private val Layout.Alignment.equivLtrPaintAlign
+ get() = when (this) {
+ Layout.Alignment.ALIGN_NORMAL -> Paint.Align.LEFT
+ Layout.Alignment.ALIGN_OPPOSITE -> Paint.Align.RIGHT
+ Layout.Alignment.ALIGN_CENTER -> Paint.Align.CENTER
+ }
diff --git a/vico/views/src/main/java/com/patrykandpatrick/vico/views/theme/TextComponentStyleExtensions.kt b/vico/views/src/main/java/com/patrykandpatrick/vico/views/theme/TextComponentStyleExtensions.kt
index b1b72a5d0..201c3b64f 100644
--- a/vico/views/src/main/java/com/patrykandpatrick/vico/views/theme/TextComponentStyleExtensions.kt
+++ b/vico/views/src/main/java/com/patrykandpatrick/vico/views/theme/TextComponentStyleExtensions.kt
@@ -21,6 +21,7 @@ import android.content.res.TypedArray
import android.graphics.Paint
import android.graphics.Typeface
import android.os.Build
+import android.text.Layout
import android.text.TextUtils
import androidx.annotation.StyleableRes
import androidx.core.content.res.ResourcesCompat
@@ -61,7 +62,9 @@ internal fun TypedArray.getTextComponent(
this.lineCount = getInteger(R.styleable.TextComponentStyle_android_maxLines, DEF_LABEL_LINE_COUNT)
this.ellipsize = getTruncateAt()
getTypeface(context)?.let { this.typeface = it }
- this.textAlign = getTextAlign()
+ @Suppress("DEPRECATION")
+ getTextAlign()?.let { this.textAlign = it }
+ this.textAlignment = getTextAlignment()
}
}
@@ -150,11 +153,11 @@ private fun TypedArray.getMargins(context: Context): MutableDimensions {
)
}
-private fun TypedArray.getTextAlign(): Paint.Align {
- val values = Paint.Align.values()
- val index = getInt(
- R.styleable.TextComponentStyle_textAlign,
- Paint.Align.LEFT.ordinal,
- ).coerceAtMost(maximumValue = Paint.Align.RIGHT.ordinal)
- return values[index]
-}
+private fun TypedArray.getTextAlign(): Paint.Align? =
+ Paint.Align.values().getOrNull(getInt(R.styleable.TextComponentStyle_textAlign, -1))
+
+private fun TypedArray.getTextAlignment(): Layout.Alignment =
+ Layout.Alignment
+ .values()
+ .getOrNull(getInt(R.styleable.TextComponentStyle_textAlignment, Layout.Alignment.ALIGN_NORMAL.ordinal))
+ ?: Layout.Alignment.ALIGN_NORMAL
diff --git a/vico/views/src/main/res/values/attrs.xml b/vico/views/src/main/res/values/attrs.xml
index 9225167c3..95de33fad 100644
--- a/vico/views/src/main/res/values/attrs.xml
+++ b/vico/views/src/main/res/values/attrs.xml
@@ -139,11 +139,17 @@
+
+
+
+
+
+