WPF Bar Chart rendering with skia


WPF Chart with SkiaSharp

SkiaShrap graphics library renders gradients very very smooth and I love it on WPF (as opposed to natural way of creating gradients) it also scales nicely when a window resizes without extra code; 



using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using SkiaSharp;
using Topten.RichTextKit;
namespace Xaml.Shop.SkiaWPFSamples
{
SKPaint pinkFillPaint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Pink,
TextSize = 80,
IsAntialias = true
};
SKPaint pinkStrokePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.HotPink.WithAlpha(90),
StrokeWidth = 0.5f,
StrokeCap = SKStrokeCap.Round,
IsAntialias = true
};
private void skiaCanvas2_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
{
SKSurface easel = e.Surface;
SKCanvas canvas = easel.Canvas;
canvas.Clear(SKColor.Parse("#FF27293D"));
var goldenRatio= 1.61803399f;
var width = e.Info.Width;
var height = e.Info.Height;
var minVal = 0;
var maxVal = 130;
var stepHeight = 10;
var stepCount = ((maxVal - minVal) / stepHeight);
var headerH = (height - (height / goldenRatio))/2;
var sideMargin = (width- (width / goldenRatio))/5;
var xStart = 0f;
var xEnd = width - (sideMargin * 2);
var yStart = 0f;
var yEnd = 0f;
canvas.Translate(sideMargin, headerH);
var chartHeight = height - (headerH * 2);
var charWidth = width - (sideMargin * 2);
var adjustedStepHeight = (int)Math.Floor((chartHeight / stepCount));
var adjustedMaxVal = maxVal*((chartHeight) / maxVal);
var count = 0;
//draw chart rectangle
SKRect chartRect = new SKRect(xStart,yStart,charWidth,chartHeight);
canvas.DrawRect(chartRect,pinkStrokePaint);
//draw horizontal lines
for (int i = 0; i < stepCount+1; i++)
{
var y = (i * adjustedStepHeight);
if (i > 0 && i < stepCount)
{
canvas.DrawLine(xStart, y, xEnd, y, pinkStrokePaint);
}
var rs = new RichString().Alignment(Topten.RichTextKit.TextAlignment.Right)
.FontFamily("Segoe UI")
.FontSize(10)
.Add($"{maxVal - count}", textColor: SKColors.WhiteSmoke);
var tw = rs.MeasuredWidth;
rs.MaxWidth =25;
rs.Paint(canvas,new SKPoint(xStart - 30, y), new TextPaintOptions{IsAntialias = true});
count += stepHeight;
canvas.Save();
}
//draw vertical lines
for (int i = 0; i < 10; i++)
{
var w = charWidth / 10;
canvas.DrawLine(i * w, 0, i*w, chartHeight, pinkStrokePaint);
}
canvas.Restore();
var values = new List<int> {50,80,130,70,90,40,110,100,70,42};
var z = 0;
foreach (var val in values)
{
using (SKPaint paint = new SKPaint())
{
var secWidth = (charWidth / 10);
var barW = secWidth / 4 * 3;
var marginLeft = (secWidth - barW) / 2;
var barH = val;
// Create 300-pixel square centered rectangle
float x = marginLeft+secWidth*z;
float y = (chartHeight - (val / 10 * adjustedStepHeight));
SKRect rect = new SKRect(x, y, x + barW, chartHeight);
// Create linear gradient from upper-left to lower-right
paint.Shader = SKShader.CreateLinearGradient(
new SKPoint(rect.Left, rect.Top),
new SKPoint(rect.Right, rect.Bottom),
new SKColor[] { SKColors.DeepPink, SKColor.Parse("#fd5d93") },
new float[] { 0, 1 },
SKShaderTileMode.Mirror);
// Draw the gradient on the rectangle
canvas.DrawRect(rect, paint);
var rs = new RichString().Alignment(Topten.RichTextKit.TextAlignment.Center)
.FontFamily("Segoe UI")
.FontSize(10)
.Add($"{val}", textColor: SKColors.WhiteSmoke);
var tw = rs.MeasuredWidth;
rs.MaxWidth = 25;
rs.Paint(canvas, new SKPoint(x, y), new TextPaintOptions { IsAntialias = true });
z++;
}
}
}
}}
view raw MainWindow.cs hosted with ❤ by GitHub
<Window x:Class="Xaml.Shop.SkiaWPFSamples.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:skia="clr-namespace:SkiaSharp.Views;assembly=SkiaSharp.Views.WPF"
xmlns:local="clr-namespace:SkiaWPFSamples"
xmlns:wpf="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
mc:Ignorable="d"
Title="WPF SKIA 2D Samples" Height="1020" Width="1900">
<Grid>
//set skia canvas
<wpf:SKElement x:Name="skiaCanvas2" PaintSurface="skiaCanvas2_PaintSurface" />
</Grid>
</Window>
view raw MainWindow.xaml hosted with ❤ by GitHub