Updated on 2026-08-14
This commit is contained in:
parent
9c5490bced
commit
a2792223a3
9 changed files with 534 additions and 0 deletions
1
common/ui-charts/.gitignore
vendored
Normal file
1
common/ui-charts/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
24
common/ui-charts/build.gradle.kts
Normal file
24
common/ui-charts/build.gradle.kts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.tangem.common.ui.charts"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Project - Core */
|
||||
implementation(projects.core.ui)
|
||||
|
||||
/** Compose */
|
||||
implementation(deps.tangem.vico.core)
|
||||
implementation(deps.tangem.vico.compose)
|
||||
implementation(deps.tangem.vico.compose.m3)
|
||||
|
||||
implementation(deps.compose.foundation)
|
||||
implementation(deps.compose.material3)
|
||||
implementation(deps.compose.ui.tooling)
|
||||
implementation(deps.compose.ui.utils)
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.common.ui.charts
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun MarketChart() {
|
||||
TODO()
|
||||
}
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
package com.tangem.common.ui.charts.layer
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.annotation.FloatRange
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.animate
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
||||
import com.patrykandpatrick.vico.compose.cartesian.fullWidth
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineSpec
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberSplitLineSpec
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState
|
||||
import com.patrykandpatrick.vico.compose.common.shader.BrushShader
|
||||
import com.patrykandpatrick.vico.core.cartesian.HorizontalLayout
|
||||
import com.patrykandpatrick.vico.core.cartesian.Zoom
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.AxisValueOverrider
|
||||
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
|
||||
import com.patrykandpatrick.vico.core.common.data.ExtraStore
|
||||
import com.patrykandpatrick.vico.core.common.shader.ColorShader
|
||||
import com.patrykandpatrick.vico.core.common.shader.DynamicShader
|
||||
import com.tangem.common.ui.charts.preview.getPreviewBigCartData
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
/**
|
||||
* Creates and remembers a LineCartesianLayer for a chart with specific characteristics.
|
||||
*
|
||||
* @param lineColor The color of the main line in the chart.
|
||||
* @param backgroundLineColor The color of the line's background.
|
||||
* @param secondLineColor The color of the line for the second part of the chart.
|
||||
* @param backgroundSecondLineColor The color of the line's background for the second part of the chart.
|
||||
* @param startDrawingAnimation A mutable state that triggers the start of the drawing animation when set to true.
|
||||
* @param axisValueOverrider An AxisValueOverrider that provides custom values for the axis.
|
||||
* @param secondColorOnTheRightSide A boolean that determines if the second color should be on the right side of the chart. Default is false.
|
||||
* @param markerFraction A float between 0.0 and 1.0 that represents the fraction of the chart where the marker is located. Default is null.
|
||||
*
|
||||
* @return A LineCartesianLayer that represents a layer in a chart with the specified characteristics.
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Composable
|
||||
fun rememberMarketChartLayer(
|
||||
lineColor: Color,
|
||||
backgroundLineColor: Color,
|
||||
secondLineColor: Color,
|
||||
backgroundSecondLineColor: Color,
|
||||
startDrawingAnimation: MutableState<Boolean>,
|
||||
axisValueOverrider: AxisValueOverrider,
|
||||
secondColorOnTheRightSide: Boolean = false,
|
||||
@FloatRange(from = 0.0, to = 1.0) markerFraction: Float? = null,
|
||||
): LineCartesianLayer {
|
||||
var animationFraction: Float? by remember { mutableStateOf(null) }
|
||||
|
||||
LaunchedEffect(startDrawingAnimation.value) {
|
||||
if (startDrawingAnimation.value) {
|
||||
animate(
|
||||
initialValue = 0f,
|
||||
targetValue = 1f,
|
||||
animationSpec = tween(easing = LinearEasing, durationMillis = 1000),
|
||||
) { start, _ ->
|
||||
if (start == 1f) {
|
||||
animationFraction = null
|
||||
startDrawingAnimation.value = false
|
||||
} else {
|
||||
animationFraction = start
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rememberRawMarketChartLayer(
|
||||
lineColor = lineColor,
|
||||
backgroundLineColor = backgroundLineColor,
|
||||
secondLineColor = secondLineColor,
|
||||
backgroundSecondLineColor = backgroundSecondLineColor,
|
||||
axisValueOverrider = axisValueOverrider,
|
||||
secondColorOnTheRightSide = secondColorOnTheRightSide,
|
||||
markerFraction = markerFraction,
|
||||
animationFraction = animationFraction,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberRawMarketChartLayer(
|
||||
lineColor: Color,
|
||||
backgroundLineColor: Color,
|
||||
secondLineColor: Color,
|
||||
backgroundSecondLineColor: Color,
|
||||
axisValueOverrider: AxisValueOverrider,
|
||||
secondColorOnTheRightSide: Boolean = false,
|
||||
@FloatRange(from = 0.0, to = 1.0) markerFraction: Float? = null,
|
||||
@FloatRange(from = 0.0, to = 1.0) animationFraction: Float? = null,
|
||||
): LineCartesianLayer {
|
||||
val backgroundColorLineGradient = listOf(backgroundLineColor, Color.Transparent)
|
||||
val backgroundSecondLineColorGradient = listOf(backgroundSecondLineColor, Color.Transparent)
|
||||
|
||||
val markerSet = markerFraction != null
|
||||
val animationRunning = animationFraction != null && animationFraction != 1f
|
||||
|
||||
val layerColors = remember(animationRunning, markerSet, secondColorOnTheRightSide) {
|
||||
when {
|
||||
!animationRunning && markerSet && secondColorOnTheRightSide -> {
|
||||
LayerColors(
|
||||
lineColor = lineColor,
|
||||
backLineColor = backgroundColorLineGradient,
|
||||
lineColorRight = secondLineColor,
|
||||
backLineColorRight = backgroundSecondLineColorGradient,
|
||||
)
|
||||
}
|
||||
!animationRunning && markerSet && !secondColorOnTheRightSide -> {
|
||||
LayerColors(
|
||||
lineColor = secondLineColor,
|
||||
backLineColor = backgroundSecondLineColorGradient,
|
||||
lineColorRight = lineColor,
|
||||
backLineColorRight = backgroundColorLineGradient,
|
||||
)
|
||||
}
|
||||
animationRunning -> {
|
||||
LayerColors(
|
||||
lineColor = lineColor,
|
||||
backLineColor = backgroundColorLineGradient,
|
||||
lineColorRight = Color.Transparent,
|
||||
backLineColorRight = listOf(Color.Transparent, Color.Transparent),
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
LayerColors(
|
||||
lineColor = lineColor,
|
||||
backLineColor = backgroundColorLineGradient,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rememberLayer(
|
||||
fractionValue = animationFraction ?: markerFraction,
|
||||
axisValueOverrider = axisValueOverrider,
|
||||
layerColors = layerColors,
|
||||
)
|
||||
}
|
||||
|
||||
private data class LayerColors(
|
||||
val lineColor: Color,
|
||||
val backLineColor: List<Color>,
|
||||
val lineColorRight: Color? = null,
|
||||
val backLineColorRight: List<Color>? = null,
|
||||
)
|
||||
|
||||
@Composable
|
||||
private fun rememberLayer(
|
||||
fractionValue: Float?,
|
||||
axisValueOverrider: AxisValueOverrider,
|
||||
layerColors: LayerColors,
|
||||
): LineCartesianLayer {
|
||||
return rememberLineCartesianLayer(
|
||||
listOf(
|
||||
if (layerColors.lineColorRight == null || layerColors.backLineColorRight == null || fractionValue == null) {
|
||||
rememberLineSpec(
|
||||
shader = remember(layerColors.lineColor) { ColorShader(color = layerColors.lineColor.toArgb()) },
|
||||
backgroundShader = remember(layerColors.backLineColor) {
|
||||
BrushShader(brush = Brush.verticalGradient(layerColors.backLineColor))
|
||||
},
|
||||
)
|
||||
} else {
|
||||
rememberSplitLineSpec(
|
||||
shader = remember(layerColors.lineColor, layerColors.lineColorRight, fractionValue) {
|
||||
DynamicShader.Companion.horizontalGradient(
|
||||
colors = intArrayOf(layerColors.lineColor.toArgb(), layerColors.lineColorRight.toArgb()),
|
||||
positions = floatArrayOf(fractionValue, fractionValue),
|
||||
)
|
||||
},
|
||||
backgroundShaderFirst = remember(layerColors.backLineColor) {
|
||||
BrushShader(brush = Brush.verticalGradient(layerColors.backLineColor))
|
||||
},
|
||||
backgroundShaderSecond = remember(layerColors.backLineColorRight) {
|
||||
BrushShader(brush = Brush.verticalGradient(layerColors.backLineColorRight))
|
||||
},
|
||||
xSplitFraction = fractionValue,
|
||||
)
|
||||
},
|
||||
),
|
||||
axisValueOverrider = axisValueOverrider,
|
||||
)
|
||||
}
|
||||
|
||||
// region Preview
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun LayerChartPreview() {
|
||||
val xListKey = ExtraStore.Key<List<Long>>()
|
||||
val model = getPreviewBigCartData(xListKey)
|
||||
|
||||
TangemThemePreview {
|
||||
Column(
|
||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||
verticalArrangement = Arrangement.spacedBy(48.dp),
|
||||
) {
|
||||
CartesianChartHost(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
chart = rememberCartesianChart(
|
||||
rememberRawMarketChartLayer(
|
||||
lineColor = Color.Blue,
|
||||
backgroundLineColor = Color.Blue.copy(alpha = 0.24f),
|
||||
secondLineColor = Color.Gray,
|
||||
backgroundSecondLineColor = Color.Gray.copy(alpha = 0.24f),
|
||||
secondColorOnTheRightSide = true,
|
||||
axisValueOverrider = AxisValueOverrider.fixed(minY = model.models[0].minY),
|
||||
),
|
||||
),
|
||||
zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
|
||||
horizontalLayout = HorizontalLayout.fullWidth(),
|
||||
model = model,
|
||||
)
|
||||
|
||||
CartesianChartHost(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
chart = rememberCartesianChart(
|
||||
rememberRawMarketChartLayer(
|
||||
lineColor = Color.Blue,
|
||||
backgroundLineColor = Color.Blue.copy(alpha = 0.24f),
|
||||
secondLineColor = Color.Gray,
|
||||
backgroundSecondLineColor = Color.Gray.copy(alpha = 0.24f),
|
||||
markerFraction = 0.35f,
|
||||
secondColorOnTheRightSide = true,
|
||||
axisValueOverrider = AxisValueOverrider.fixed(minY = model.models[0].minY),
|
||||
),
|
||||
),
|
||||
zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
|
||||
horizontalLayout = HorizontalLayout.fullWidth(),
|
||||
model = model,
|
||||
)
|
||||
|
||||
CartesianChartHost(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
chart = rememberCartesianChart(
|
||||
rememberRawMarketChartLayer(
|
||||
lineColor = Color.Blue,
|
||||
backgroundLineColor = Color.Blue.copy(alpha = 0.24f),
|
||||
secondLineColor = Color.Blue,
|
||||
backgroundSecondLineColor = Color.Blue.copy(alpha = 0.24f),
|
||||
markerFraction = 0.35f,
|
||||
secondColorOnTheRightSide = true,
|
||||
animationFraction = 0.7f,
|
||||
axisValueOverrider = AxisValueOverrider.fixed(minY = model.models[0].minY),
|
||||
),
|
||||
),
|
||||
zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
|
||||
horizontalLayout = HorizontalLayout.fullWidth(),
|
||||
model = model,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.tangem.common.ui.charts.marker
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
||||
import com.patrykandpatrick.vico.compose.cartesian.fullWidth
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
|
||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineSpec
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberCartesianChart
|
||||
import com.patrykandpatrick.vico.compose.cartesian.rememberVicoZoomState
|
||||
import com.patrykandpatrick.vico.compose.common.component.rememberLayeredComponent
|
||||
import com.patrykandpatrick.vico.compose.common.component.rememberShapeComponent
|
||||
import com.patrykandpatrick.vico.compose.common.component.rememberUnboundedLineComponent
|
||||
import com.patrykandpatrick.vico.compose.common.of
|
||||
import com.patrykandpatrick.vico.compose.common.shader.color
|
||||
import com.patrykandpatrick.vico.compose.common.shape.dashed
|
||||
import com.patrykandpatrick.vico.core.cartesian.*
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.AxisValueOverrider
|
||||
import com.patrykandpatrick.vico.core.cartesian.marker.CartesianMarker
|
||||
import com.patrykandpatrick.vico.core.cartesian.marker.DefaultCartesianMarker
|
||||
import com.patrykandpatrick.vico.core.common.Dimensions
|
||||
import com.patrykandpatrick.vico.core.common.component.TextComponent
|
||||
import com.patrykandpatrick.vico.core.common.data.ExtraStore
|
||||
import com.patrykandpatrick.vico.core.common.shader.DynamicShader
|
||||
import com.patrykandpatrick.vico.core.common.shape.Shape
|
||||
import com.tangem.common.ui.charts.preview.getPreviewBigCartData
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
/**
|
||||
* @param color The color of the indicator and guideline.
|
||||
* @param innerCircleColor The color of the inner circle of the indicator.
|
||||
*
|
||||
* @return A [CartesianMarker] that consists of a dashed guideline and a layered indicator with a shadow effect.
|
||||
*/
|
||||
@Composable
|
||||
internal fun rememberTangemChartMarker(color: Color, innerCircleColor: Color): CartesianMarker {
|
||||
val indicatorFrontComponent = rememberShapeComponent(
|
||||
shape = Shape.Pill,
|
||||
color = innerCircleColor,
|
||||
)
|
||||
val indicatorCenterComponent = rememberShapeComponent(
|
||||
shape = Shape.Pill,
|
||||
color = color,
|
||||
)
|
||||
val indicatorRearComponent = rememberShapeComponent(
|
||||
shape = Shape.Pill,
|
||||
color = color.copy(alpha = INDICATOR_REAR_COLOR_ALPHA),
|
||||
)
|
||||
val indicator = rememberLayeredComponent(
|
||||
rear = indicatorRearComponent,
|
||||
front = rememberLayeredComponent(
|
||||
rear = indicatorCenterComponent,
|
||||
front = indicatorFrontComponent,
|
||||
padding = indicatorPadding,
|
||||
),
|
||||
padding = indicatorPadding,
|
||||
)
|
||||
val guideline = rememberUnboundedLineComponent(
|
||||
color = color,
|
||||
verticalAddDrawSpace = TangemTheme.dimens.spacing24,
|
||||
shape = remember { Shape.dashed(Shape.Rectangle, 4.dp, 4.dp) },
|
||||
)
|
||||
return remember(indicator, guideline) {
|
||||
object : DefaultCartesianMarker(
|
||||
label = TextComponent.build { textSizeSp = 0f },
|
||||
indicator = indicator,
|
||||
indicatorSizeDp = INDICATOR_SIZE_DP,
|
||||
guideline = guideline,
|
||||
) {
|
||||
override fun getInsets(
|
||||
context: CartesianMeasureContext,
|
||||
outInsets: Insets,
|
||||
horizontalDimensions: HorizontalDimensions,
|
||||
) {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val indicatorPadding = Dimensions.of(3.dp)
|
||||
private const val LABEL_BACKGROUND_SHADOW_RADIUS_DP = 4f
|
||||
private const val LABEL_BACKGROUND_SHADOW_DY_DP = 2f
|
||||
private const val CLIPPING_FREE_SHADOW_RADIUS_MULTIPLIER = 1.4f
|
||||
private const val INDICATOR_SIZE_DP = 16f
|
||||
private const val INDICATOR_REAR_COLOR_ALPHA = .24f
|
||||
|
||||
// region Preview
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun TangemChartMarkerPreview() {
|
||||
val marker = rememberTangemChartMarker(Color.Red, Color.White)
|
||||
val xListKey = ExtraStore.Key<List<Long>>()
|
||||
val model = getPreviewBigCartData(xListKey)
|
||||
val centerAprx = (model.models[0].minX + model.models[0].maxX) / 2f
|
||||
val center = model.models[0].getXDeltaGcd().let { centerAprx - centerAprx % it }
|
||||
|
||||
TangemThemePreview {
|
||||
Box(modifier = Modifier.background(TangemTheme.colors.background.primary)) {
|
||||
CartesianChartHost(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
chart = rememberCartesianChart(
|
||||
rememberLineCartesianLayer(
|
||||
listOf(rememberLineSpec(shader = DynamicShader.color(Color.Blue))),
|
||||
axisValueOverrider = AxisValueOverrider.fixed(minY = model.models[0].minY),
|
||||
),
|
||||
persistentMarkers = mapOf(center to marker),
|
||||
),
|
||||
model = model,
|
||||
marker = marker,
|
||||
zoomState = rememberVicoZoomState(initialZoom = Zoom.Content, zoomEnabled = false),
|
||||
horizontalLayout = HorizontalLayout.fullWidth(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
@file:Suppress("MagicNumber", "LongMethod")
|
||||
|
||||
package com.tangem.common.ui.charts.preview
|
||||
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModel
|
||||
import com.patrykandpatrick.vico.core.cartesian.data.LineCartesianLayerModel
|
||||
import com.patrykandpatrick.vico.core.common.data.ExtraStore
|
||||
import com.patrykandpatrick.vico.core.common.data.MutableExtraStore
|
||||
|
||||
internal fun getPreviewBigCartData(xListKey: ExtraStore.Key<List<Long>>): CartesianChartModel {
|
||||
val y = listOf(
|
||||
59270, 61748, 61941, 62889, 62740, 62989, 63858, 63608, 63951, 63917,
|
||||
63253, 63765, 63862, 64502, 63876, 64028, 63875, 64531, 64249, 63680,
|
||||
63228, 63159, 63249, 63664, 63469, 63711, 63003, 62333, 62882, 62183,
|
||||
62231, 62244, 62200, 61188, 61683, 61199, 61036, 62116, 62436, 63065,
|
||||
62908, 63067, 63294, 60904, 60677, 60790, 60705, 61041, 60667, 61158,
|
||||
61112, 60795, 60900, 60771, 61124, 61343, 61371, 61484, 61133, 62372,
|
||||
62704, 63007, 63092, 62905, 62470, 62019, 61756, 61776, 61557, 61540,
|
||||
61904, 62151, 62419, 64663, 65955, 66229, 65991, 66176, 66517, 65838,
|
||||
65210, 65216, 65611, 66467, 66209, 67247, 66913, 67059, 66978, 66845,
|
||||
67240, 66874, 66993, 66940, 67185, 67330, 67340, 66845, 66062, 66273,
|
||||
66645, 66865, 67005, 67382, 70049, 71464, 71293, 70875, 71137, 69720,
|
||||
69323, 70139, 69964, 69716, 69855, 70442, 69774, 69125, 69404, 69714,
|
||||
69967, 68042, 67077, 67938, 67833, 67182, 67306, 68327, 69093, 68517,
|
||||
68726, 68759, 69061, 68880, 69148, 69305, 69044, 69313, 69122, 68821,
|
||||
68854, 68506, 68823, 68613, 68420, 70356, 69241, 69401, 68004, 67630,
|
||||
68311, 68311, 68291, 68302, 68717, 67926, 67690, 67314, 67285, 67567,
|
||||
68026, 67552, 67740, 68519, 68611, 68363, 68503, 68171, 68326, 67121,
|
||||
67626, 67481, 67657, 67567, 67608, 67607, 67683, 67729, 67733, 67709,
|
||||
)
|
||||
val timestamps: List<Long> = listOf(
|
||||
1714752000000, 1714766400000, 1714780800000, 1714795200000, 1714809600000,
|
||||
1714824000000, 1714838400000, 1714852800000, 1714867200000, 1714881600000,
|
||||
1714896000000, 1714910400000, 1714924800000, 1714939200000, 1714953600000,
|
||||
1714968000000, 1714982400000, 1714996800000, 1715011200000, 1715025600000,
|
||||
1715040000000, 1715054400000, 1715068800000, 1715083200000, 1715097600000,
|
||||
1715112000000, 1715126400000, 1715140800000, 1715155200000, 1715169600000,
|
||||
1715184000000, 1715198400000, 1715212800000, 1715227200000, 1715241600000,
|
||||
1715256000000, 1715270400000, 1715284800000, 1715299200000, 1715313600000,
|
||||
1715328000000, 1715342400000, 1715356800000, 1715371200000, 1715385600000,
|
||||
1715400000000, 1715414400000, 1715428800000, 1715443200000, 1715457600000,
|
||||
1715472000000, 1715486400000, 1715500800000, 1715515200000, 1715529600000,
|
||||
1715544000000, 1715558400000, 1715572800000, 1715587200000, 1715601600000,
|
||||
1715616000000, 1715630400000, 1715644800000, 1715659200000, 1715673600000,
|
||||
1715688000000, 1715702400000, 1715716800000, 1715731200000, 1715745600000,
|
||||
1715760000000, 1715774400000, 1715788800000, 1715803200000, 1715817600000,
|
||||
1715832000000, 1715846400000, 1715860800000, 1715875200000, 1715889600000,
|
||||
1715904000000, 1715918400000, 1715932800000, 1715947200000, 1715961600000,
|
||||
1715976000000, 1715990400000, 1716004800000, 1716019200000, 1716033600000,
|
||||
1716048000000, 1716062400000, 1716076800000, 1716091200000, 1716105600000,
|
||||
1716120000000, 1716134400000, 1716148800000, 1716163200000, 1716177600000,
|
||||
1716192000000, 1716206400000, 1716220800000, 1716235200000, 1716249600000,
|
||||
1716264000000, 1716278400000, 1716292800000, 1716307200000, 1716321600000,
|
||||
1716336000000, 1716350400000, 1716364800000, 1716379200000, 1716393600000,
|
||||
1716408000000, 1716422400000, 1716436800000, 1716451200000, 1716465600000,
|
||||
1716480000000, 1716494400000, 1716508800000, 1716523200000, 1716537600000,
|
||||
1716552000000, 1716566400000, 1716580800000, 1716595200000, 1716609600000,
|
||||
1716624000000, 1716638400000, 1716652800000, 1716667200000, 1716681600000,
|
||||
1716696000000, 1716710400000, 1716724800000, 1716739200000, 1716753600000,
|
||||
1716768000000, 1716782400000, 1716796800000, 1716811200000, 1716825600000,
|
||||
1716840000000, 1716854400000, 1716868800000, 1716883200000, 1716897600000,
|
||||
1716912000000, 1716926400000, 1716940800000, 1716955200000, 1716969600000,
|
||||
1716984000000, 1716998400000, 1717012800000, 1717027200000, 1717041600000,
|
||||
1717056000000, 1717070400000, 1717084800000, 1717099200000, 1717113600000,
|
||||
1717128000000, 1717142400000, 1717156800000, 1717171200000, 1717185600000,
|
||||
1717200000000, 1717214400000, 1717228800000, 1717243200000, 1717257600000,
|
||||
1717272000000, 1717286400000, 1717300800000, 1717315200000, 1717329600000,
|
||||
)
|
||||
|
||||
val x = List(y.size) { index -> index }
|
||||
|
||||
return CartesianChartModel(LineCartesianLayerModel.build { series(x, y) }).copy(
|
||||
extraStore = MutableExtraStore().apply {
|
||||
set(xListKey, timestamps)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -91,6 +91,8 @@ tangemBlockchainSdk = "develop-654"
|
|||
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
|
||||
tangemCardSdk = "develop-360"
|
||||
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
|
||||
tangemVico = "2.0.0-alpha.21-tangem13"
|
||||
#tangemVico = "0.0.1" # Keep it! - used for local builds ^
|
||||
# endregion Tangem
|
||||
|
||||
# region Tools
|
||||
|
|
@ -180,6 +182,10 @@ firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx"
|
|||
tangem-blockchain = { module = "com.tangem:blockchain", version.ref = "tangemBlockchainSdk" }
|
||||
tangem-card-android = { module = "com.tangem.tangem-sdk-kotlin:android", version.ref = "tangemCardSdk" }
|
||||
tangem-card-core = { module = "com.tangem.tangem-sdk-kotlin:core", version.ref = "tangemCardSdk" }
|
||||
|
||||
tangem-vico-compose = { group = "com.tangem.vico", name = "compose", version.ref = "tangemVico" }
|
||||
tangem-vico-compose-m3 = { group = "com.tangem.vico", name = "compose-m3", version.ref = "tangemVico" }
|
||||
tangem-vico-core = { group = "com.tangem.vico", name = "core", version.ref = "tangemVico" }
|
||||
# endregion Tangem
|
||||
|
||||
# region Detekt
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ internal fun BaseExtension.configureCompilerOptions() {
|
|||
internal fun BaseExtension.configureCompose(project: Project) {
|
||||
val useCompose = with(project.path) {
|
||||
contains(":ui") ||
|
||||
contains(":common:ui-charts") ||
|
||||
contains(":features:onboarding") || // TODO: divide on api/impl after migrating all onboarding to module
|
||||
contains(Regex(pattern = ":presentation\$")) ||
|
||||
contains(Regex(pattern = ":app\$")) || // TODO: [REDACTED_JIRA]
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ dependencyResolutionManagement {
|
|||
includeModule("com.tangem", "blockchain")
|
||||
includeModule("com.tangem", "wallet-core-proto")
|
||||
includeModule("com.tangem", "wallet-core")
|
||||
includeModule("com.tangem", "vico")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
|
|
@ -80,6 +81,17 @@ dependencyResolutionManagement {
|
|||
includeModule("com.tangem", "wallet-core")
|
||||
}
|
||||
}
|
||||
maven {
|
||||
// setting any repository from tangem project allows maven search all packages in the project
|
||||
url = uri("https://maven.pkg.github.com/tangem/vico")
|
||||
credentials {
|
||||
username = properties.getProperty("gpr.user") ?: System.getenv("GITHUB_ACTOR")
|
||||
password = properties.getProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
content {
|
||||
includeGroupAndSubgroups("com.tangem.vico")
|
||||
}
|
||||
}
|
||||
jcenter { // unable to replace with mavenCentral() due to rekotlin
|
||||
content {
|
||||
includeModule("org.rekotlin", "rekotlin")
|
||||
|
|
@ -100,6 +112,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
|||
|
||||
include(":app")
|
||||
include(":common")
|
||||
include(":common:ui-charts")
|
||||
|
||||
// region Core modules
|
||||
include(":core:analytics")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue