Giter VIP home page Giter VIP logo

Comments (11)

patrickmichalik avatar patrickmichalik commented on July 3, 2024 1

Thanks for sharing, @matpascaud! It looks like I forgot to add an explicit cast in my previous comment. I’ve updated the code snippet. Apologies for the error.

Seeing that only the first nonzero ColumnCartesianLayerModel.Entry is used here, I’d suggest using first or firstOrNull, not filter. firstOrNull will be needed if it’s possible for all columns in a stack to have y values of zero, a case handled by the MarkerLabelFormatter you’ve shared. With first or firstOrNull, the logic will be simpler and more direct. This change will also improve performance and reduce memory use, though only marginally, as markedEntries is a short list.

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024 1

This should do the trick, @matpascaud:

CartesianMarkerValueFormatter { _, targets ->
    val target = targets.first() as ColumnCartesianLayerMarkerTarget
    target.columns.first { column -> column.entry.y != 0f }.entry.y.roundToInt().toString()
}

That said, switching to ColumnProvider, which I touched on above, would be optimal. You’ll then no longer need a custom CartesianMarkerValueFormatter. If you have any questions or need an example, let me know.

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

Hello! It seems like one of the bugs that we’ve recently fixed made your MarkerLabelFormatter work when, in fact, it shouldn’t have worked. first appears to be the culprit here. Could you try switching to the following?

first { (it.entry as ColumnCartesianLayerModel.Entry).y != 0f }

By the way, Vico 2.0.0 Alpha 13 introduces column-by-column customization for ColumnCartesianLayer. The solution you’re using to give your columns different colors will, of course, continue to work, but I’d suggest switching to ColumnCartesianLayer.ColumnProvider.

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

from vico.

matpascaud avatar matpascaud commented on July 3, 2024

For those who might be interested in how I implement the labelFormatter, here it is:

markerComponent.labelFormatter = MarkerLabelFormatter { markedEntries, chartValues ->
            val entries = markedEntries.filter {
                (it.entry as ColumnCartesianLayerModel.Entry).y > 0

            }
            if(entries.isEmpty())
                ""
            else {
                String.format("%.0f", (entries.first().entry as ColumnCartesianLayerModel.Entry).y)
            }

        }

from vico.

matpascaud avatar matpascaud commented on July 3, 2024

Thanks @patrickmichalik.
I upgraded to Alpha 16 and I must confess I do not know how to convert from the code above to the new API.
I need to display the value of the current colum and not all 3columns (3 colors).
There is no more access to Y value like in MarkerLabelFormatter ?

from vico.

matpascaud avatar matpascaud commented on July 3, 2024

Wow, that's quick! Many thanks.
I still need to modify because it's crashing probably when there is not colum but at least, I have an example.
I probably need switching to columnProvider. I have done part of it but probably not enough

with (chartView) {
            chart = CartesianChart(
                ColumnCartesianLayer(
                    columnProvider =
                    series(
                        columnColors.map { color ->
                            LineComponent(
                                color = color,
                                thicknessDp = 13f,
                                shape = Shape.Rectangle,
                            )
                        },
                    ),
                    spacingDp = 7f,
                    innerSpacingDp = 2f,
                    mergeMode =  { ColumnCartesianLayer.MergeMode.Stacked},
                    verticalAxisPosition = null,
                    dataLabel = null,
                    dataLabelVerticalPosition = VerticalPosition.Top,
//                    dataLabelValueFormatter = DecimalFormatValueFormatter(),
                    dataLabelRotationDegrees = 0f,
                    drawingModelInterpolator = DefaultDrawingModelInterpolator()
                )

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

You’re welcome, @matpascaud! I posted a reply a while ago, but I later noticed that it required clarification, so I deleted it. This is a more comprehensive revision.

It sounds like your chart has all-zero stacks, which I previously wasn’t sure about. first, used above, will throw an exception for such stacks. As discussed, you can utilize firstOrNull to ensure that all-zero stacks are properly handled. The following should behave as expected and not produce any crashes. Sorry for the confusion.

CartesianMarkerValueFormatter { _, targets ->
    val target = targets.first() as ColumnCartesianLayerMarkerTarget
    val column = target.columns.firstOrNull { column -> column.entry.y != 0f }
    column?.entry?.y?.roundToInt()?.toString().orEmpty()
}

Regarding the migration to ColumnCartesianLayer.ColumnProvider,ColumnCartesianLayer.ColumnProvider.series should be avoided here. The migration should, instead, involve the following:

  • switching from multiple series to one
  • creating a custom ColumnCartesianLayer.ColumnProvider implementation that styles individual columns based on their y values

The resulting logic will be simpler and more flexible. A custom CartesianMarkerValueFormatter will stop being required because there won’t be any extra columns with y values of zero to be ignored during formatting. As such, these columns can be removed even without the migration to ColumnCartesianLayer.ColumnProvider, but the migration necessitates and simplifies doing so.

If you’re able to share the entirety of your Vico code, I’ll be happy to describe how to migrate. Otherwise, I can prepare an example based on the screenshot you’ve shared and everything else we’ve discussed.

from vico.

matpascaud avatar matpascaud commented on July 3, 2024

@patrickmichalik You really saved me hours of work trying to make the code doing what I expected. So big thanks again.
As soon as this part is fine, I think I will migrate to ColumnCartesianLayer.ColumnProvider to make the code more concise and clear.
I still have something a bit weird with this code: persistent marker appear at the top of the column only for the first color.

val markerFormatter = CartesianMarkerValueFormatter { _, targets ->
            (targets.first() as ColumnCartesianLayerMarkerTarget)
                .columns
                .firstOrNull { column -> column.entry.y != 0f }
                ?.let { column -> column.entry.y.roundToInt().toString() }
                .orEmpty()
        }

        val markerComponent = DefaultCartesianMarker(label = markerTxtComponent, labelPosition = DefaultCartesianMarker.LabelPosition.AbovePoint, valueFormatter = markerFormatter)

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

Happy to help, @matpascaud. I took a look, and this turned out to be a bug on our end. I’ve resolved it and released a hotfix, Vico 2.0.0 Alpha 17. Could you try updating?

from vico.

matpascaud avatar matpascaud commented on July 3, 2024

@patrickmichalik Thanks again, updating to 2.0.0 Alpha 17 solves the bug.

from vico.

patrickmichalik avatar patrickmichalik commented on July 3, 2024

I’m glad to hear that, @matpascaud. My pleasure!

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.