Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bar Charts #6

Open
laurentiuonac opened this issue May 9, 2023 Discussed in #1 · 0 comments
Open

Bar Charts #6

laurentiuonac opened this issue May 9, 2023 Discussed in #1 · 0 comments

Comments

@laurentiuonac
Copy link
Member

Discussed in #1

Originally posted by hdralexandru April 6, 2023

📢 Place of discussion for the Bar's Chart API.

See the current proposal beneath. React with 👍🏻 if you like it or with 👎🏻 if you don't.
If you 👎🏻 the API, please specify why and suggest an alternative.

The API

We are suggesting the following approach

BarChart

See A Complete Guide to Bar Charts for more info about bar charts.

@Composable
fun BarChart(
    modifier: Modifier = Modifier,
    data: List<Bar>,
    yAxisInterval: AxisInterval,
    verticalLabel: List<ValueLabel>,
    labelStyle: TextStyle,
    axisStyle: AxisStyle,
    background: List<BackgroundStyle> = listOf(),
    barColor: List<Color>,
)

modifier: Modifier

The Modifier object from compose, used for customizing the behaviour of this composable.

data: List <Bar>

Bar is a data class that gives us the information to show.

data class Bar(
    val key: DataLabel,
    val value: Float,
)

DataLabel is a value class, used for displaying the labels. For vertical bar charts, they are the labels displayed on the X axis

@JvmInline
value class DataLabel(val label: String)

yAxisInterval: AxisInterval

data class AxisInterval(
    val max: Float,
    val min: Float = 0f,
)

The AxisInterval class gives us the min and max values of the ax. We use it in order to compute where a point should be in our chart.

We use the following formula:
Let:

  • cy be the maximum space we have for drawing on the Y axis (vertically)
  • curr be the current value we have to draw on the screen
  • max = AxisInterval.max
  • min = AxisInterval.min
    We assume that min <= curr <= max.
    Having those conditions set, the point P where the curr value is represented on the screen will be deducted using the following formula:
$$P = (curr * cy) / (max - min)$$

verticalLabels: List<ValueLable>

Same as DataLabel, ValueLabel is a value class that defines the label that will be displayed on the Y axis (in this case)

labelStyle: TextStyle

The TextStyle we'll be using for drawing the labels

axisStyle: AxisStyle

The style used for drawing the axis.

data class AxisStyle(
    val width: Dp,
    val brush: Brush,
)

backgroundStyles: List<BackgroundStyle>

Across the many examples we've seen of BarCharts, there were different kind of background: gradients, horizontal lines or grid.
The user will decide what style to apply, by passing a list of BackgroundStyle

sealed interface BackgroundStyle {
    // TODO those will be classes, not objects. Objects are only for demo purposes
    object HorizontalGrid : BackgroundStyle
    object VerticalGrid : BackgroundStyle

    // FIXME think more about the naming
    data class Brush(val brush: androidx.compose.ui.graphics.Brush)
}

barColor: List<Color>

The user will provide a list of colors, used for drawing the bars.
The list should have the same size as data. We'll be using the index to determine the color

StackedBarChart

See A Complete Guide to Stacked Bar Charts for more info about stacked bar charts.

fun StackedBarChart(
    modifier: Modifier = Modifier,
    data: List<BarEntrySet>,
    yAxisInterval: AxisInterval,
    verticalLabels: List<ValueLabel>,
    labelStyle: TextStyle,
    axisStyle: AxisStyle? = null,
    background: List<BackgroundStyle> = listOf(),
    barColor: Map<DataLabel, Color>,
)

The api is mostly the same, with a few exceptions.

data: List<BarEntrySet>

data class BarEntrySet(
    val dataLabel: DataLabel,
    val bars: List<Bar>
)

Just like a key-value, we use dataLabel to determine what set of data is being represented.

barColor: Map<DataLabel, Color>

We use the DataLabel from the BarEntrySet to determine what color to use for a bar.
The number of keys in this map should be equal to the number of entries in BarEntrySet.bars

GroupedBarChart

@Composable
fun GroupedBarChart(
    modifier: Modifier = Modifier,
    data: List<BarEntrySet>,
    axisInterval: AxisInterval,
    verticalLabels: List<ValueLabel>,
    labelStyle: TextStyle,
    axisStyle: AxisStyle? = null,
    background: List<BackgroundStyle> = listOf(),
    barColor: Map<DataLabel, Color>,
)

The api is the same as in StackedBarChart

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants