XCharts开源库介绍

XCharts开源库介绍

【博物纳新】是UWA旨在为开发者推荐新颖、易用、有趣的开源项目,帮助大家在项目研发之余发现世界上的热门项目、前沿技术或者令人惊叹的视觉效果,并探索将其应用到自己项目的可行性。很多时候,我们并不知道自己想要什么,直到某一天我们遇到了它。

更多精彩内容请关注:lab.uwa4d.com


导读

图表(Chart)是我们最为广泛使用的数据可视化工具。

对于简单的图表,Office系软件就完全可以胜任了。如果需要更加美观和专业,也可以用ECharts、Highcharts、D3、G2之类专门的工具。在各类编程语言中,也有各种图形库用来制作图表。

那么今天,我们来介绍一个可以在Unity的UI中绘制图表的开源库项目——XCharts。它参考了ECharts的风格,通过UGUI绘制,可以静态或使用代码动态地控制内容。

开源库链接:https://lab.uwa4d.com/lab/5bc42d5404617c5805d4d685

特性

1、内置丰富示例,参数可视化配置,效果实时预览,纯源码绘制;
2、支持折线图(LineChart)、柱状图(BarChart)、饼图(PieChart)、雷达图(RadarChart);
3、支持Default、Light、Dark三种默认主题切换,自定义主题;
4、支持多数据密集图表;
5、折线图通过参数可配置出:折线图、曲线图、面积图等;
6、饼图通过参数可配置出:饼图、环形图、南丁格尔玫瑰图等。

目前项目仍在不断更新之中。

使用方法

在开源库下载好XCharts后,我们可以直接作为Unity项目打开,也可以将其导入到现有的项目,然后我们只需要把对应的图表脚本添加到一个Canvas的子对象中。

请输入图片描述

这样基本的配置就完成了。更加详细的控制图表内容以及代码使用的方法,可以在项目自带的演示场景中找到。

那么既然可以在UI里动态绘制图表,我们就来尝试做一些有意义的事情吧。(以下均使用LowPoly Environment PackDemo1场景测试)

1、通过折线图显示帧数走势

帧数计算有多种方法,最简单的是可以取完成最后一帧的时间的倒数:

fps=1/Time.deltaTime;

但这实际上是用一帧的时间来估计一秒经过的帧数,而且全部显示出来会有刷新过快的情况;另一种更常用的方法是统计一下1s左右走过的帧数,如下:

ftime += Time.deltaTime;
frameCount++;
if (ftime >= 1f)
    {
        fps = frameCount / ftime;
        //这里添加图表数据控制代码
        ftime = 0f;
        frameCount = 0f;
    }

需要添加的图表代码:

chart.AddXAxisData(Time.frameCount.ToString()); //添加横轴数据,这里我们使用总帧数
chart.AddData(0, fps);//添加对应数据
chart.RefreshChart();//刷新图表

然后我们在Inspector中把折线图脚本中的Max Cache Data Number设置为我们希望图表能够同时显示的最大数据量,超过这个值图表就会进行推移。这样简单的帧率折线图就完成了。

请输入图片描述

我们可以尝试隐藏除线条以外的元素,这在Inspector中可以很容易的控制,十分简洁的帧率走势就呈现了出来,如下图:

请输入图片描述

2、通过折线图显示Mono内存

Mono内存分为两个部分:已用内存(Used)和堆内存(Heap),因为它们特殊的关系,我们可以将他们显示在同一个折线图中。要得到这两个数据,我们可以用使用下面的两段代码:

Profiler.GetMonoHeapSizeLong()
Profiler.GetMonoUsedSizeLong()

与查看fps相同,我们将其放入Update()里,并隔1s左右刷新:

ftime += Time.deltaTime;
if(ftime>=1f)
    { 
        ftime = 0f;
        chart.AddXAxisData(Time.frameCount.ToString());
        chart.AddData("Heap", Profiler.GetMonoHeapSizeLong()/ 1048576f);//堆内存 MB
        chart.AddData("Used", Profiler.GetMonoUsedSizeLong()/ 1048576f);//占用内存 MB
        chart.RefreshChart();//刷新图表
    }

简单地样式调整之后,得到了下面的效果图,两条折线可以很清晰地反映出Mono内存的变化。

请输入图片描述

3、通过饼图显示材质占比

统计贴图个数占比或者贴图内存占比会更加具有意义,但在非Editor环境下得到所有可见贴图并不方便,为了简单起见,这里选择材质个数进行举例。

以下是部分主要代码,通过渲染器查找到所有可见的材质,使用字典matNames辅助统计:

matNames.Clear();
Renderer[] renderers = (Renderer[])FindObjectsOfType(typeof(Renderer));
foreach (Renderer renderer in renderers) {
    if (renderer.isVisible){
        foreach (Material material in renderer.sharedMaterials){
            if (matNames.ContainsKey(material.name)) {
                int temp = ++matNames[material.name];
                chart.UpdateData(material.name, temp); //图表会自动计算比例,这里只统计个数
                }
            else {
                matNames.Add(material.name, 1);
                chart.AddData(material.name, 1);
}}}}

复杂的遍历工作计算开销比较大,我们这里添加协程来延时3s运行。值得注意的是,对于元素减少,即材质不在视野里的情况,相应的数据列表应该被裁剪,但源码中并没有实现这种功能的方法;我们可以利用该项目纯源码绘制的优点,自己在series.cs里添加新的方法:

public void RemoveSerie() => m_Series = new List<Serie>();

这样每次遍历之前添加chart.series.RemoveSerie()清空数据列表,达到调整列表大小的作用。

以下是运行效果图:

请输入图片描述

简单的主题修改:

请输入图片描述

这样,显示材质占比的饼图也有模有样了。

打包测试

最后,我们尝试打包一下,并测试其运行效果:
平台信息:Android 8.1,meizu 16th
编者这里打包遇到了一些问题,检查发现图表源代码有一部分被限定在了Editor环境之中。

请输入图片描述

不过我们只要见招拆招,删除这段代码及其所有的引用即可,并不影响打包后的正常使用。

下面就是真机的运行效果:

请输入图片描述
折线图(FPS)和 饼图(材质占比)


折线图(FPS)和 折线图(Mono内存)

我们想要的图表这样就基本完成了。

结语

以上就是本次开源库介绍的全部内容了,我们通过3个例子演示了使用XCharts在UI中绘制动态图表的方法;

不管是运行帧率、Mono内存还是材质占比,将数据的动态趋势显示出来都具有非常直观的参考意义。

无论如何,动态图表是数据可视化的有效手段,希望这篇文章能对有需要的读者有所帮助。

快用UWA Lab合辑Mark好项目!

请输入图片描述

今天的推荐就到这儿啦,或者它可直接使用,或者它需要您的润色,或者它启发了您的思路......

请不要吝啬您的点赞和转发,让我们知道我们在做对的事。当然如果您可以留言给出宝贵的意见,我们会越做越好。