Updated on 2026-08-14
This commit is contained in:
parent
7d6d4fddf6
commit
d75368608f
4 changed files with 134 additions and 5 deletions
|
|
@ -145,6 +145,7 @@ class TangemColors internal constructor(
|
|||
class Background internal constructor(
|
||||
primary: Color,
|
||||
secondary: Color,
|
||||
tertiary: Color,
|
||||
plain: Color,
|
||||
action: Color,
|
||||
fade: Color,
|
||||
|
|
@ -153,6 +154,8 @@ class TangemColors internal constructor(
|
|||
private set
|
||||
var secondary by mutableStateOf(secondary)
|
||||
private set
|
||||
var tertiary by mutableStateOf(tertiary)
|
||||
private set
|
||||
var plain by mutableStateOf(plain)
|
||||
private set
|
||||
var action by mutableStateOf(action)
|
||||
|
|
@ -163,6 +166,7 @@ class TangemColors internal constructor(
|
|||
fun update(other: Background) {
|
||||
primary = other.primary
|
||||
secondary = other.secondary
|
||||
tertiary = other.tertiary
|
||||
plain = other.plain
|
||||
action = other.action
|
||||
fade = other.fade
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ data class TangemDimens internal constructor(
|
|||
val radius18: Dp = 18.dp,
|
||||
val radius24: Dp = 24.dp,
|
||||
val radius28: Dp = 28.dp,
|
||||
val radius36: Dp = 36.dp,
|
||||
// endregion Radius
|
||||
// region Size
|
||||
val size0: Dp = 0.dp,
|
||||
|
|
@ -71,6 +72,7 @@ data class TangemDimens internal constructor(
|
|||
val size80: Dp = 80.dp,
|
||||
val size84: Dp = 84.dp,
|
||||
val size86: Dp = 86.dp,
|
||||
val size90: Dp = 90.dp,
|
||||
val size93: Dp = 93.dp,
|
||||
val size96: Dp = 96.dp,
|
||||
val size102: Dp = 102.dp,
|
||||
|
|
|
|||
|
|
@ -116,12 +116,13 @@ private fun lightThemeColors(): TangemColors {
|
|||
background = TangemColors.Background(
|
||||
primary = TangemColorPalette.White,
|
||||
secondary = TangemColorPalette.Light1,
|
||||
tertiary = TangemColorPalette.Light1,
|
||||
plain = TangemColorPalette.White,
|
||||
action = TangemColorPalette.Black,
|
||||
action = TangemColorPalette.White,
|
||||
fade = TangemColorPalette.White,
|
||||
),
|
||||
control = TangemColors.Control(
|
||||
checked = TangemColorPalette.Meadow,
|
||||
checked = TangemColorPalette.Dark6,
|
||||
unchecked = TangemColorPalette.Light2,
|
||||
key = TangemColorPalette.White,
|
||||
),
|
||||
|
|
@ -168,14 +169,15 @@ private fun darkThemeColors(): TangemColors {
|
|||
background = TangemColors.Background(
|
||||
primary = TangemColorPalette.Dark6,
|
||||
secondary = TangemColorPalette.Black,
|
||||
tertiary = TangemColorPalette.Dark6,
|
||||
plain = TangemColorPalette.Black,
|
||||
action = TangemColorPalette.Light4,
|
||||
action = TangemColorPalette.Dark5,
|
||||
fade = TangemColorPalette.Black,
|
||||
),
|
||||
control = TangemColors.Control(
|
||||
checked = TangemColorPalette.Meadow,
|
||||
checked = TangemColorPalette.Azure,
|
||||
unchecked = TangemColorPalette.Dark4,
|
||||
key = TangemColorPalette.Light1,
|
||||
key = TangemColorPalette.White,
|
||||
),
|
||||
stroke = TangemColors.Stroke(
|
||||
primary = TangemColorPalette.Dark5,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,121 @@
|
|||
package com.tangem.managetokens.presentation.managetokens.ui.components
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Path
|
||||
import androidx.compose.ui.graphics.drawscope.DrawScope
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
* A chart with a solid line and gradient underneath. It can accept values of any range and number.
|
||||
* If the last value is bigger or equal to the first, the chart is of accent color, otherwise it's warning color.
|
||||
*
|
||||
* @param values a list of float values for a chart.
|
||||
**/
|
||||
@Composable
|
||||
fun PriceChangesChart(values: List<Float>, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier) {
|
||||
if (values.size < 2) return // escape without drawing when there are not enough points
|
||||
|
||||
val lineColor = if (values.last() >= values.first()) {
|
||||
TangemTheme.colors.icon.accent
|
||||
} else {
|
||||
TangemTheme.colors.icon.warning
|
||||
}
|
||||
val gradient = Brush.verticalGradient(
|
||||
colors = listOf(lineColor.copy(alpha = 0.21f), lineColor.copy(alpha = 0.0f)),
|
||||
)
|
||||
Chart(list = values, lineColor = lineColor, gradient = gradient, modifier = Modifier.weight(1f))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Chart(list: List<Float>, lineColor: Color, gradient: Brush, modifier: Modifier = Modifier) {
|
||||
val max = list.max()
|
||||
val min = list.min()
|
||||
val zipList: List<Pair<Float, Float>> = list.zipWithNext()
|
||||
|
||||
for (pair in zipList) {
|
||||
val fromValuePercentage = getValuePercentageForRange(pair.first, max, min)
|
||||
val toValuePercentage = getValuePercentageForRange(pair.second, max, min)
|
||||
|
||||
Canvas(
|
||||
modifier = modifier.fillMaxHeight(),
|
||||
onDraw = {
|
||||
val fromPoint = Offset(x = 0f, y = size.height.times(1 - fromValuePercentage))
|
||||
val toPoint = Offset(x = size.width, y = size.height.times(1 - toValuePercentage))
|
||||
|
||||
val path = drawChartLineAndCreatePath(fromPoint = fromPoint, toPoint = toPoint, lineColor = lineColor)
|
||||
|
||||
fillChart(
|
||||
path = path,
|
||||
fromPoint = fromPoint,
|
||||
toPoint = toPoint,
|
||||
size = size,
|
||||
gradient = gradient,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun DrawScope.drawChartLineAndCreatePath(fromPoint: Offset, toPoint: Offset, lineColor: Color): Path {
|
||||
val path = Path()
|
||||
path.moveTo(fromPoint.x, fromPoint.y)
|
||||
path.lineTo(toPoint.x, toPoint.y)
|
||||
drawPath(
|
||||
path = path,
|
||||
color = lineColor,
|
||||
style = Stroke(width = 1f),
|
||||
)
|
||||
return path
|
||||
}
|
||||
|
||||
private fun DrawScope.fillChart(path: Path, fromPoint: Offset, toPoint: Offset, size: Size, gradient: Brush) {
|
||||
path.lineTo(toPoint.x, size.height)
|
||||
path.lineTo(fromPoint.x, size.height)
|
||||
path.lineTo(0f, fromPoint.y)
|
||||
drawPath(
|
||||
path = path,
|
||||
brush = gradient,
|
||||
)
|
||||
}
|
||||
|
||||
private fun getValuePercentageForRange(value: Float, max: Float, min: Float): Float {
|
||||
return if (max == min) { // to draw a straight line when all values are the same
|
||||
val modifiedMax = max + 1
|
||||
val modifiedMin = min - 1
|
||||
(value - modifiedMin) / (modifiedMax - modifiedMin)
|
||||
} else {
|
||||
(value - min) / (max - min)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 150, heightDp = 150, showBackground = true)
|
||||
@Composable
|
||||
private fun Chart_Positive_Preview() {
|
||||
TangemTheme(isDark = true) {
|
||||
PriceChangesChart(
|
||||
listOf(1f, 2f, 4f, 1f, 5f),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(widthDp = 150, heightDp = 150, showBackground = true)
|
||||
@Composable
|
||||
private fun Chart_Negative_Preview() {
|
||||
TangemTheme(isDark = true) {
|
||||
PriceChangesChart(
|
||||
listOf(10f, 2f, 4f, 1f, 5f),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue