Skip to content

Radar Chart #10

@hdralexandru

Description

@hdralexandru

The Radar Chart is useful for displaying a multitude of data points and the variations between them.

We may split the Radar Chart into 3 parts:

  • The net - the background of the graph
  • The polygons - the visual representation of the data.
  • The labels - both on the net and outside the net.

Example of Radar Chart
Screenshot 2023-07-17 at 15 18 57

The suggestions are inspired from here: https://r-graph-gallery.com/142-basic-radar-chart.html

The API

A first iteration of the api:

/**
 * @param limits the min/max limits of the graph. Will be used to determine where a point lies on the axis.
 * @param entries each entry represents a new polygon that will be drawn on the screen
 * @param labels the labels drawn on the corners of the graph. The number of corners is determined by the [entries.size] function
 * @param labelStyle the style used for drawing the label
 * @param polygons a list of [PolygonProperties] used to determine the style of each polygon on the ui.
 * @param netStyle style for the net that's being drawn behind the content
 */
@Composable
fun RadarChart(
    modifier: Modifier,
    limits: ChartValueLimits,
    entries: List<RadarEntry>,
    polygons: List<PolygonProperties>,
    labels: List<String>,
    labelStyle: TextStyle = TextStyle.Default,
    netStyle: NetStyle,
) 

There are some constrains regarding the parameters:

  • the number of entries must match the number of PolygonProperties.
  • the number of labels will determine the number of angles of the Chart

RadarEntry

Will represent an entry in the chart.
In contains the list of values to be displayed. If a value is missing or negative, will be set to 0

/**
 * Class holding the data that will be used to draw on the screen
 * The values must match the number of corners the [RadarChart].
 * If the number of entries in the [values] is smaller than the number of corners,
 * the rest will be considered to be 0
 */
class RadarEntry(val values: List<Float>) {

    fun valueAt(position: Int): Float {
        return if (position < 0 || position > values.size) {
            0f
        } else {
            values[position]
        }
    }
}

Chart Value Limits

We'll use those values to determine where our point will be on the axis.
To determine the value, we'll use the 3 simple rule between the inferior, superior and current value.

/**
 * The limits of the axis of the chart.
 * To determine where the point lies on the axis, we'll use the 3-simple rule.
 */
class ChartValueLimits(
    val inferior: Float,
    val superior: Float,
)

Net Style

The background of the chart

/**

  • The style used for drawing the net(grid) on which the polygons lie.
    */
    class NetStyle(
    val width: Float,
    val color: Color,
    val type: DrawStyle = Stroke()
    )

PolygonProperties

How we are going to draw our polygon on the screen

/**
 * The information necessary for drawing a polygon on the screen, for a [RadarEntry].
 *
 * @param borderColor the [Color] used for drawing the borders of the polygon. Mandatory
 * @param borderWidth the width of the border of the polygon. Mandatory
 * @param areaColor the color for the area inside the [borderColor]
 * @param dotsRadius if different from 0f, dots will be drawn at the intersection between 2 lines of the border
 */
class PolygonProperties(
    val borderColor: Color,
    val borderWidth: Float,
    val areaColor: Color = Color.Unspecified,
    val dotsRadius: Float = 0f,
)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions