Skip to content

Commit

Permalink
Make Insets-related updates (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickmichalik committed Jun 29, 2024
1 parent 313f44f commit 3b03130
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 319 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,25 @@ internal fun rememberMarker(
},
guideline = guideline,
) {
override fun getInsets(
override fun updateInsets(
context: CartesianMeasureContext,
outInsets: Insets,
horizontalDimensions: HorizontalDimensions,
insets: Insets,
) {
with(context) {
super.getInsets(context, outInsets, horizontalDimensions)
val baseShadowInsetDp =
CLIPPING_FREE_SHADOW_RADIUS_MULTIPLIER * LABEL_BACKGROUND_SHADOW_RADIUS_DP
outInsets.top += (baseShadowInsetDp - LABEL_BACKGROUND_SHADOW_DY_DP).pixels
outInsets.bottom += (baseShadowInsetDp + LABEL_BACKGROUND_SHADOW_DY_DP).pixels
var topInset = (baseShadowInsetDp - LABEL_BACKGROUND_SHADOW_DY_DP).pixels
var bottomInset = (baseShadowInsetDp + LABEL_BACKGROUND_SHADOW_DY_DP).pixels
when (labelPosition) {
LabelPosition.Top,
LabelPosition.AbovePoint ->
topInset += label.getHeight(context) + label.tickSizeDp.pixels
LabelPosition.Bottom ->
bottomInset += label.getHeight(context) + label.tickSizeDp.pixels
LabelPosition.AroundPoint -> Unit
}
insets.ensureValuesAtLeast(top = topInset, bottom = bottomInset)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ internal fun CartesianChartHostImpl(
horizontalLayout: HorizontalLayout,
chartValues: ChartValues,
) {
val bounds = remember { RectF() }
val canvasBounds = remember { RectF() }
val markerTouchPoint = remember { mutableStateOf<Point?>(null) }
val measureContext =
rememberCartesianMeasureContext(
scrollState.scrollEnabled,
zoomState.zoomEnabled,
bounds,
canvasBounds,
horizontalLayout,
with(LocalContext.current) { ::spToPx },
chartValues,
Expand Down Expand Up @@ -251,10 +251,10 @@ internal fun CartesianChartHostImpl(
},
)
) {
bounds.set(left = 0, top = 0, right = size.width, bottom = size.height)
canvasBounds.set(left = 0, top = 0, right = size.width, bottom = size.height)

horizontalDimensions.clear()
chart.prepare(measureContext, model, horizontalDimensions, bounds, marker)
chart.prepare(measureContext, model, horizontalDimensions, canvasBounds, marker)

if (chart.bounds.isEmpty) return@Canvas

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.patrykandpatrick.vico.core.common.BoundsAware
import com.patrykandpatrick.vico.core.common.Legend
import com.patrykandpatrick.vico.core.common.data.MutableExtraStore
import com.patrykandpatrick.vico.core.common.inClip
import com.patrykandpatrick.vico.core.common.orZero
import com.patrykandpatrick.vico.core.common.set
import com.patrykandpatrick.vico.core.common.setAll
import java.util.SortedMap
Expand All @@ -52,9 +53,8 @@ public open class CartesianChart(
) : BoundsAware, ChartInsetter {
private val decorations = mutableListOf<Decoration>()
private val persistentMarkers = mutableMapOf<Float, CartesianMarker>()
private val tempInsets = Insets()
private val insets = Insets()
private val axisManager = AxisManager()
private val virtualLayout = VirtualLayout(axisManager)
private val _markerTargets = sortedMapOf<Float, MutableList<CartesianMarker.Target>>()

private val drawingModelAndLayerConsumer =
Expand Down Expand Up @@ -101,9 +101,6 @@ public open class CartesianChart(
/** The [CartesianLayer]s of which this [CartesianChart] is composed. */
public val layers: List<CartesianLayer<*>> = layers.toList()

/** The [CartesianChart]’s [ChartInsetter]s (persistent [CartesianMarker]s). */
public val chartInsetters: Collection<ChartInsetter> = persistentMarkers.values

/** Links _x_ values to [CartesianMarker.Target]s. */
@Suppress("UNCHECKED_CAST")
public val markerTargets: SortedMap<Float, List<CartesianMarker.Target>> =
Expand Down Expand Up @@ -139,10 +136,11 @@ public open class CartesianChart(
context: CartesianMeasureContext,
model: CartesianChartModel,
horizontalDimensions: MutableHorizontalDimensions,
bounds: RectF,
canvasBounds: RectF,
marker: CartesianMarker?,
) {
_markerTargets.clear()
insets.clear()
model.forEachWithLayer(
horizontalDimensionUpdateModelAndLayerConsumer.apply {
this.context = context
Expand All @@ -153,7 +151,29 @@ public open class CartesianChart(
topAxis?.updateHorizontalDimensions(context, horizontalDimensions)
endAxis?.updateHorizontalDimensions(context, horizontalDimensions)
bottomAxis?.updateHorizontalDimensions(context, horizontalDimensions)
virtualLayout.setBounds(context, bounds, this, legend, horizontalDimensions, marker)
val insetters = buildList {
add(this@CartesianChart)
addAll(axisManager.axisCache)
if (marker != null) add(marker)
addAll(persistentMarkers.values)
}
insetters.forEach { it.updateInsets(context, horizontalDimensions, insets) }
val legendHeight = legend?.getHeight(context, canvasBounds.width()).orZero
val freeHeight = canvasBounds.height() - insets.vertical - legendHeight
insetters.forEach { it.updateHorizontalInsets(context, freeHeight, insets) }
setBounds(
canvasBounds.left + insets.getLeft(context.isLtr),
canvasBounds.top + insets.top,
canvasBounds.right - insets.getRight(context.isLtr),
canvasBounds.bottom - insets.bottom - legendHeight,
)
axisManager.setAxesBounds(context, canvasBounds, bounds, insets)
legend?.setBounds(
left = canvasBounds.left,
top = bounds.bottom + insets.bottom,
right = canvasBounds.right,
bottom = bounds.bottom + insets.bottom + legendHeight,
)
}

/** Draws the [CartesianChart]. */
Expand Down Expand Up @@ -188,24 +208,20 @@ public open class CartesianChart(
)
}

override fun getInsets(
override fun updateInsets(
context: CartesianMeasureContext,
outInsets: Insets,
horizontalDimensions: HorizontalDimensions,
insets: Insets,
) {
tempInsets.clear()
layers.forEach { it.getInsets(context, tempInsets, horizontalDimensions) }
outInsets.setValuesIfGreater(tempInsets)
layers.forEach { it.updateInsets(context, horizontalDimensions, insets) }
}

override fun getHorizontalInsets(
override fun updateHorizontalInsets(
context: CartesianMeasureContext,
availableHeight: Float,
outInsets: HorizontalInsets,
freeHeight: Float,
insets: HorizontalInsets,
) {
tempInsets.clear()
layers.forEach { it.getHorizontalInsets(context, availableHeight, tempInsets) }
outInsets.setValuesIfGreater(start = tempInsets.start, end = tempInsets.end)
layers.forEach { it.updateHorizontalInsets(context, freeHeight, insets) }
}

/** Prepares the [CartesianLayer]s for a difference animation. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,33 +25,33 @@ import com.patrykandpatrick.vico.core.cartesian.marker.CartesianMarker
*/
public interface ChartInsetter {
/**
* Called during the measurement phase, before [getHorizontalInsets]. Both horizontal and vertical
* insets can be requested from this function. The final inset for a given edge of the associated
* [CartesianChart] is the largest of the insets requested for the edge.
* Called during the measurement phase, before [updateHorizontalInsets]. Both horizontal and
* vertical insets can be requested from this function. The final inset for a given edge of the
* associated [CartesianChart] is the largest of the insets requested for the edge.
*
* @param context holds data used for the measuring of components.
* @param outInsets used to store the requested insets.
* @param insets used to store the requested insets.
* @param horizontalDimensions the [CartesianChart]’s [HorizontalDimensions].
*/
public fun getInsets(
public fun updateInsets(
context: CartesianMeasureContext,
outInsets: Insets,
horizontalDimensions: HorizontalDimensions,
): Unit = Unit
insets: Insets,
) {}

/**
* Called during the measurement phase, after [getInsets]. Only horizontal insets can be requested
* from this function. Unless the available height is of interest, [getInsets] can be used to set
* all insets. The final inset for a given edge of the associated [CartesianChart] is the largest
* of the insets requested for the edge.
* Called during the measurement phase, after [updateInsets]. Only horizontal insets can be
* requested from this function. Unless the available height is of interest, [updateInsets] can be
* used to set all insets. The final inset for a given edge of the associated [CartesianChart] is
* the largest of the insets requested for the edge.
*
* @param context holds data used for the measuring of components.
* @param availableHeight the available height. The vertical insets are considered here.
* @param outInsets used to store the requested insets.
* @param freeHeight the available height. The vertical insets are considered here.
* @param insets used to store the requested insets.
*/
public fun getHorizontalInsets(
public fun updateHorizontalInsets(
context: CartesianMeasureContext,
availableHeight: Float,
outInsets: HorizontalInsets,
): Unit = Unit
freeHeight: Float,
insets: HorizontalInsets,
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,22 @@ package com.patrykandpatrick.vico.core.cartesian
* @see Insets
*/
public interface HorizontalInsets {
/** Sets the start and end insets. */
public fun set(start: Float, end: Float)
/** The start inset’s size (in pixels). */
public val start: Float

/**
* For the start and end insets, updates the value of the inset to the corresponding provided
* value if the provided value is greater than the current value.
*/
public fun setValuesIfGreater(start: Float, end: Float)
/** The end inset’s size (in pixels). */
public val end: Float

/** The sum of the start and end insets’ sizes (in pixels). */
public val horizontal: Float
get() = start + end

/** Returns the left inset’s size (in pixels). */
public fun getLeft(isLtr: Boolean): Float = if (isLtr) start else end

/** Returns the right inset’s size (in pixels). */
public fun getRight(isLtr: Boolean): Float = if (isLtr) end else start

/** Ensures that the stored values are no smaller than the provided ones. */
public fun ensureValuesAtLeast(start: Float = this.start, end: Float = this.end)
}
Loading

0 comments on commit 3b03130

Please sign in to comment.