Giter VIP home page Giter VIP logo

Comments (6)

patrickmichalik avatar patrickmichalik commented on July 3, 2024

Hello! DefaultMarkerLabelFormatter color-codes Marker labels. You can set colorCode to false to turn this off.

To customize the number format such that there are no trailing zeros, please use a custom MarkerLabelFormatter implementation. (We’ll be looking into updating DefaultMarkerLabelFormatter to accept a pattern string and improving the default behavior.) You can also use MarkerLabelFormatter to add extra text to your Marker—any string can be returned. Regarding font customization, TextComponent has a typeface field. A Marker can have any position—while a MarkerComponent appears at the top of its chart, you can create a custom Marker implementation with different positioning logic. (We’ll be looking into making MarkerComponent configurable position-wise.) Finally, Marker visibility changes can be detected via MarkerVisibilityChangeListener, and the ability to highlight individual columns in column charts is a planned addition.

Since the behavior described isn’t a bug and can be changed, I’ll be closing this issue, but feel free to comment if you have any questions.

from vico.

ozanKalan1 avatar ozanKalan1 commented on July 3, 2024

Thanks for the response, will give those suggestions a shot

from vico.

ozanKalan1 avatar ozanKalan1 commented on July 3, 2024

@patrickmichalik If you could, Could you help point me in the right direction for the marker height in the marker class?
I made my own, which I now have color authority, font, and string formatting completed. Just a bit unsure how to override the hight so that it's on top of the columns like the labels are.

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

Sure, @ozanKalan1. Could you share your Marker code? I’ll then be able to give you precise instructions.

from vico.

ozanKalan1 avatar ozanKalan1 commented on July 3, 2024

Here you go @patrickmichalik

import android.text.Spannable
import android.text.style.ForegroundColorSpan
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.content.res.ResourcesCompat
import com.autonomy.autonomyconsumer.R
import com.autonomy.autonomyconsumer.data.extensions.formatToMileage
import com.autonomy.autonomyconsumer.ui.theme.AutonomyBlack
import com.autonomy.autonomyconsumer.ui.theme.White
import com.patrykandpatrick.vico.compose.dimensions.dimensionsOf
import com.patrykandpatrick.vico.core.chart.dimensions.HorizontalDimensions
import com.patrykandpatrick.vico.core.chart.insets.Insets
import com.patrykandpatrick.vico.core.chart.values.ChartValues
import com.patrykandpatrick.vico.core.component.marker.MarkerComponent
import com.patrykandpatrick.vico.core.component.shape.DashedShape
import com.patrykandpatrick.vico.core.component.shape.ShapeComponent
import com.patrykandpatrick.vico.core.component.shape.Shapes
import com.patrykandpatrick.vico.core.component.shape.cornered.Corner
import com.patrykandpatrick.vico.core.component.shape.cornered.MarkerCorneredShape
import com.patrykandpatrick.vico.core.component.text.TextComponent
import com.patrykandpatrick.vico.core.context.MeasureContext
import com.patrykandpatrick.vico.core.extension.appendCompat
import com.patrykandpatrick.vico.core.extension.sumOf
import com.patrykandpatrick.vico.core.extension.transformToSpannable
import com.patrykandpatrick.vico.core.marker.Marker
import com.patrykandpatrick.vico.core.marker.MarkerLabelFormatter
import com.patrykandpatrick.vico.core.model.CartesianLayerModel
import com.patrykandpatrick.vico.core.model.ColumnCartesianLayerModel
import com.patrykandpatrick.vico.core.model.LineCartesianLayerModel

public class AutonomyMarkerLabelFormatter(private val colorCode: Color? = White) :
MarkerLabelFormatter {
override fun getLabel(
markedEntries: List<Marker.EntryModel>,
chartValues: ChartValues,
): CharSequence =
markedEntries.transformToSpannable(
prefix = if (markedEntries.size > 1) PATTERN.format(markedEntries.sumOf { it.entry.y }) + " (" else "",
postfix = if (markedEntries.size > 1) ")" else "",
separator = "; ",
) { model ->
if (colorCode != null) {
appendCompat(
"${model.entry.y.toInt().formatToMileage()} Mi.",
ForegroundColorSpan(colorCode.hashCode()),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE,
)
} else {
append("${model.entry.y.toInt().formatToMileage()} Mi.")
}
}

private val CartesianLayerModel.Entry.y
    get() =
        when (this) {
            is ColumnCartesianLayerModel.Entry -> y
            is LineCartesianLayerModel.Entry -> y
            else -> throw IllegalArgumentException("Unexpected `CartesianLayerModel.Entry` implementation.")
        }

private companion object {
    const val PATTERN = "%.02f"
}

}

@composable
internal fun rememberMarker(): Marker {
val labelBackgroundColor = AutonomyBlack
val labelBackground =
remember(labelBackgroundColor) {
ShapeComponent(labelBackgroundShape).setShadow(
radius = LABEL_BACKGROUND_SHADOW_RADIUS,
dy = LABEL_BACKGROUND_SHADOW_DY,
applyElevationOverlay = true,
)
}
val context = LocalContext.current
val label =
TextComponent.Builder().apply {
background = labelBackground
lineCount = LABEL_LINE_COUNT
padding = labelPadding
typeface = ResourcesCompat.getFont(context, R.font.dmsansbold)//Typeface.createFromFile(ResourcesCompat.getFont(context, R.font.dmsansbold).toString())
textSizeSp = 13f
color = Color.White.toArgb()
}.build()

val indicator = null
val guideline = null

return remember(label, indicator, guideline) {
    object : MarkerComponent(label, indicator, guideline) {
        init {
            labelFormatter = AutonomyMarkerLabelFormatter()
        }

        override fun getInsets(
            context: MeasureContext,
            outInsets: Insets,
            horizontalDimensions: HorizontalDimensions,
        ) = with(context) {
            outInsets.bottom = label.getHeight(context) + labelBackgroundShape.tickSizeDp.pixels +
                LABEL_BACKGROUND_SHADOW_RADIUS.pixels * SHADOW_RADIUS_MULTIPLIER -
                LABEL_BACKGROUND_SHADOW_DY.pixels
        }
    }
}

}

private const val LABEL_BACKGROUND_SHADOW_RADIUS = 4f
private const val LABEL_BACKGROUND_SHADOW_DY = 2f
private const val LABEL_LINE_COUNT = 1
private const val GUIDELINE_ALPHA = .2f
private const val INDICATOR_SIZE_DP = 36f
private const val INDICATOR_OUTER_COMPONENT_ALPHA = 32
private const val INDICATOR_CENTER_COMPONENT_SHADOW_RADIUS = 12f
private const val GUIDELINE_DASH_LENGTH_DP = 8f
private const val GUIDELINE_GAP_LENGTH_DP = 4f
private const val SHADOW_RADIUS_MULTIPLIER = 1.3f

private val labelBackgroundShape = MarkerCorneredShape(Corner.FullyRounded)
private val labelHorizontalPaddingValue = 8.dp
private val labelVerticalPaddingValue = 4.dp
private val labelPadding = dimensionsOf(labelHorizontalPaddingValue, labelVerticalPaddingValue)
private val indicatorInnerAndCenterComponentPaddingValue = 5.dp
private val indicatorCenterAndOuterComponentPaddingValue = 10.dp
private val guidelineThickness = 2.dp
private val guidelineShape = DashedShape(Shapes.pillShape, GUIDELINE_DASH_LENGTH_DP, GUIDELINE_GAP_LENGTH_DP)

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

Thanks, @ozanKalan1! A custom Marker implementation, not a MarkerComponent instance, will be needed. I’d suggest copying over the MarkerComponent definition and making the necessary tweaks. Pull request #540 adds the feature in question, so you can use it as a reference. Once #540 has been merged and an update has been released, you’ll no longer need a custom Marker implementation to achieve the desired result—you’ll just have to pass an extra argument to the MarkerComponent constructor.

By the way, in Compose, TextComponent instances are best created via rememberTextComponent. In rememberMarker, for label, you appear to be using TextComponent.Builder, which is generally intended for the view system. With rememberTextComponent, your TextComponent won’t be unnecessarily recreated.

from vico.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.