patrykandpatrick / vico

A light and extensible chart library for Android.
https://patrykandpatrick.com/vico/wiki
Apache License 2.0
2.07k stars 125 forks source link

Bottom margin only for stacked columns #781

Closed ivanleong closed 2 months ago

ivanleong commented 2 months ago

How to reproduce

Set 2 series with mergeMode set to Stacked. Apply bottom margin to bottom line component only:

ColumnCartesianLayer.ColumnProvider.series(
        rememberLineComponent(
            color = color2,
            thickness = columnThickness,
            margins = Dimensions.of(0.dp, 8.dp)
        ),
        rememberLineComponent(
            color = color1,
            thickness = columnThickness
        ),
    )

Observed behavior

Screenshot_20240701-151333

Both series showing bottom margins

Expected behavior

Only bottom series to have bottom margin

Vico version(s)

2.0.0-alpha.21

Android version(s)

13

Additional information

No response

Gowsky commented 2 months ago

Hi @ivanleong, with Dimensions.of(0.dp, 8.dp) you're adding an 8 dp margin both at the top and at the bottom of the orange LineComponent. Simply use Dimensions.of(bottom = 8.dp).

ivanleong commented 2 months ago

@Gowsky Thanks, that fixed it! However when i use Dimensions.of(bottom = 10.dp). I've noticed that the bottom margins for different columns start to become uneven. What can cause this?

Screenshot_20240701-162848

Gowsky commented 2 months ago

There is a bug with how margins are handled. We'll look into it, but I don't think fixing it will get you what you expect.

That's how it would look after the fix. image

The problem is that the normal height of a column might be smaller than the margin. The columns can't be shifted as it would make them incorrect relative to the data.

Could you describe what you are trying to do?

ivanleong commented 2 months ago

@Gowsky I just need to shift all the columns (stacked) off the bottom axis by x amount. Similar to this graph. It works for a single stack but it gets uneven on multiple stacks Screenshot 2024-07-01 at 20 53 45

Gowsky commented 2 months ago

I just need to shift all the columns

You are actually shrinking the bottom one.

It works for a single stack

It doesn't work at all. The columns become shorter than they should be based on the data.

What you are looking to do relates to the y range. For example, in the picture, the minimum y value is effectively less than 0. You can't do this with margins as they are unrelated to the chart data.

You can adjust the y value range by using AxisValueOverrider. We also plan on adding an option to specify vertical padding to the content area in dp. This is related to #448.

ivanleong commented 2 months ago

@Gowsky Great thanks that seemed to work but unfortunately when i used AxisValueOverrider.fixed(minY = -10f) the padding always varies depending on the maxY value. I'll probably wait for your update on the vertical padding.

Gowsky commented 2 months ago

You can solve this by calculating the y range dynamically based on the length of the default. All the required information is passed to AxisValueOverrider functions. For example, this adds 10% of the length at the bottom, which is always the same amount of pixels.

override fun getMinY(minY: Float, maxY: Float, extraStore: ExtraStore) = minY - (maxY - minY) * .1f
Gowsky commented 2 months ago

Vico v2.0.0-alpha.22 fixes the bug with the margins. Cheers!