愿你出走半生,归来仍是少年!
环境:.NET 7、MAUI
数据的统计呈现主要以图表形式为主,而折线图是统计图中最常用的形式之一。
LiveChartsCore.SkiaSharpView是一个简单、灵活、交互式、强大的跨平台图表库,支持Maui、Uno Platform、Blazor-wasm、WPF、WinForms、Xamarin、Avalonia、WinUI、UWP。
在MAUI框架下可安装LiveChartsCore.SkiaSharpView.Maui包进行使用,基于其CartesianChart类进行封装,实现单柱的柱状图展示。
1.BasicSerieDto
看过LiveChartsCore.SkiaSharpView的文档后会了解,它并未直接的给出类似LineChart、PieChart之类的图标,而是有一个很基础的CartesianChart(笛卡尔坐标图表),然后塞入不同的Series实现图表类别的区分以及数据填充。为了更加方便的在业务中使用图表,所以需要进行BasicSerieDto的封装。
1.1.基础属性
一个BasicSerieDto代表一个类别,它包含了类别名称、数据集合、标签集合。通过这些数据可以很方便的转换出对应图表的数据。
public class BasicSerieDto
{
/// <summary>
/// 类别名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 数据
/// </summary>
public List<double> Datas { get; set; }
/// <summary>
/// 文本标签
/// </summary>
public List<string> Labels { get; set; }
public BasicSerieDto(string name, List<double> datas, List<string> labels)
{
Name = name;
if (datas == null || datas.Count==0)
{
throw new ArgumentNullException("BasicSerieDto datas");
}
Datas = datas;
if (labels == null || labels.Count != datas.Count)
{
throw new Exception("BasicSerieDto labels 为空或数量与数据不匹配");
}
Labels = labels;
}
}
1.2.转换出单柱图标的LineSeries
柱状图使用的是LineSeries对象,主要设定了类别名称、数据值、标签、标注等。
其中比较重要的是针对文本的字体需要设定下支持中文的,不然有些品牌的系统会出现乱码情况。
/// <summary>
/// 转换为单折线
/// </summary>
/// <returns></returns>
public LineSeries<double> ToSingleLine()
{
var series = new LineSeries<double>()
{
Name = Name,
Values = Datas,
//填充色
Fill = new SolidColorPaint(SKColors.Blue.WithAlpha(90)),
//点上的文本
DataLabelsFormatter = (point) => { return Labels[point.Index]; },
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.Top,
DataLabelsSize = 12,
DataLabelsPaint = new SolidColorPaint(SKColors.Black)
{
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
},
IsHoverable = false
};
return series;
}
2.图表标题
比较重要的也是汉化问题。
private void InitTitle(string title)
{
Title = new LabelVisual()
{
Text = title,
TextSize = 25,
Padding = new LiveChartsCore.Drawing.Padding(15),
Paint = new SolidColorPaint(SKColors.DarkSlateGray)
{
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
},
};
chart.SetBinding(CartesianChart.TitleProperty, new Binding("Title"));
}
3.横坐标
比较重要的也是汉化问题。
/// <summary>
/// 初始化横坐标
/// </summary>
/// <param name="xLabels"></param>
private void InitX(List<string> xLabels)
{
var xAxis = new Axis()
{
Labels = xLabels,
LabelsAlignment = LiveChartsCore.Drawing.Align.Start,
//LabelsRotation = 90,//横坐标文本旋转角度
LabelsPaint = new SolidColorPaint(SKColors.Black)
{
SKTypeface = SKFontManager.Default.MatchCharacter('汉')
},
};
XAxes = new Axis[] { xAxis };
chart.SetBinding(CartesianChart.XAxesProperty, new Binding("XAxes"));
}
4.数据设置
通过BasicSerieDto的ToSingleLine方法直接获取LineSeries<double>。
private void InitValue(BasicSerieDto dto)
{
Series = new ISeries[]{ dto.ToSingleLine() };
chart.SetBinding(CartesianChart.SeriesProperty, new Binding("Series"));
}
5.使用
public partial class SingleBarChartDemo : ContentPage
{
private class Day
{
public string name { get; set; }
public double Money { get; set; }
}
public SingleBarChartDemo()
{
InitializeComponent();
List<Day> days = new List<Day>();
for (int i = 0; i < 7; i++)
{
days.Add(new Day()
{
name = "周" + i,
Money = (new Random()).NextDouble() * 10000
});
}
chart.BindData("一周营业额", days.Select(p => p.name).ToList(),
new BasicSerieDto("",
days.Select(p => p.Money).ToList(),
days.Select(p => p.name + "\n" + Math.Round(p.Money, 2)).ToList())
);
}
}