var rnd = new Random();
var days = new[] { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
var values = new double[days.Length];
const double plotHeight = 220;
const double scaleMax = 100;
const double barWidth = 40;
const double columnSpacing = 12;
void Roll()
{
for (int i = 0; i < values.Length; i++)
values[i] = rnd.Next(15, 100);
}
Roll();
var bars = new List<SkiaShape>();
var valueLabels = new List<SkiaLabel>();
SkiaSvg icon = null;
void Place(int i, double barHeight)
{
bars[i].HeightRequest = barHeight;
valueLabels[i].TranslationY = -(barHeight + 4);
}
void Refresh()
{
Roll();
icon?.AnimateRotation(0, 360, seconds: 0.7, easing: Easing.CubicInOut);
for (int i = 0; i < bars.Count; i++)
{
var index = i;
var from = bars[index].HeightRequest;
var to = plotHeight * (values[index] / scaleMax);
valueLabels[index].Text = $"{values[index]:0}";
bars[index].Animate(0.6, (me, animator, value, dt) =>
{
Place(index, from + (to - from) * value);
}, repeat: 0, easing: Easing.CubicOut, delaySeconds: index * 0.05);
}
}
return new SkiaLayer()
{
BackgroundColor = Color.Parse("#12161F"),
Children = new List<SkiaControl>()
{
new SkiaStack()
{
Spacing = 4,
Children = new List<SkiaControl>()
{
new SkiaLayer()
{
Children = new List<SkiaControl>()
{
new SkiaStack()
{
Spacing = 2,
Children = new List<SkiaControl>()
{
new SkiaLabel("Weekly Active Users")
{
FontSize = 22,
FontAttributes = FontAttributes.Bold,
TextColor = Colors.White,
},
new SkiaLabel("sessions per day, thousands")
{
FontSize = 12,
TextColor = Color.Parse("#78849B"),
},
}
}.StartX().CenterY(),
new SkiaShape()
{
Type = ShapeType.Circle,
WidthRequest = 30,
LockRatio = 1,
BackgroundColor = Color.Parse("#262F42"),
StrokeColor = Color.Parse("#2E7BF6"),
StrokeWidth = 1,
AnimationTapped = SkiaTouchAnimation.Ripple,
TouchEffectColor = Color.Parse("#5EE7C4"),
Children = new List<SkiaControl>()
{
new SkiaSvg()
{
SvgString = "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='white' d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-8 8s3.58 8 8 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/></svg>",
TintColor = Color.Parse("#5EE7C4"),
WidthRequest = 18,
LockRatio = 1,
}.Center().Assign(out icon),
}
}
.EndX()
.CenterY()
.OnTapped(me => Refresh()),
}
}.FillX(),
new SkiaRow()
{
Spacing = columnSpacing,
Margin = new Thickness(0, 16, 0, 0),
Children = days.Select((day, i) => (SkiaControl)new SkiaLayer()
{
WidthRequest = barWidth,
HeightRequest = plotHeight,
Children = new List<SkiaControl>()
{
new SkiaShape()
{
Type = ShapeType.Rectangle,
CornerRadius = 8,
WidthRequest = barWidth,
HeightRequest = plotHeight * (values[i] / scaleMax),
FillGradient = new SkiaGradient()
{
Type = GradientType.Linear,
StartXRatio = 0, StartYRatio = 0,
EndXRatio = 0, EndYRatio = 1,
Colors = new List<Color>()
{
Color.Parse("#5EE7C4"),
Color.Parse("#2E7BF6"),
},
},
}
.EndY()
.Adapt(me => bars.Add(me))
.Animate(0.9, (me, animator, value, dt) =>
{
Place(i, plotHeight * (values[i] / scaleMax) * value);
}, repeat: 0, easing: Easing.CubicOut, delaySeconds: i * 0.07),
new SkiaLabel($"{values[i]:0}")
{
FontSize = 12,
TextColor = Color.Parse("#9FB0C9"),
TranslationY = -(plotHeight * (values[i] / scaleMax) + 4),
}
.CenterX()
.EndY()
.Adapt(me => valueLabels.Add(me)),
}
}).ToList()
}.CenterX(),
new SkiaShape()
{
Type = ShapeType.Rectangle,
HeightRequest = 1,
BackgroundColor = Color.Parse("#2A3346"),
}.FillX(),
new SkiaRow()
{
Spacing = columnSpacing,
Margin = new Thickness(0, 8, 0, 0),
Children = days.Select(day => (SkiaControl)new SkiaLabel(day)
{
FontSize = 12,
WidthRequest = barWidth,
TextColor = Color.Parse("#78849B"),
}.CenterText()).ToList()
}.CenterX(),
}
}
.Center()
.WithPadding(24),
}
}.Fill();