LiveCharts 已停止维护,新项目应使用 LiveCharts 2;老项目需注意 .NET 6+ 兼容性、WPF 渲染线程限制及迁移要点(如命名空间、数据绑定、坐标轴配置、导出方案等)。

LiveCharts 不再维护,新项目别用;老项目若已接入,需注意 .NET 6+ 兼容性问题和 WPF 渲染线程限制。
LiveCharts 2 是唯一可选的现代替代方案
LiveCharts(v0.x)基于 .NET Framework 4.x,不支持 .NET Core / .NET 5+ 的跨平台 WPF 或 WinUI;它的 Chart 控件直接继承自 UserControl,但内部大量依赖 Dispatcher.BeginInvoke 和 UI 线程绑定,在 .NET 6+ WPF 中易抛出 InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
- 必须用
LiveChartsCore+LiveChartsCore.SkiaSharpView.WPF(即 LiveCharts 2),它基于 SkiaSharp 渲染,完全支持 .NET 6/7/8 - 旧项目迁移时,
SeriesCollection→ISeries[],ChartValues→List或ObservableCollection - WPF XAML 中不再写
,改用(命名空间前缀从lvc变为lcv)
动态生成折线图:绑定数据前先确认坐标轴类型
LiveCharts 2 默认按数值轴(Axis)处理所有数据,但时间序列若传入 DateTime 类型值,不显式配置 X 轴会渲染错乱——它会把 DateTime.Ticks 当成 double 显示,导致横轴显示超长数字而非日期。
- X 轴必须设为
DateTimeUnit类型:new Axis { Labeler = value => new DateTime((long)value).ToString("MM/dd") } - Y 轴建议开启自动范围:
MaxLimit = null,否则动态追加数据时图表可能“卡死”在初始范围 - 动态更新推荐用
ObservableCollection绑定到CartesianChart.Series,而非每次清空重赋值Series = new[] { ... }
// 示例:添加一条随时间增长的折线
var series = new LineSeries<datetimepoint>
{
Values = new ObservableCollection<datetimepoint>(),
Name = "CPU Usage"
};
chart.Series.Add(series);
// 后续任意线程中安全添加点(Skia 渲染层已做同步)
Application.Current.Dispatcher.Invoke(() =>
{
series.Values.Add(new DateTimePoint(DateTime.Now, 72.4));
});
</datetimepoint></datetimepoint>
柱状图分组失败?检查 CategoryAxis 和 Labels 是否匹配
想画“每月销售额对比”这类分组柱状图,却只出来一列或堆叠异常,大概率是没配 CategoryAxis 或 Labels 与数据长度不一致。
ECharts 图表大师。根据用户数据和业务上下文,自动设计并生成专业的 ECharts 可视化图表。使用场景:(1) 用户提供表格/JSON/CSV 数据需要可视化,(2) 用户说"帮我做个图"、"画个图表",(3) 需要将查询结果可视化展示。
-
CartesianChart.AxisX必须设为new CategoryAxis { Labels = new[] { "Jan", "Feb", "Mar" } } - 每条
ColumnSeries的Values长度必须严格等于Labels.Length,多一个少一个都会导致渲染跳行或崩溃 - 分组柱状图不需要手动算间距,LiveCharts 2 自动按
Series.Count均分宽度;但若某系列Values全为 0,该列会塌缩为细线,建议用double.NaN占位
导出 PNG 失败?绕过 WPF 渲染树截图为上策
调用 cartesianChart.SaveImage(...) 在 .NET 6+ WPF 中常返回黑图或空图——因为 Skia 渲染不走 WPF 视觉树,RenderTargetBitmap 截不到内容。
- 正确做法:用
cartesianChart.SkiaSharpCanvas(类型为SKElement)获取底层SKSurface,再调用surface.Snapshot().Encode(SKEncodedImageFormat.Png, 100).ToArray() - 若需带标题/图例导出,得提前用
SKCanvas.DrawText手动绘制,LiveCharts 2 不提供原生导出标注功能 - 导出操作必须在 UI 线程执行,且确保 chart 已完成首次布局(
Loaded事件后才安全)
动态图表的核心不是“怎么画”,而是“怎么让数据流自然驱动视图更新而不卡顿、不跨线程报错、不导出失败”。LiveCharts 2 的设计更贴近现代 .NET,但它的文档示例分散在 GitHub Wiki 和 demo 项目里,官方 NuGet 包里没有 XML 注释,遇到 ISeries 构造参数不明确时,直接查源码里的 LineSeries.cs 比翻文档快得多。










